I'm wondering what the best way to get information from video files is.
More specifically, AVI files, and the type of information you'd get by opening a file in mplayer2.exe (good old media player), going file->properties, details tab. That is, filesize in mb (ok, that's easy to get with normal API calls ;-)), but more importantly, length (hh:mm:ss) and resolution (512x384 or whatever).

I hope there's some API routines to do this, as I have a suspicions these informations can't be extracted generically from AVIs with different codecs? Also, it would be neat if one api exists that works for both avi/mpeg (and all other mplayer-known filetypes).

Even though this isn't a strictly asm question but more of a "which APIs"/"should I dig into the fileformat myself" kind of question, I think it belongs in main and not heap...
Posted on 2003-04-22 16:12:58 by f0dder
I think that there is no way to do this from the API, it would essentially require reading the file header and decoding the tag as with MP3. There is a way to do it with XP and IShellFolders2 or something like that but it involves many inherited interfaces and though I read about it once I can't remember the exact interface to use. A quick glance at an AVI file shows that this is info in the header. There is a synopsis of the header info here , BTW I went through hell decoding the MP3 header, I wish you a better time with AVI.
Posted on 2003-04-22 16:23:39 by donkey
humm, I would have thought there was some generic way to do it, since mplayer has generic-looking stuff for supported filetypes :/ "XP and better" is not an option.

Oh well, I guess I should have a look at it when I'm less beat up.
Posted on 2003-04-22 16:35:13 by f0dder
eMule shows information for AVI and MPEG clips. It is open-source.
Posted on 2003-04-22 16:49:16 by comrade
There is a way to do it with an MCI window, the following example will give you playback time. It will also play some AVIs
f_MCIWndCreate	BYTE "MCIWndCreate",0

Library_Name BYTE "msvfw32.dll",0

MCIInit Proc
invoke LoadLibrary, ADDR Library_Name
mov hMCILib, eax
invoke GetProcAddress, eax, ADDR f_MCIWndCreate
mov p_MCIWndCreate,eax
mov eax,hMCILib
mov eax,-1
mov eax,0
MCIInit endp

MCIWndCreate proc hWnd:DWORD, hInst:DWORD, Style:DWORD, szFile:DWORD
push szFile
push Style
push hInst
push hWnd

call p_MCIWndCreate ; Call the dll routine using a pointer

mov mcihWnd,eax
pop eax
pop eax
pop eax
pop eax

MCIWndCreate endp

OpenMCIFile proc pszFile:DWORD
invoke MCIWndCreate, hDlg, hInstance, WS_CHILD or MCIWNDF_NOOPEN, pszFile
invoke SendMessage, mcihWnd, MCIWNDM_GETEND, 0, 0
mov Mp3End, eax
invoke SendMessage, mcihWnd, WM_CLOSE, 0, 0
OpenMCIFile endp
You need the following libs Lord Rhesus :
Posted on 2003-04-22 17:24:34 by donkey
If creating a MCI window and loading media files there can get me resolution and playback length, that's a quite fine way to do it, as MCI (afaik) ought to be able to play anything there's a codec installed for. Thanks for the ideas, should be enough to get me going tomorrow - and if you have any other ideas, feel free to add them too :)
Posted on 2003-04-22 17:26:55 by f0dder
It's just that I'm not sure how reliable it is, I originally used this method (as many do) to calculate the playtime of an mp3 and it varied widely from the acutal playback length. I eventually scrapped it and wrote my own header decompiler that was extremely accurate (within 1/10 sec of Winamp even on VBR). I don't know much about video codecs so I'm not sure that MCI can play any one of them but it's worth a try (it cannot even play all mp3 files). In checking my old file I found this set of equates I think they were put in because they were missing from the INC file

Posted on 2003-04-22 17:35:02 by donkey
I think if you open the file type(s) with the generic multimedia command MCI_OPEN (a notification message of the winmm mciSendCommand api), (or use the mciSendString 'open' string version), you may have access to other winmm functions from which you can get what you want for different file types.

For avi files at least there are some specific calls you might be able to use, AVIStreamOpenFromFile, AVIFileInfo,... The AVIFILEINFO structure accessed from the AVIFileInfo function obtains information about an open AVI file, for example the width/height in pixels, and the scale, rate and length values which you might be able to get the time scale from, a thought anyway.
Posted on 2003-04-22 18:30:17 by Kayaker

Hei f0dder,
sorry for being the usual "low-level is better" coder, but wouldn't it be easiest (and also give more satisfactions) to just find where the AVI header begins (hint, for well behaved AVI files it must be offset 24), and then ReadFile the DWORD on offset 40 of the header to get the Width, and offset 44 to get the Height?

By having that mentality, I quickly found the following relevant information:

some general info you may want to read before:

I just checked the method I suggested on a real AVI file, and it worked.
However, I suggest you to place additional code to parse any (although non-standard AFAIK) LIST placed before the LIST "hdrl" to get rock solid error checking, you never know. I repeat, though, that that would be a non-standard AVI file (Microsoft says [..] AVI files must keep these three components in the proper sequence [..]).. so you may well not bother at all about others' errors, if you want simplicity.. and in this case go fetch directly the width at offset 64 from the begin of the file, and the height at offset 68.
Posted on 2003-04-23 02:23:18 by Maverick
If that works for all AVIs, all codecs etc, it would be an okay solution - I still need to get time, though. Also, if MCI works for "all" formats for which codecs are installed, and can give width+height+length, that would be preferable. I'll have to look into it...
Posted on 2003-04-23 02:38:45 by f0dder

If that works for all AVIs, all codecs etc, it would be an okay solution - I still need to get time, though.
Yes, it's meant to.
As I understand it, you get the total running time by multiplying a field of the header (which holds the "microseconds".. in reality it's an average per frame), i.e. dwMicroSecPerFrame and the number of frames, i.e. dwTotalFrames. Haven't checked it, but from what I read on those pages that seems the way to do it.
Also, if MCI works for "all" formats for which codecs are installed, and can give width+height+length, that would be preferable. I'll have to look into it...
The choice is yours. Go directly on the source, or pass through millions of useless layers. ;)
Posted on 2003-04-23 02:52:16 by Maverick

The choice is yours. Go directly on the source, or pass through millions of useless layers.

You won't be able to feel the speed difference... and if MCI, or some other API, supports all installed video format codecs... well, it's the difference between supporting one file format or all of them. In a case like this, the "direct approach" doesn't make any sense, unless it's easier to write.

But if the width+height+dwTotalFrames+dwMicroSecPerFrame are present for all AVI files (all codecs), that would probably be easier to code than messing with MCI, and I could live with only supporting AVIs and not MPEGs.
Posted on 2003-04-23 03:42:02 by f0dder
Use DirectShow instead of MCI as its far more powerfull :)
Posted on 2003-04-23 09:33:30 by bazik
Well well, now I have a whole lot of things to look a bit at.
DirectShow might be a possibility, I really loathe MCI... passing strings around, etc. It's a horrible API, and the implementation underneath is horrible too. I had to go to some length to fix midi playback "lockup" in XCOM... all sorts of fun threaded stuff.

DirectShow just smells like "complicated code" :)
Posted on 2003-04-23 09:39:50 by f0dder
Posted on 2003-04-23 09:45:13 by bazik
While looking for some midi stuff I came upon a decent multimedia code site
that happens to mention a method for getting the length of an AVI file.

Visual Basic MCI Command Post (avi midi wav cd)

Determine the STATUS of an AVI file

How long is the AVI file?
You will probably want to use this code to set the maximum value for a
Progress Bar, Meter or a scroll bar. You will need to decide if you want to
display the length of the AVI in Time or Frames. Notice that the STR() is
used. Without it, the mssg variable would be 255 charactrers long.


Dim mssg As String * 255

i = mciSendString("set video1 time format frames", 0&, 0, 0)
i = mciSendString("status video1 length", mssg, 255, 0)
msgbox "There are " & Str(mssg) & " frames"


Dim mssg As String * 255

i = mciSendString("set video1 time format ms", 0&, 0, 0)
i = mciSendString("status video1 length", mssg, 255, 0)
MsgBox "There are " & Str(mssg) & " milliseconds"

Posted on 2003-04-24 10:57:10 by Kayaker
If you right-click on an AVI and select properties. There is a "DETAILS" tab that has this info your looking for, as well if you click on the "PREVIEW" tab it actually give you a play control to watch it.

This tells me there is OLE automation here, based on the file extension. I've done some simple snooping in the registry (nothing to extensive yet). It appears to be referenced to mplayer but im not sure how it automates the control yet, since i still havent been able to manually walk through the required com interface calls to get this info out (Using Japheth's COMView). But im sure its there, just have to find the right interface and the right methods, in the right order...

Posted on 2003-04-26 23:01:59 by NaN

Hi NaN,
if you change the AVI file association to a "poorly-featuring" program, the "Details" and "Preview" tabs will be missing.
Ergo, it must be the application that provides those two context menus.. or at least that's what I reckon.
Posted on 2003-04-27 01:14:30 by Maverick
Or at least the CLSID key to operate the file maybe stored within it. I've seen this from MS Doc and Xls files. There is a section of OLE attached objects. All it does is store the CLSID key and set up info...

Thanks for the tip.. i will look into it..
Posted on 2003-04-27 01:22:08 by NaN
> This might help:


Now I can't open this link...
Posted on 2005-01-11 05:05:50 by Mike