也就是說,重取樣函式swr_convert一次只會輸出指定長度的音訊資料,超出這個長度的資料被留在重取樣的快取當中。那麼在對一個音訊檔案轉換格式之時,有可能所有音訊幀都遍歷完了,重取樣快取裡面還儲存著剩餘未取走的音訊資料。此時要像對待影片編碼快取那樣,想辦法把剩下的音訊資料衝出來。
具體到程式碼實現上,在呼叫swr_convert函式之時,倒數第二個引數填NULL,表示輸入的資料內容為空;倒數第一個引數填0,表示輸入的資料大小為0。這便告訴取樣器,已經沒有要轉換的音訊了,請把快取中剩餘的資料衝出來吧。那麼swr_convert函式的返回值就是本次沖走的輸出資料大小,當返回值為0時,表示重取樣快取已經衝光了,再也沒有剩餘的資料了,此時才能結束音訊的格式轉換操作。
當然,對於常見的mp3和aac格式,它們每幀的長度是固定的,正常情況呼叫一次swr_convert函式即可輸出完整的音訊資料,無需另外處理重取樣快取。只有ogg、amr、wma等格式的每幀音訊長度不固定,才需要額外處理音訊的重取樣快取,於是對《FFmpeg開發實戰:從零基礎到短影片上線》一書第五章的重取樣程式碼改動如下。
開啟chapter05/swrmp3.c,把下面這行
改為下面幾行(因為ogg、amr和wma的frame_size為0,所以需要另外賦值):
另外在輪詢資料包的迴圈結束之後,補充下面的重取樣快取沖刷程式碼,這樣新生成的音訊檔案才是完整的:
接著執行下面的編譯命令。
編譯完成後執行以下命令啟動測試程式,期望把ring.ogg重取樣後儲存為MP3檔案。
程式執行完畢,發現控制檯輸出以下的日誌資訊,說明完成了對ogg檔案重取樣mp3音訊的操作。
然後開啟影音播放器可以正常播放output_swrmp3.mp3,表示上述程式碼正確實現了將ogg音訊資料重取樣再轉存MP3檔案的功能。