FFmpeg名稱中的mpeg來自視頻編碼標準MPEG,而前綴FF是Fast Forward的首字母縮寫。
目錄
默認的編譯會生成 4 個可執行文件和 8 個靜態庫。可執行文件包括用於 轉碼 、 推流 、Dump媒體文件的 ffmpeg 、用於播放媒體文件的 ffplay 、 用於獲取媒體文件信息的 ffprobe ,以及作為簡單流媒體服務器的 ffserver 。
8個靜態庫其實就是FFmpeg的8個模塊,具體包括如下內容。
比如AAC編碼,常見的有兩種封裝格式
AAC 的 bit stream filter 常常應用在 編碼 的過程中。
與音頻的AAC編碼格式相對應的是視頻中的 H264編碼 ,它也有兩種封裝格式
FFmpeg中也提供了對應的 bit stream filter ,稱 H264_mp4toannexb ,可以將MP4封裝格式的H264數據包轉換為annexb封裝格式的H264數據 (其實就是裸的H264的數據)包。
H264 的 bit stream filter 常常應用於視頻解碼過程中。
ffmpeg 是進行媒體文件轉碼的命令行工具
ffprobe 是用於查看媒體 文件頭信息的工具
ffplay 則是用於播放媒體文件的工具
1.首先用ffprobe查看壹個音頻的文件
2.輸出格式信息format_name、時間長度duration、文件 大小size、比特率bit_rate、流的數目nb_streams等。
3.以JSON格式的形式輸出具體每壹個流 最詳細 的信息
4.顯示幀信息的命令如下:
5.查看包信息的命令如下:
ffplay是以FFmpeg框架為基礎,外加渲染音視頻 的庫libSDL來構建的媒體文件播放器。
業界內開源的 ijkPlayer 其實就是基於 ffplay 進行改造的播放器,當然其做了硬件解碼以及很多兼容性的工作。
在 ffplay中音畫同步的實現方式其實有三種。分別是
並且在 ffplay 中默認的對齊方式也是以 音頻 為基準進行對齊的。
首先要聲明的是,播放器接收到的視頻幀或者音頻幀,內部都會有 時間戳(PTS時鐘) 來標識它實際應該在什麽時刻進行展示。
實際的對齊策略如下:比較視頻當前的播放時間和音頻當前的播放時間
關鍵就在於音視頻時間的比較以及延遲的計算,當然在比較的過程中會設 置壹個 閾值(Threshold) ,若超過預設的閾值就應該做調整(丟幀渲染 或者重復渲染),這就是整個對齊策略。
ffmpeg 就是強大的媒體文件轉換工具。它可以轉換任何格式的媒體文件,並且還可以用自己的 AudioFilter 以及 VideoFilter 進行處理和編輯。
接下來介紹壹個解碼的實例,該實例實現的功能非常單壹,就是把壹個視頻文件解碼成單獨的音頻PCM文件和視頻YUV文件。
AVFormatContext是API層直接接觸到的結構體,它會進行格式的封 裝與解封裝。
該結構體包含的就是與實際的 編解碼 有關的部分。
3.3.1 av_register_all
所以該函數的內部實現會先調用 avcodec_register_all 來註冊所有config.h裏面開放的編解碼器,然後會註冊所有的 Muxer 和 Demuxer (也就是封裝格式),最後註冊所有的 Protocol (即協議層的東西)。
3.3.2 av_find_codec
這裏面其實包含了兩部分的內容:壹部分是尋找 解碼器 ,壹部分是尋找 編碼器 。
3.3.3 avcodec_open2
該函數是打開編解碼器(Codec)的函數,無論是編碼過程還是解碼過程,都會用到該函數。
avformat_open_input
根據所提供的文件路徑判斷文件的格 式,其實就是通過這壹步來決定使用的到底是哪壹個 Demuxer 。
avformat_find_stream_info
該方法的作用就是把所有 Stream 的 MetaData 信息填充好。
av_read_frame
使用該方法讀取出來的數據是 AVPacket 。
對於 音頻流 ,壹個 AVPacket 可能包含 多 個 AVFrame ,但是對於 視頻流 ,壹個 AVPacket 只包含 壹 個 AVFrame ,該函數最終只會返回壹個 AVPacket 結構體。
avcodec_decode
該方法包含了兩部分內容:壹部分是 解碼視頻 ,壹部分是 解碼音頻 , 解碼 是會委托給對應的解碼器來實施的。
avformat_close_input
該函數負責釋放對應的資源。
avformat_alloc_output_context2
該函數內部需要調用方法avformat_alloc_context來分配壹個 AVFormatContext 結構體。
avio_open2
編碼的階段了,開發者需要將手動封裝好的 AVFrame 結構體,作為 avcodec_encode_video 方法的輸入,將其編碼成為 AVPacket ,然後調用 av_write_frame 方法輸出到媒體文件中。
本文參考 音視頻開發進階指南
項目源碼地址 - FFmpegDecoder