有兩個相關的結構體: TMMIOInfo、TMMCKInfo.
TMMIOInfo 是多媒體文件打開後的狀態信息, mmioOpen 函數的第二個參數就是這個結構的指針;
以後還可以通過 mmioGetInfo、mmiOSetInfo 使用它; 不過暫時還沒有用到它.
現在先用到了 TMMCKInfo, 這是文件內部 "塊" 的信息, 構成如下:
TMMCKInfo = record
ckid: FOURCC; {塊標識}
cksize: DWord; {塊大小}
fccType: FOURCC; {格式類型標識}
dwDataOffset: DWord; {偏移地址}
dwFlags: DWord; {附加信息}
end;
查找 "塊" 需要通過 mmioDescend、mmioAscend 兩個函數.
mmioAscend 是從子塊跳出;
mmioDescend 是進入到子塊; 進入子塊是需要指定子塊的 ckid 和父塊信息;
mmioDescend 也用來查找主塊(RIFF), 此時需要很少的信息就可以找到主塊.
測試代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses MMSystem;
const FilePath = 'C:\WINDOWS\Media\Windows XP 啟動.wav';
//獲取 RIFF 塊的信息
procedure TForm1.Button1Click(Sender: TObject);
var
hFile: HMMIO;
ckiRIFF: TMMCKInfo;
begin
//清空 ckiRIFF 結構體; 有些函數使用前要求必須清空, 即使不要求也還是清空的好.
FillChar(ckiRIFF, SizeOf(TMMCKInfo), 0); {局部變量在清空前有垃圾數據}
//打開文件, 獲取句柄
hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ);
//獲取 RIFF 塊的信息
mmioDescend(hFile, {文件句柄}
@ckiRIFF, {塊信息結構的指針, 用於獲取塊的信息}
nil, {這父塊的結構信息, RIFF 沒有父塊, 無需指定}
MMIO_FINDRIFF {如果是查詢子塊這裡的標志是 MMIO_FINDCHUNK}
); {返回 0 表示查找成功, 這裡忽略了驗證}
//以下是查證獲取到的信息
ShowMessageFmt('%d, %d, %d, %d, %d', [ckiRIFF.ckid, ckiRIFF.cksize, ckiRIFF.fccType,
ckiRIFF.dwDataOffset, ckiRIFF.dwFlags ]); {1179011410, 424636, 1163280727, 8, 0}
if ckiRIFF.ckid = FOURCC_RIFF then ShowMessage('是 RIFF');
if ckiRIFF.fccType = mmiOStringToFOURCC('WAVE',0) then ShowMessage('是 WAVE');
//關閉
mmioClose(hFile, 0);
end;
//獲取子塊的信息
procedure TForm1.Button2Click(Sender: TObject);
var
hFile: HMMIO;
ckiRIFF,ckiSub: TMMCKInfo;
n: Integer;
begin
//清空准備接受信息的結構
FillChar(ckiRIFF, SizeOf(TMMCKInfo), 0);
FillChar(ckiSub, SizeOf(TMMCKInfo), 0);
hFile := mmioOpen(PChar(FilePath), nil, MMIO_READ);
//先獲取主塊(RIFF)信息
mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF);
//獲取 fmt 子塊信息
ckiSub.ckid := mmiOStringToFOURCC('fmt', 0);
if mmioDescend(hFile, @ckiSub, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR then
begin
ShowMessageFmt('%d, %d, %d, %d, %d', [ckiSub.ckid, ckiSub.cksize, ckiSub.fccType,
ckiSub.dwDataOffset, ckiSub.dwFlags]);
end;
//如果繼續查找需要跳出子塊; 下面將從偏移地址 20 跳到 36 處
mmioAscend(hFile, @ckiSub, 0); {其第三個參數一直是 0, 是備用參數}
//獲取 data 子塊信息
ckiSub.ckid := mmiOStringToFOURCC('data', 0);
if mmioDescend(hFile, @ckiSub, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR then
begin
ShowMessageFmt('%d, %d, %d, %d, %d', [ckiSub.ckid, ckiSub.cksize, ckiSub.fccType,
ckiSub.dwDataOffset, ckiSub.dwFlags]);
end;
mmioClose(hFile, 0);
end;
end.