ffmpeg是一個(gè)非常好用的多媒體工具,不少音視頻編輯軟件其實(shí)都是內(nèi)置ffmpeg然后調(diào)用它的。一些簡(jiǎn)單的日常需求,對(duì)我來說,它無需付費(fèi),足夠好用,并且輕量。
下載安裝
http://ffmpeg.org/download.html頁(yè)面可以下載ffmpeg的源碼與可執(zhí)行文件,這里我們選擇Get packages & executable files。選擇對(duì)應(yīng)的平臺(tái),以windows為例,需要點(diǎn)擊windows徽標(biāo),下載對(duì)應(yīng)的windows builds。解壓完成后,將bin目錄添加到環(huán)境變量,安裝就完成了。
常用命令
媒體格式轉(zhuǎn)換
視頻格式轉(zhuǎn)換,準(zhǔn)確地說是視頻包裝格式轉(zhuǎn)換,比如你打算把一個(gè)flv的視頻轉(zhuǎn)換成mp4,則可以使用以下命令。
ffmpeg -i source.flv -acodec copy -vcodec copy out.mp4
-i表示輸入文件,-acodec表示音頻編解碼器,-vcodec表示視頻編解碼器,copy表示直接拷貝輸入流到輸出流。其中-acodec copy -vcodec copy可以簡(jiǎn)寫為-c copy。
假如說你打算提取出一個(gè)視頻中的音頻文件,并將其保存為mp3格式,那就更簡(jiǎn)單了,幾乎不需要什么額外的參數(shù)。
ffmpeg -i mv.mp4 music.mp3
音頻格式轉(zhuǎn)換,比如將aac格式轉(zhuǎn)換成wav格式。
ffmpeg -i source.aac out.wav
去除一個(gè)視頻中的音頻。
ffmpeg -i source.mp4 -an out.mp4
其中-an表示不要音頻。
媒體剪輯與合并
比如說現(xiàn)在有一個(gè)需求,需要剪輯視頻的1:01到1:31這段時(shí)間輸出為一個(gè)新的視頻。
ffmpeg -i source.mp4 -ss 00:01:01 -t 30 -c copy out.mp4
上述這段命令表示從1:01開始剪30秒的視頻,當(dāng)然,你也可以使用下面的命令:
ffmpeg -i source.mp4 -ss 00:01:01 -to 00:01:31 -c copy out.mp4
注意到,t表示剪輯的時(shí)長(zhǎng),而to表示剪輯的終點(diǎn)。你也可以將-ss放置在-i輸入文件的前面,不過,當(dāng)這樣使用時(shí),只可使用t選項(xiàng),而不可使用to。
ffmpeg -ss 00:01:01 -i source.mp4 -t 30 -c copy out.mp4
下載網(wǎng)絡(luò)視頻的一段
上文中提到的命令還有一個(gè)重要的用處,即下載網(wǎng)絡(luò)視頻的一段。比如說你在網(wǎng)上看到一個(gè)不錯(cuò)的視頻,打算將其中的一個(gè)精彩片段存下來。能夠想到的一個(gè)方法是,將整個(gè)視頻下載下來,再使用剪輯工具剪輯。可是這樣做會(huì)有幾個(gè)問題,一個(gè)是下載視頻文件耗時(shí)且費(fèi)流量,另一個(gè)問題則是占用硬盤空間。亦或者錄屏,然而畫質(zhì)會(huì)遭受損失。不過,有了ffmpeg,一切問題都迎刃而解。
首先,你需要解析出在線視頻的源地址,你可以使用一些在線解析工具,也可以按F12打開控制臺(tái)切換到network選項(xiàng)卡手動(dòng)查找。這里有一些技巧(將在另一篇文章中介紹),不過這不是本文的重點(diǎn)。
現(xiàn)在,假設(shè)你已經(jīng)獲得了視頻源地址,它可能是一個(gè)較大的mp4文件,或者是一個(gè)m3u8文件,不過這些并不影響。下面這個(gè)例子將一個(gè)網(wǎng)絡(luò)視頻中的01:01:01(一小時(shí)零一分一秒)到01:11:01下載到本地,并保存為download.mp4。
ffmpeg -ss 01:01:01 -i "https://example.com/hls/token/he-xu-yuan/player.m3u8?t=10086&key=10086&expiredtime=YIWANNIAN" -t 600 -c copy download.mp4
注意到,修改-i選項(xiàng)。是的,就是如此簡(jiǎn)單。請(qǐng)注意,必須將-ss選項(xiàng)放到-i前面。
自定義HTTP Header
當(dāng)輸入為網(wǎng)絡(luò)地址時(shí),有時(shí)可能需要自定義請(qǐng)求頭。此時(shí),使用-headers選項(xiàng)。
ffmpeg -ss 01:02:03 -headers "Referer: https://example.com/" -i "https://example.com/hls/token/he-xu-yuan/index.m3u8" 1.mp4
特別地,user-agent可以由-user_agent選項(xiàng)指定,即-user_agent "chrome"和-headers "user-agent: chrome"是等價(jià)的。
媒體合并
細(xì)心的朋友可能注意到,某些app緩存下來的視頻是三個(gè)文件,一個(gè)沒有聲音的視頻文件、一個(gè)原生音頻文件、還有一個(gè)媒體編碼信息info文件。此時(shí),一種可能的需求是將視頻文件和音頻文件合并。這并不麻煩。
ffmpeg -i movie.flv -i audio.flac -c copy out.mkv
注意到,只需多次使用-i選項(xiàng)。是的,這并不復(fù)雜。
然而,多數(shù)情況下,手機(jī)緩存下來的視頻可能是由一堆ts文件組成,如何將多個(gè)視頻文件片段合成一個(gè)完整的視頻呢?故技重施?好像并不可以。
此時(shí)需要新建一個(gè) list.txt 文件,告訴ffmpeg有哪些文件需要合并。格式如下:
file "1.ts"
file "2.ts"
file "3.ts"
然后,使用以下命令[1]:
ffmpeg -f concat -i list.txt -c copy out.mp4
問題在于,通常ts文件可能有100多個(gè),如果手打的話,十分費(fèi)勁。熟悉C語言的同學(xué),可以使用printf格式化輸出,并將輸出流重定向到文件。此時(shí),只需一個(gè)for語句即可。
上面的這個(gè)命令對(duì)于不是ts格式文件也可以使用,比如說都是flv格式的文件,此時(shí)輸出文件也需為out.flv。
然而,有時(shí)可能會(huì)遭遇一些問題,比如說需要合并的文件都是自己手工剪輯的,而非視頻網(wǎng)站切分好的文件。這時(shí),在合并完成后,你可能會(huì)看到一些錯(cuò)誤提示[2]。有時(shí)它并不會(huì)影響合并后的視頻正常播放,有時(shí)它會(huì)引起視頻時(shí)間軸錯(cuò)誤。此時(shí),可以嘗試將視頻先包裝進(jìn)ts文件中[1],再合并ts文件。
ffmpeg -i source.flv -c copy -bsf:v h264_mp4toannexb -f mpegts 1.ts
上述命令將一個(gè)flv文件轉(zhuǎn)為了ts文件,也可以嘗試將其轉(zhuǎn)為mts文件。
ffmpeg -i 1.mp4 -q 0 1.mts
其中,-q 0為指定輸出文件采用盡可能最好的質(zhì)量以實(shí)現(xiàn)輸入文件的畫面與聲音。
格式轉(zhuǎn)換完成后,再重新合并即可。
另一種情況,如果你能找到m3u8文件,此時(shí)只需要將其作為輸入即可。
ffmpeg -i index.m3u8 -c copy out.mp4
請(qǐng)注意,當(dāng)輸入文件為本地m3u8文件,而其中引用了網(wǎng)絡(luò)地址,會(huì)引發(fā)錯(cuò)誤(例如:Protocol 'https' not on whitelist 'file,crypto,data'!)。此時(shí),需要啟用協(xié)議白名單[3]。
其他
比如說現(xiàn)在有一個(gè)手機(jī)錄制的視頻,但聲音太小了,想將視頻文件中的聲音調(diào)大怎么辦?
ffmpeg -i source.mp4 -vcodec copy -filter:a "volume=3" out.mp4
上述命令對(duì)輸入流的視頻流直接拷貝,對(duì)音頻流使用過濾器,volume=3表示輸出文件的音頻流的基礎(chǔ)音量為源文件的3倍。如果需要調(diào)小視頻的音量,使用小數(shù)即可。
ffmpeg -i music.mp3 -filter:a "volume=0.5" out.mp3
上面的命令將一個(gè)mp3音樂文件中的基礎(chǔ)音量調(diào)小。