Author: Tomas Rutkauskas
Does anybody know how to read properties of movie files (avi, mpeg, asf, ..). I
would like to get as much information about files as possible: length, resolution,
audio and video codecs, copyright and so on. In other words: Information that is
displayed after right-clicking file and selecting "properties".
Answer:
Below is some code to get some of the data. To use the DirectDraw/ DirectShow calls
you need either the older DSHOW.PAS (DX6) or more current DirectShow.pas header
conversion from the Project JEDI web site:
1 type
2 TDSMediaInfo = record
3 SurfaceDesc: TDDSurfaceDesc;
4 Pitch: integer;
5 PixelFormat: TPixelFormat;
6 MediaLength: Int64;
7 AvgTimePerFrame: Int64;
8 FrameCount: integer;
9 Width: integer;
10 Height: integer;
11 FileSize: Int64;
12 end;
13
14 function GetHugeFileSize(const FileName: string): int64;
15 var
16 FileHandle: hFile;
17 begin
18 FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyNone);
19 try
20 LARGE_INTEGER(Result).LowPart := GetFileSize(FileHandle,
21 @LARGE_INTEGER(Result).HighPart);
22 if LARGE_INTEGER(Result).LowPart = $FFFFFFFF then
23 Win32Check(GetLastError = NO_ERROR);
24 finally
25 FileClose(FileHandle);
26 end;
27 end;
28
29 function GetMediaInfo(FileName: WideString): TDSMediaInfo;
30 var
31 DirectDraw: IDirectDraw;
32 AMStream: IAMMultiMediaStream;
33 MMStream: IMultiMediaStream;
34 PrimaryVidStream: IMediaStream;
35 DDStream: IDirectDrawMediaStream;
36 GraphBuilder: IGraphBuilder;
37 MediaSeeking: IMediaSeeking;
38 TimeStart, TimeStop: Int64;
39 DesiredSurface: TDDSurfaceDesc;
40 DDSurface: IDirectDrawSurface;
41 begin
42 if FileName = '' then
43 raise Exception.Create('No File Name Specified');
44 OleCheck(DirectDrawCreate(nil, DirectDraw, nil));
45 DirectDraw.SetCooperativeLevel(GetDesktopWindow(), DDSCL_NORMAL);
46 Result.FileSize := GetHugeFileSize(FileName);
47 AMStream := IAMMultiMediaStream(CreateComObject(CLSID_AMMultiMediaStream));
48 OleCheck(AMStream.Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, nil));
49 OleCheck(AMStream.AddMediaStream(DirectDraw, MSPID_PrimaryVideo, 0,
50 IMediaStream(nil^)));
51 OleCheck(AMStream.OpenFile(PWideChar(FileName), AMMSF_NOCLOCK));
52 AMStream.GetFilterGraph(GraphBuilder);
53 MediaSeeking := GraphBuilder as IMediaSeeking;
54 MediaSeeking.GetDuration(Result.MediaLength);
55 MMStream := AMStream as IMultiMediaStream;
56 OleCheck(MMStream.GetMediaStream(MSPID_PrimaryVideo, PrimaryVidStream));
57 DDStream := PrimaryVidStream as IDirectDrawMediaStream;
58 DDStream.GetTimePerFrame(Result.AvgTimePerFrame);
59 {Result.FrameCount := Result.MediaLength div Result.AvgTimePerFrame;}
60 { TODO : Test for better accuracy }
61 Result.FrameCount := Round(Result.MediaLength / Result.AvgTimePerFrame);
62 Result.MediaLength := Result.FrameCount * Result.AvgTimePerFrame;
63 ZeroMemory(@DesiredSurface, SizeOf(DesiredSurface));
64 DesiredSurface.dwSize := Sizeof(DesiredSurface);
65 OleCheck(DDStream.GetFormat(TDDSurfaceDesc(nil^), IDirectDrawPalette(nil^),
66 DesiredSurface, DWord(nil^)));
67 Result.SurfaceDesc := DesiredSurface;
68 DesiredSurface.ddsCaps.dwCaps := DesiredSurface.ddsCaps.dwCaps or
69 DDSCAPS_OFFSCREENPLAIN or DDSCAPS_SYSTEMMEMORY;
70 DesiredSurface.dwFlags := DesiredSurface.dwFlags or DDSD_CAPS or DDSD_PIXELFORMAT;
71 {Create a surface here to get vital statistics}
72 OleCheck(DirectDraw.CreateSurface(DesiredSurface, DDSurface, nil));
73 OleCheck(DDSurface.GetSurfaceDesc(DesiredSurface));
74 Result.Pitch := DesiredSurface.lPitch;
75 if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 24 then
76 Result.PixelFormat := pf24bit
77 else if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 32 then
78 Result.PixelFormat := pf32bit;
79 Result.Width := DesiredSurface.dwWidth;
80 Result.Height := DesiredSurface.dwHeight;
81 end;
|