轉(zhuǎn)發(fā)自白狼棧:查看原文
閱讀目錄
視頻是怎么被播放的?
我們知道蝗羊,當(dāng)下大多數(shù)播放器都是基于ffmpeg二次開發(fā)的藏澳。你有沒有想過,你用播放器打開一個視頻的時候耀找,是怎么看到的畫面翔悠,怎么聽到的聲音?
我們用這張圖簡單描繪出視頻被播放的流程涯呻。
下面稍微解釋下圖中的含義凉驻。
- 解封裝:播放器將輸入的封裝格式(mp4、mkv)的數(shù)據(jù)分離复罐,產(chǎn)生音頻流和視頻流兩部分涝登,注意此時這兩部分數(shù)據(jù)還只是壓縮的數(shù)據(jù),類似分流效诅,后面我們也會介紹如何從視頻文件中抽離出音頻和視頻胀滚。
- 下一步就是解碼操作了趟济,我們說解碼就是將視頻、音頻壓縮的編碼數(shù)據(jù)咽笼,解碼成為非壓縮的視頻顷编、音頻原始數(shù)據(jù)。這里將音頻解碼為pcm格式的數(shù)據(jù)剑刑,將視頻解碼為yuv格式的數(shù)據(jù)媳纬。
- 音視頻同步播放:把解封裝和解碼分別拿到的視頻信息和音視頻數(shù)據(jù),發(fā)送給顯卡和聲卡即可播放施掏。
ffmpeg命令的格式
我們在音視頻基礎(chǔ)概念一文中介紹轉(zhuǎn)碼的時候钮惠,拋出過一條轉(zhuǎn)碼的命令,如下
ffmpeg -i input.flv output.mp4
對于ffmpeg命令的基本格式七芭,參考ffmpeg官網(wǎng)
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
翻譯過來就是
ffmpeg [全局選項] {[輸入文件選項] -i 輸入文件} ... {[輸出文件選項] 輸出文件} ...
... 表示一條命令可能會有多個輸入和多個輸出素挽。
比如我們可以通過輸入多個文件轉(zhuǎn)碼后輸出多個文件
ffmpeg -i input1 -i input2 \
-acodec … -vcodec … output1 \
-acodec … -vcodec … output2 \
-acodec … -vcodec … output3
據(jù)不完全統(tǒng)計,ffmpeg命令的選項數(shù)量就有小幾萬狸驳,所以不僅要多掌握學(xué)習(xí)技巧预明,更多的是多積累經(jīng)驗,靠死記硬背是完全行不通的耙箍。
那么多的選項撰糠,體現(xiàn)在一條命令上,一個基本的通用規(guī)則就是:
輸入文件選項只作用于它后面的第一個輸入文件究西,自然窗慎,輸出文件選項也只作用于它后面的第一個輸出文件。所以是有順序要求的卤材。
全局選項倒是可以隨便寫遮斥,比如有個全局選項 -y,詢問我們是否要覆蓋輸出扇丛,下面兩種寫法都可以
ffmpeg -y -i input.flv output.mp4
ffmpeg -i input.flv -y output.mp4
但是术吗,如果命令很長很長(比如我們前面給的音視頻案例,一條命令甚至都有幾百個字符)帆精,類似這種全局選項较屿,最好寫在輸入文件前面或者輸出文件前面。
另外卓练,千萬不要先寫輸出文件隘蝎,再寫輸入文件,至少應(yīng)該寫完輸入文件襟企,再寫輸出文件嘱么,比如下面這樣就是不好的寫法
ffmpeg output.mp4 -i input.flv
良好的習(xí)慣才是好的開始。
ffmpeg轉(zhuǎn)碼輸出的過程
ffmpeg -i input.flv output.mp4
還是上面這條簡單的轉(zhuǎn)碼命令顽悼,對于類似這樣的一條命令曼振,對于ffmpeg几迄,又是怎么處理的呢?
我們用下面這個圖來表示轉(zhuǎn)碼輸出的過程冰评。
具體描述如下
- ffmpeg 調(diào)用一個包含解復(fù)用器demuxer的libavformat庫映胁,從輸入文件中讀取包含編碼的數(shù)據(jù)包
- 然后將編碼的數(shù)據(jù)包傳遞給解碼器(decoder)(流復(fù)制操作忽略該步驟)
- 解碼器(decoder)產(chǎn)生未壓縮的幀(即原始幀)可以進一步被濾鏡處理
- 接下來,被濾鏡處理的原始數(shù)據(jù)被傳遞給編碼器(encoder)
- 編碼器對傳遞過來的數(shù)據(jù)進行編碼并輸出編碼數(shù)據(jù)包
- 最后甲雅,這些數(shù)據(jù)被復(fù)用器(muxer)寫入輸出文件解孙。
任何復(fù)雜的命令历造,都必須經(jīng)過上面這樣的轉(zhuǎn)碼過程蚜厉,底層代碼你可以不看汹粤,但是整個過程必須了解惕橙。