首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

使用 FFmpeg 庫分離多媒體檔案中的音頻碼流

     編輯:關於C語言

前言

在使用 FFmpeg 類庫進行多媒體開發時,開發者常需從容器格式中提取原始音頻碼流。本文詳細記錄了針對不同容器格式(MP3、AAC、TS、FLV、MP4)分離音頻碼流的實踐經驗與關鍵技術點,特別針對 AAC 在 FLV/MP4 容器中需補充 ADTS 頭部的問題進行了深入分析。

核心流程:調用 av_read_frame() 獲取 AVPacket

分離音頻碼流的基本邏輯是:在解複用循環中,每次調用 av_read_frame() 後,檢查返回的 AVPacket 是否屬於音頻流,若是則直接將其 data 與 size 寫入本地文件。這一方法對於某些容器格式效果良好,但對其他格式則存在缺陷。

不同容器格式的分離表現差異

1. MP3 碼流:直接存儲即可播放

經測試,若源文件為 MP3 格式,直接將 AVPacket 寫入文件,生成的文件可正常播放。這是因為 MP3 幀本身包含同步頭等信息,屬於自同步的碼流格式。

2. AAC 碼流:容器格式決定成敗

  • TS (MPEG2-TS) 容器:直接存儲 AVPacket 可播放。TS 封裝時通常已包含 ADTS 頭或 PES 頭,碼流具備幀同步能力。
  • FLV、MP4 等「特殊容器」:直接存儲 AVPacket 生成的文件無法播放。

深度解析:為何 FLV/MP4 中的 AAC 需手動添加 ADTS 頭?

通過對比發現,從 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 結構及生成代碼實現。

總結與建議

  • 分離音頻碼流時,必須識別容器格式,採取差異化處理策略。
  • 對於 AAC,若容器為 FLV/MP4/MKV 等,務必補全 ADTS 頭,否則輸出文件不可用。
  • 建議封裝通用的「碼流分離工具類」,內部根據 AVFormatContext->iformat->name 自動判斷並處理。

本文轉載自 “leixiaohua1020視音頻技術” 博客,原文地址:https://leixiaohua1020.blog.51cto.com/3974648/1303851

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved