轉(zhuǎn)發(fā)自白狼棧:查看原文
有些小伙伴看文章非常細(xì)心睬罗,對于上一節(jié)課不經(jīng)意提到的一些邊緣細(xì)節(jié)都比較在意揽惹,比如 -acodec、-vcodec彩掐、流復(fù)制等。其實這些都離不開我們今天要講的重點——流灰追。
說起流堵幽,可能有很多小伙伴第一反應(yīng)是流媒體狗超,但是我們今天要說的是容器內(nèi)流的類型。通過前面的介紹朴下,相信你對容器內(nèi)的音頻(audio, a)和視頻(video, v)都有了一些印象努咐。除此之外,容器內(nèi)流的類型還有字幕(subtitle, s)殴胧、附加數(shù)據(jù)(attachment, t)和普通數(shù)據(jù)(data, d)渗稍。我們重點介紹一下音頻流、視頻流和字幕流团滥。
流的操作竿屹,指的是我們可以從輸入文件中選擇不同的流進(jìn)行操作,然后輸出我們想要的結(jié)果灸姊。
舉個例子拱燃,家里有小孩的都應(yīng)該比較清楚,學(xué)辛撸現(xiàn)在有很多英語的配音比賽碗誉,大屏幕播放一段視頻,學(xué)生在舞臺上配音夯膀,非常形象诗充。
在這個場景中,大屏幕上播放的視頻诱建,其實就是無聲視頻蝴蜓。無聲視頻并不是把聲音調(diào)到最小,它指的是沒有音頻的視頻俺猿,這樣播放的視頻只有畫面茎匠。比方說對于前文案例一的素材視頻可以通過 -an 的命令去除音頻流,只保留視頻流即只有畫面(沒有下載的可以點擊這里下載)押袍。
ffmpeg -i r1ori.mp4 -an -y r1-silent.mp4
來看下結(jié)果視頻r1-silent.mp4的信息诵冒,沒有了 Stream #0:1(und): Audio 的信息。
? ffmpeg -i r1-silent.mp4 -hide_banner
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1-silent.mp4':
Metadata:
major_brand : isom
minor_version : 512 compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100 Duration: 00:00:58.53, start: 0.000000, bitrate: 1687 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1684 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
Metadata:
handler_name : VideoHandler
At least one output file must be specified
現(xiàn)在即使你把音響抱過來谊惭,聲音加到最大播放這個視頻汽馋,也不會聽到任何聲音。
-an 即 -acodec none圈盔。a指的是audio豹芯,codec指的是解碼器,-acodec就是音頻解碼器驱敲,合起來就是不指定音頻解碼器铁蹈,回顧下我們在ffmpeg是怎么轉(zhuǎn)碼的一文介紹的轉(zhuǎn)碼流程就很容易理解了。
你應(yīng)該已經(jīng)猜到了众眨,類似的我們還可以去除視頻流握牧、字幕流等容诬。
- -an 去除音頻流
- -vn 去除視頻流
- -sn 去除字幕流
- -dn 去除數(shù)據(jù)流
有同學(xué)可能注意到了,我們的原視頻的時長是59秒沿腰,還不到一分鐘览徒,但是 -an 的一條命令要花上十幾秒的處理時間,太慢了矫俺,有沒有辦法優(yōu)化下吱殉?
你仔細(xì)思考下,那么慢厘托,時間花在哪里了友雳?對,就是重新編碼铅匹。
這里我們只是去除音頻流押赊,有必要重新編碼嗎?沒有包斑,所以如果我們可以把視頻流復(fù)制出來是不是就好了流礁?
優(yōu)化后的命令如下
ffmpeg -i r1ori.mp4 -an -vcodec copy -y r1-silent.mp4
這條命令瞬間就輸出結(jié)果了。我們添加了一個參數(shù) -vcodec copy罗丰。-vcodec指的是視頻解碼器神帅,v是視頻video,codec是解碼器萌抵,后跟解碼器名稱找御,copy復(fù)制輸入的視頻流,不作解碼處理绍填。
同樣霎桅,如果我們想提取視頻中的音頻,或者說把視頻轉(zhuǎn)成音頻讨永,是不是可以用下面這條命令滔驶?
ffmpeg -i r1ori.mp4 -vn -c:a copy -y r1-silent.mp3
執(zhí)行該命令后發(fā)現(xiàn)報錯了
Invalid audio stream. Exactly one MP3 audio stream is required.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
提示我們音頻流無效,原因是codec的參數(shù)錯誤卿闹。我們看下原視頻的信息
? ffmpeg -i r1ori.mp4 -hide_banner
......
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
......
注意音頻流這行信息揭糕,我們發(fā)現(xiàn)音頻流是aac格式的,而我們要輸出的是mp3格式的锻霎,-c:a copy 參數(shù)意味著我們想要把aac格式的音頻流裝進(jìn)mp3容器插佛,這是不可行的。aac 音頻流需要一個專用的 aac 容器量窘,mp3 音頻流需要專用的 mp3 容器。
注:aac 和 mp3 都是有損壓縮音頻編碼格式氢拥。
找到原因就好辦了蚌铜,我們把輸出的mp3格式修改成aac格式
ffmpeg -i r1ori.mp4 -vn -c:a copy -y r1-silent.aac
雖然mp4容器內(nèi)的音頻流大多數(shù)都是aac格式锨侯,但是,試想一下如果我們寫好程序冬殃,要針對用戶上傳的視頻提取音頻并做存儲囚痴,偏偏用戶上傳的原視頻內(nèi)的音頻是mp3呢?
為了滿足這一場景审葬,我們制作一個含mp3格式的視頻深滚,然后再執(zhí)行上面的命令試試。
1涣觉、把r1ori.mp4視頻內(nèi)的音頻流轉(zhuǎn)成mp3
ffmpeg -i r1ori.mp4 -c:a libmp3lame -c:v copy -y r2.mp4
注:由于ffmpeg沒有原生的mp3編碼器痴荐,所有我們指定了外部的libmp3lame編碼庫(雖然 -c:a libmp3lame 你也可以把libmp3lame改為mp3,實際上使用的還是libmp3lame)官册。如果你執(zhí)行上面的命令報了一個類似這樣的錯誤 ERROR: libmp3lame >= 3.98.3 not found生兆,說明你本地的ffmpeg沒有添加--enable-libmp3lame編譯參數(shù),可以參考這篇文章選擇對應(yīng)的方式重新安裝ffmpeg膝宁;
2鸦难、提取該視頻的音頻
ffmpeg -i r2.mp4 -vn -c:a copy -y r1-silent.aac
報錯:Only AAC streams can be muxed by the ADTS muxer
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
所以,-c:a copy 不是萬能的员淫,也就是說如果我們想讓視頻轉(zhuǎn)音頻合蔽,最好指定一種編碼器,用aac還是libmp3lame介返?就音質(zhì)質(zhì)量而言拴事,我們更推薦libmp3lame,盡管ffmpeg自帶的最好音頻編碼器是aac映皆。
綜上挤聘,如果你需要輸出mp3格式的音頻,你可以使用
ffmpeg -i r1ori.mp4 -vn -c:a libmp3lame -y r1-silent.mp3
如果你想輸出aac格式的音頻捅彻,你可以使用
ffmpeg -i r1ori.mp4 -vn -c:a aac -y r1-silent.aac
注:新版本的ffmpeg是支持原生aac編碼的组去,所以可以直接使用 -c:a aac,低版本的ffmpeg像2.x的版本原生aac編碼器是不完全支持的步淹,必須同時指定 -strict -2 才可以使用从隆。
以上,我們介紹了手動指定音頻解碼器缭裆,成功的將視頻轉(zhuǎn)換成了音頻键闺。
既然ffmpeg那么厲害,那如果我們不手動指定澈驼,它能自動幫我們選擇合適的解碼器處理嗎辛燥?
非常可以。
以mp3為例挎塌,我們試下
ffmpeg -i r1ori.mp4 -y r1-silent.mp3
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4':
......
Stream mapping: Stream #0:1 -> #0:0 (aac (native) -> mp3 (libmp3lame))
......
注意看輸出的過程代碼中包含 Stream mapping 以及其下一行代碼徘六,可以看出ffmpeg的確自動為我們選擇了libmp3lame解碼器。
如果原視頻有多路音頻流榴都,又該如何操作呢待锈?我們下節(jié)課再說。