Я использую модуль VFW из оболочки JEDI на WinAPI.
Код, который я пишу, предназначен для поиска пользовательских дисков и обнаружения вареза. Мы делаем поиск MP3, WMA и некоторых графических файлов. Теперь мы хотим обнаружить нелегальные фильмы. Я хочу открыть файл AVI, прочитать некоторые детали из него и закрыть его. У меня есть следующий код:
uses WFV; //from JEDI api wrappers
procedure TForm1.Button1Click(Sender: TObject);
var
lInfo : TAVIFILEINFO lFile : IAVIFILE;
lFileType : string;
lLenMinutes : integer;
lFPS : integer;
begin
{init file}
AVIFileInit;
{Open file - note: since we search for warez this is perfely "warezy" file}
AVIFileOpen(lFile, 'e:\Sideways KLAXXON\Sideways KLAXXON.avi', OF_READ, nil);
{Get file info}
AVIFileInfoW(lFile, lInfo, sizeof(lInfo));
lFPS:=Round(lInfo.dwRate /lInfo.dwScale);
lLenMinutes := Round(lInfo.dwLength / lFPS / 60);
lFileType := lInfo.szFileType;
{just for show: prepare some memo to see what we get}
memo1.Lines.Clear;
memo1.Lines.Add('File lenght [min]: ' + IntToStr(lLenMinutes));
memo1.Lines.Add('Width: ' + IntToStr(lInfo.dwWidth));
memo1.Lines.Add('Height: ' + IntToStr(lInfo.dwHeight));
memo1.Lines.Add('File type: ' + lFileType);
{Closing the file}
AVIFileRelease (lFile);
{and here goes the crash}
FreeAndNil(lFile);
end;
Есть две проблемы:
- lLenMinutes — это что-то равное 98, в то время как фильм длится около двух часов. dwRate — 1 миллион, а dwScale — 40 тыс., поэтому FPS идеально равен 25. MSDN говорит: "Единицы определяются dwRate и dwScale".
- Код падает на строке FreeAndNil. Почему? Я предполагаю, что я несу ответственность за освобождение lFile (и, по крайней мере, я чувствую, что должен освободить файл). Без строки с FreeAndNil у меня есть нарушение прав доступа при выходе из процедуры.
Итак, вы знаете, как правильно получить продолжительность фильма из файла AVI? А почему крах?
Изменить
Фильм длится 2 часа одна минута, поэтому результат должен быть действительно близок к 120. Файл lFile объявлен в Jedi как:
IAVIFile = interface(IUnknown)
AVIFileOpen объявляется в JEDI как:
функция AVIFileOpen (var ppfile: IAVIFILE; szFile: LPCWSTR; uMode: UINT; lpHandler: PCLSID): HResult; стандартный вызов; внешнее имя AVIFIDLL 'AVIFileOpenW';
и в MSDN:
STDAPI AVIFileOpen( PAVIFILE *ppfile, LPCTSTR szFile, режим UINT, CLSID pclsidHandler );
MSDN говорит:
«Функция AVIFileOpen открывает файл AVI и возвращает адрес файлового интерфейса, используемого для доступа к нему».
поэтому я предполагаю, что объект создается этой функцией.
Изменить 2
Длина файла avi была перемещена в новый вопрос, так как mghie ответил на этот вопрос.