2007. február 13., kedd
How to read the properties of movie files
Problem/Question/Abstract:
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:
type
TDSMediaInfo = record
SurfaceDesc: TDDSurfaceDesc;
Pitch: integer;
PixelFormat: TPixelFormat;
MediaLength: Int64;
AvgTimePerFrame: Int64;
FrameCount: integer;
Width: integer;
Height: integer;
FileSize: Int64;
end;
function GetHugeFileSize(const FileName: string): int64;
var
FileHandle: hFile;
begin
FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyNone);
try
LARGE_INTEGER(Result).LowPart := GetFileSize(FileHandle, @LARGE_INTEGER(Result).HighPart);
if LARGE_INTEGER(Result).LowPart = $FFFFFFFF then
Win32Check(GetLastError = NO_ERROR);
finally
FileClose(FileHandle);
end;
end;
function GetMediaInfo(FileName: WideString): TDSMediaInfo;
var
DirectDraw: IDirectDraw;
AMStream: IAMMultiMediaStream;
MMStream: IMultiMediaStream;
PrimaryVidStream: IMediaStream;
DDStream: IDirectDrawMediaStream;
GraphBuilder: IGraphBuilder;
MediaSeeking: IMediaSeeking;
TimeStart, TimeStop: Int64;
DesiredSurface: TDDSurfaceDesc;
DDSurface: IDirectDrawSurface;
begin
if FileName = '' then
raise Exception.Create('No File Name Specified');
OleCheck(DirectDrawCreate(nil, DirectDraw, nil));
DirectDraw.SetCooperativeLevel(GetDesktopWindow(), DDSCL_NORMAL);
Result.FileSize := GetHugeFileSize(FileName);
AMStream := IAMMultiMediaStream(CreateComObject(CLSID_AMMultiMediaStream));
OleCheck(AMStream.Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, nil));
OleCheck(AMStream.AddMediaStream(DirectDraw, MSPID_PrimaryVideo, 0, IMediaStream(nil^)));
OleCheck(AMStream.OpenFile(PWideChar(FileName), AMMSF_NOCLOCK));
AMStream.GetFilterGraph(GraphBuilder);
MediaSeeking := GraphBuilder as IMediaSeeking;
MediaSeeking.GetDuration(Result.MediaLength);
MMStream := AMStream as IMultiMediaStream;
OleCheck(MMStream.GetMediaStream(MSPID_PrimaryVideo, PrimaryVidStream));
DDStream := PrimaryVidStream as IDirectDrawMediaStream;
DDStream.GetTimePerFrame(Result.AvgTimePerFrame);
{Result.FrameCount := Result.MediaLength div Result.AvgTimePerFrame;}
{ TODO : Test for better accuracy }
Result.FrameCount := Round(Result.MediaLength / Result.AvgTimePerFrame);
Result.MediaLength := Result.FrameCount * Result.AvgTimePerFrame;
ZeroMemory(@DesiredSurface, SizeOf(DesiredSurface));
DesiredSurface.dwSize := Sizeof(DesiredSurface);
OleCheck(DDStream.GetFormat(TDDSurfaceDesc(nil^), IDirectDrawPalette(nil^),
DesiredSurface, DWord(nil^)));
Result.SurfaceDesc := DesiredSurface;
DesiredSurface.ddsCaps.dwCaps := DesiredSurface.ddsCaps.dwCaps or
DDSCAPS_OFFSCREENPLAIN or DDSCAPS_SYSTEMMEMORY;
DesiredSurface.dwFlags := DesiredSurface.dwFlags or DDSD_CAPS or DDSD_PIXELFORMAT;
{Create a surface here to get vital statistics}
OleCheck(DirectDraw.CreateSurface(DesiredSurface, DDSurface, nil));
OleCheck(DDSurface.GetSurfaceDesc(DesiredSurface));
Result.Pitch := DesiredSurface.lPitch;
if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 24 then
Result.PixelFormat := pf24bit
else if DesiredSurface.ddpfPixelFormat.dwRGBBitCount = 32 then
Result.PixelFormat := pf32bit;
Result.Width := DesiredSurface.dwWidth;
Result.Height := DesiredSurface.dwHeight;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése