我正在嘗試編寫一個Delphi 6應用程序,該應用程序需要使用VFW服務將視頻和音頻寫入AVI。我設法讓視頻流正常工作。它在VLC或Windows Media Player中運行良好。但是當我添加一個音頻流並嘗試播放輸出AVI時,VLC播放器抱怨AVI文件被破壞。它會播放文件和視頻看起來不錯,但沒有音頻。我試圖在寫入視頻流之前添加音頻流,然後再添加音頻流。都沒有工作。在Delphi 6應用程序中無法使用視頻和音頻(VFW)創建AVI文件
此外,如果我不添加音頻流,我可以在Windows資源管理器中右鍵單擊輸出AVI文件,並在摘要選項卡中查看流中視頻數據的正確信息。添加流右鍵單擊後,顯示狀態消息說AVI屬性無法讀取。
UPDATE:我正在做一些真正基本錯誤的事情。事實證明,我正在做的是吹的文件的頂級標題。如果我沒有創建音頻流,那麼文件就沒有問題,我會在文件的開頭看到通常的標題信息。 我打電話創建音頻流,即創建的第二個流,輸出AVI文件開頭的標題完全是空白(零)。即使我沒有調用AVIStreamSetFormat()或寫入任何數據(即使我這樣做),只要在用十六進制編輯器檢查文件時,使第二個AVICreateStream()調用擦除文件的一開始。如果對輸出文件造成「損害」,我會怎麼做呢?
我的問題是:
1)我在做什麼錯了? 2)你知道一個很好的例子,它展示瞭如何創建一個音頻和視頻交錯的AVI,尤其是一個顯示如何編寫壓縮音頻流的AVI?
下面是我用來寫入音頻流的代碼,在我完全寫出視頻流之後。單位級變量FAvi已經填充了TWaveFormatEx字段(wfx)。我檢查了內容,並將這些字段全部設置爲8000 Khz採樣率,1通道,每通道16位和格式標記1(WAVE_FORMAT_PCM)的有效值。塊對齊,數據速率等都是正確填寫太:
function TAviWriterWithCompression.addAudioFrame(dat: Pointer; numbytes: Cardinal): HRESULT;
var
bRetErr: boolean;
numsamps: LongInt;
ahdr: TAVISTREAMINFO;
hr: HRESULT;
lSampWritten, lBytesWritten: LONG;
begin
Result := S_OK;
bRetErr := true;
if Assigned(FAvi_) then
begin
if Assigned(dat) and (numbytes <> 0) then
begin
if not FAvi_.iserr then
begin
if FAvi_.wfx.nChannels <> 0 then
bRetErr := false
else
Result := LongInt(AVIERR_BADFORMAT);
end
else
Result := LongInt(AVIERR_ERROR);
end
else
Result := LongInt(AVIERR_BADPARAM);
end
else
Result := LongInt(AVIERR_BADHANDLE);
if bRetErr then
// =========================== EXIT POINT ==============
exit;
if FAvi_.wfx.wBitsPerSample <= 0 then
begin
Result := LongInt(AVIERR_BADFORMAT);
// =========================== EXIT POINT ==============
exit;
end; // if FAvi_.wfx.wBitsPerSample <= 0 then
numsamps := Trunc((numbytes * 8)/FAvi_.wfx.wBitsPerSample);
if ((numsamps * FAvi_.wfx.wBitsPerSample/8) <> numbytes) then
begin
Result := LongInt(AVIERR_BADPARAM);
// =========================== EXIT POINT ==============
exit;
end; // if ((numsamps * FAvi_.wfx.wBitsPerSample/8) <> numbytes) then
if not Assigned(FAvi_.theAs) then
begin
ZeroMemory(@ahdr, sizeof(ahdr));
ahdr.fccType := streamtypeAUDIO;
ahdr.dwScale := FAvi_.wfx.nBlockAlign;
ahdr.dwRate := FAvi_.wfx.nSamplesPerSec*FAvi_.wfx.nBlockAlign;
ahdr.dwSampleSize := FAvi_.wfx.nBlockAlign;
ahdr.dwQuality := DWORD(-1);
hr := AVIFileCreateStream(FAvi_.pfile, FAvi_.theAs, ahdr);
if hr <> AVIERR_OK then
begin
Result := hr;
// Set the error flag.
FAvi_.iserr := true;
// =========================== EXIT POINT ==============
exit;
end; // if hr <> AVIERR_OK then
hr := AVIStreamSetFormat(FAvi_.theAs, 0, @FAvi_.wfx, sizeof(FAvi_.wfx));
if hr <> AVIERR_OK then
begin
Result := hr;
// Set the error flag.
FAvi_.iserr := true;
// =========================== EXIT POINT ==============
exit;
end; // if hr <> AVIERR_OK then
end; // if not Assigned(FAvi_.theAs) then
// now we can write the data
hr := AVIStreamWrite(FAvi_.theAs, FAvi_.nsamp, numsamps, dat, numbytes, AVIIF_KEYFRAME, @lSampWritten, @lBytesWritten);
if hr <> AVIERR_OK then
begin
Result := hr;
// Set the error flag in our utility object.
FAvi_.iserr := true;
// =========================== EXIT POINT ==============
exit;
end; // if hr <> AVIERR_OK then
Inc(FAvi_.nsamp, numsamps);
// Set the flag that tells it is no longer a virgin file and that
// attempting to set the compression is not allowed.
FIsVirginFile := false;
end;
這裏是完成了當清理音頻和視頻流兩者的代碼:
destructor TAviWriterWithCompression.Destroy;
begin
// Code goes here.
if Assigned(FAvi_) then
begin
// Release the streams.
if Assigned(FAvi_.theAs) then
begin
AVIStreamRelease(FAvi_.theAs);
FAvi_.theAs := nil;
end;
if Assigned(FAvi_.thePsCompressed) then
begin
AVIStreamRelease(FAvi_.thePsCompressed);
// FAvi_.thePsCompressed := nil;
end;
if Assigned(FAvi_.thePs) then
begin
AVIStreamRelease(FAvi_.thePs);
// FAvi_.thePs := nil;
end;
if Assigned(FAvi_.pfile) then
begin
AVIFileRelease(FAvi_.pfile);
// FAvi_.pfile := nil;
end;
AVIFileExit();
// FreeAndNil(FAvi_);
end; // if Assigned(FAvi_) then
inherited Destroy;
end;
通知: @RemyLebau
你在問一個例子;那麼['VirtualDub'](http://sourceforge.net/projects/virtualdub/files/)應該能夠向您展示如何處理音頻流並正確設置所有結構(請參閱* AudioSource .cpp *,* InputFileMP3.cpp *和* InputFileWAV.cpp *)。幾年前,當我使用它時,我感到很滿意。 – TLama
是的,我一直在使用它。這就是我發現創建音頻流的方法是用Hex File Editor和Riff Chunk協助來改變AVI文件頭。 –