在使用 FFmpeg 類庫進行多媒體開發時,開發者常需從容器格式中提取原始音頻碼流。本文詳細記錄了針對不同容器格式(MP3、AAC、TS、FLV、MP4)分離音頻碼流的實踐經驗與關鍵技術點,特別針對 AAC 在 FLV/MP4 容器中需補充 ADTS 頭部的問題進行了深入分析。
av_read_frame() 獲取 AVPacket分離音頻碼流的基本邏輯是:在解複用循環中,每次調用 av_read_frame() 後,檢查返回的 AVPacket 是否屬於音頻流,若是則直接將其 data 與 size 寫入本地文件。這一方法對於某些容器格式效果良好,但對其他格式則存在缺陷。
經測試,若源文件為 MP3 格式,直接將 AVPacket 寫入文件,生成的文件可正常播放。這是因為 MP3 幀本身包含同步頭等信息,屬於自同步的碼流格式。
AVPacket 可播放。TS 封裝時通常已包含 ADTS 頭或 PES 頭,碼流具備幀同步能力。AVPacket 生成的文件無法播放。通過對比發現,從 FLV 或 MP4 容器中通過 av_read_frame() 取出的 AVPacket 數據,實際上是不帶 ADTS 文件頭的純 AAC 原始幀數據(即 Raw AAC / AAC Elementary Stream)。這類數據缺幀同步信息、採樣率、聲道數等關鍵參數,播放器無法解析。
解決方案:在寫入每個 AVPacket 前,手動構造並寫入 7 字節的 ADTS 文件頭。ADTS 頭包含同步字、層級、配置文件、採樣率索引、聲道配置、幀長度等字段,需根據 AVCodecContext 中的 extradata(解碼器特定配置)動態計算填充。
提示:ADTS 頭構造涉及位運算,需嚴格遵循 MPEG-2 Part 7 標準。後續將專文詳解 ADTS 結構及生成代碼實現。
AVFormatContext->iformat->name 自動判斷並處理。本文轉載自 “leixiaohua1020視音頻技術” 博客,原文地址:https://leixiaohua1020.blog.51cto.com/3974648/1303851