WinAPI で JEDI ラッパーの VFW ユニットを使用しています。
私が書いているコードは、ユーザーのドライブを検索してウェアーズを検出するためのものです。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;
2 つの問題があります。
- lLenMinutes は 98 に相当し、映画は約 2 時間です。dwRate は 100 万で、dwScale は 40k であるため、FPS は完全に 25 です。MSDN は次のように述べています。
- FreeAndNil 行でコードがクラッシュします。なんで?lFile を解放する責任があると思います (少なくとも、ファイルを解放する必要があると感じています)。FreeAndNil との関係がなければ、プロシージャの終了時に Access Violation が発生します。
では、AVI ファイルから映画の長さを正しく取得する方法を知っていますか? そして、なぜクラッシュしたのですか?
編集
この映画は 2 時間 1 分なので、結果は実際には 120 に近いはずです。lFile は Jedi で次のように宣言されています。
IAVIFile = interface(IUnknown)
AVIFileOpen は JEDI で次のように宣言されています。
function AVIFileOpen(var ppfile: IAVIFILE; szFile: LPCWSTR; uMode: UINT; lpHandler: PCLSID): HResult; stdcall; 外部 AVIFILDLL 名 'AVIFileOpenW';
およびMSDNで:
STDAPI AVIFileOpen( PAVIFILE *ppfile, LPCTSTR szFile, UINT モード, CLSID pclsidHandler );
MSDN は次のように述べています。
「AVIFileOpen 関数は AVI ファイルを開き、アクセスに使用されるファイル インターフェイスのアドレスを返します。」
したがって、オブジェクトはこの関数によって作成されると想定しています。
編集 2
mghie がこの質問に回答したため、avi ファイルの長さは新しい質問に移動されました。