ffmpeg入門(mén)到實(shí)戰(zhàn)-ffmpeg是怎么轉(zhuǎn)碼的?

轉(zhuǎn)發(fā)自白狼棧:查看原文

閱讀目錄

視頻是怎么被播放的?

我們知道,當(dāng)下大多數(shù)播放器都是基于ffmpeg二次開(kāi)發(fā)的。你有沒(méi)有想過(guò),你用播放器打開(kāi)一個(gè)視頻的時(shí)候,是怎么看到的畫(huà)面,怎么聽(tīng)到的聲音?

我們用這張圖簡(jiǎn)單描繪出視頻被播放的流程。

image

下面稍微解釋下圖中的含義。

  1. 解封裝:播放器將輸入的封裝格式(mp4、mkv)的數(shù)據(jù)分離,產(chǎn)生音頻流和視頻流兩部分,注意此時(shí)這兩部分?jǐn)?shù)據(jù)還只是壓縮的數(shù)據(jù),類似分流,后面我們也會(huì)介紹如何從視頻文件中抽離出音頻和視頻。
  2. 下一步就是解碼操作了,我們說(shuō)解碼就是將視頻、音頻壓縮的編碼數(shù)據(jù),解碼成為非壓縮的視頻、音頻原始數(shù)據(jù)。這里將音頻解碼為pcm格式的數(shù)據(jù),將視頻解碼為yuv格式的數(shù)據(jù)。
  3. 音視頻同步播放:把解封裝和解碼分別拿到的視頻信息和音視頻數(shù)據(jù),發(fā)送給顯卡和聲卡即可播放。

ffmpeg命令的格式

我們?cè)?a target="_blank">音視頻基礎(chǔ)概念一文中介紹轉(zhuǎn)碼的時(shí)候,拋出過(guò)一條轉(zhuǎn)碼的命令,如下

ffmpeg -i input.flv output.mp4

對(duì)于ffmpeg命令的基本格式,參考ffmpeg官網(wǎng)

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

翻譯過(guò)來(lái)就是

ffmpeg [全局選項(xiàng)] {[輸入文件選項(xiàng)] -i 輸入文件} ... {[輸出文件選項(xiàng)] 輸出文件} ...

... 表示一條命令可能會(huì)有多個(gè)輸入和多個(gè)輸出。

比如我們可以通過(guò)輸入多個(gè)文件轉(zhuǎn)碼后輸出多個(gè)文件

ffmpeg -i input1 -i input2 \
    -acodec … -vcodec … output1 \
    -acodec … -vcodec … output2 \
    -acodec … -vcodec … output3

據(jù)不完全統(tǒng)計(jì),ffmpeg命令的選項(xiàng)數(shù)量就有小幾萬(wàn),所以不僅要多掌握學(xué)習(xí)技巧,更多的是多積累經(jīng)驗(yàn),靠死記硬背是完全行不通的。

那么多的選項(xiàng),體現(xiàn)在一條命令上,一個(gè)基本的通用規(guī)則就是:

輸入文件選項(xiàng)只作用于它后面的第一個(gè)輸入文件,自然,輸出文件選項(xiàng)也只作用于它后面的第一個(gè)輸出文件。所以是有順序要求的。

全局選項(xiàng)倒是可以隨便寫(xiě),比如有個(gè)全局選項(xiàng) -y,詢問(wèn)我們是否要覆蓋輸出,下面兩種寫(xiě)法都可以

ffmpeg -y -i input.flv output.mp4
ffmpeg -i input.flv -y output.mp4

但是,如果命令很長(zhǎng)很長(zhǎng)(比如我們前面給的音視頻案例,一條命令甚至都有幾百個(gè)字符),類似這種全局選項(xiàng),最好寫(xiě)在輸入文件前面或者輸出文件前面。

另外,千萬(wàn)不要先寫(xiě)輸出文件,再寫(xiě)輸入文件,至少應(yīng)該寫(xiě)完輸入文件,再寫(xiě)輸出文件,比如下面這樣就是不好的寫(xiě)法

ffmpeg output.mp4 -i input.flv

良好的習(xí)慣才是好的開(kāi)始。

ffmpeg轉(zhuǎn)碼輸出的過(guò)程

ffmpeg -i input.flv output.mp4

還是上面這條簡(jiǎn)單的轉(zhuǎn)碼命令,對(duì)于類似這樣的一條命令,對(duì)于ffmpeg,又是怎么處理的呢?

我們用下面這個(gè)圖來(lái)表示轉(zhuǎn)碼輸出的過(guò)程。

image

具體描述如下

  1. ffmpeg 調(diào)用一個(gè)包含解復(fù)用器demuxer的libavformat庫(kù),從輸入文件中讀取包含編碼的數(shù)據(jù)包
  2. 然后將編碼的數(shù)據(jù)包傳遞給解碼器(decoder)(流復(fù)制操作忽略該步驟)
  3. 解碼器(decoder)產(chǎn)生未壓縮的幀(即原始幀)可以進(jìn)一步被濾鏡處理
  4. 接下來(lái),被濾鏡處理的原始數(shù)據(jù)被傳遞給編碼器(encoder)
  5. 編碼器對(duì)傳遞過(guò)來(lái)的數(shù)據(jù)進(jìn)行編碼并輸出編碼數(shù)據(jù)包
  6. 最后,這些數(shù)據(jù)被復(fù)用器(muxer)寫(xiě)入輸出文件。

任何復(fù)雜的命令,都必須經(jīng)過(guò)上面這樣的轉(zhuǎn)碼過(guò)程,底層代碼你可以不看,但是整個(gè)過(guò)程必須了解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容