一、簡述
ffmpeg是一個非常強大的工具,它可以轉換任何格式的媒體文件,並且還可以用自己的AudioFilter以及VideoFilter進行處理和編輯。有了它,我們就可以對媒體文件做很多我們想做的事情了。
二、命令行參數
1. 通用參數
- -f fmt : 指定格式
- -i filename:指定輸入文件名
- -y:覆蓋已有文件
- -t duration:指定時長
- -fs limit_size:設置文件大小的上限
- -ss time_off: 從指定的時間開始
- -re:代表按照時間戳讀取或發送數據,尤其在作為推流工具的時候一定要加上該參數,否則ffpmeg會按照最高速率向流媒體不停的發送數據。
- -map:指定輸出文件的流映射關系。例如:“-map 1:0 -map 1:1”要求按照第二個輸入的文件的第一個流和第二個流寫入輸出文件。如果沒有設置此項,則ffpmeg采用默認的映射關系。
2. 視頻參數
- -b:指定比特率(bit/s),ffmpeg默認采用的是VBR的,若指定的該參數,則使用平均比特率。
- -bitexact:使用標准比特率。
- -vb:指定視頻比特率(bit/s)
- -r rate:幀速率(fps)
- -s size:指定分辨率(320x240)
- -aspect aspect:設置視頻長寬比(4:3、16:9或1.33333、1.77777)
- -croptop size:設置頂部切除尺寸(in pixels)
- -cropleft size:設置左切除尺寸(in pixels)
- -cropbottom size:設置地步切除尺寸(in pixels)
- -cropright size:設置右切除尺寸(in pixels)
- -padtop size:設置頂部補齊尺寸(in pixels)
- -padleft size:設置左補齊尺寸(in pixels)
- -padbottom size:設置地步補齊尺寸(in pixels)
- -padright size:設置右補齊尺寸(in pixels)
- -padcolor color:設置補齊顏色
- -vn:取消視頻的輸出
- -vcodec codec:強制使用codec編碼方式
3. 音頻參數
- -ab:設置比特率(bit/s),對於MP3的格式,想要聽到較高品質的聲音,建議設置160Kbit/s(單聲道80Kbit/s)以上。
- -aq quality:設置音頻質量
- -ar ratre:設置音頻采樣率(Hz)
- -ac channels:設置聲道數,1就是單聲道,2就是立體聲
- -an:取消音頻輸出
- -acodec codec:強制使用codec編碼方式
- -vol volume:設置錄制音量大小
以上就是在日常開發中經常用到的音視頻參數及通用參數。下面會針對常見的開發場景進行實踐和說明。
三、實踐學習
1. 列出ffmpeg支持的所有格式
相關命令:
ffmpeg -formats
輸出結果:
File formats: D. = Demuxing supported .E = Muxing supported -- D 3dostr 3DO STR E 3g2 3GP2 (3GPP2 file format) E 3gp 3GP (3GPP file format) D 4xm 4X Technologies E a64 a64 - video for Commodore 64 D aa Audible AA format files D aac raw ADTS AAC (Advanced Audio Coding) DE ac3 raw AC-3
省略...... D xbin eXtended BINary text (XBIN) D xmv Microsoft XMV D xpm_pipe piped xpm sequence D xvag Sony PS3 XVAG D xwma Microsoft xWMA D yop Psygnosis YOP DE yuv4mpegpipe YUV4MPEG pipe
2. 剪切一段媒體文件,可以是音頻或者視頻文件
相關命令:
ffmpeg -i pm.mp4 -ss 00:00:50.0 -codec copy -t 20 output.mp4
命令說明:
表示將文件pm.mp4從第50s開始剪切20s的時間,輸出到output.mp4中,其中-ss指定偏移時間(time Offset),-t指定的時長(duration)。
但是直接這樣執行命令,固然我們能截取出來音視頻的文件,但是當我們播放的時候,我們會發現雖然ffmepg剪切視頻,很方便,但是也有很大缺陷:
(1). 剪切時間點不精確
(2). 有時剪切的視頻開頭有黑屏
造成這些問題的原因是ffmpeg無法seek到非關鍵幀上。
命令層面定位的話就是如果把-ss, -t參數放在-i參數之后,是對輸出文件執行的seek操作
輸入文件會逐幀解碼,直到-ss設置的時間點為止,這么操作會很慢,雖然時間點是准確的,但是很容易出現黑屏問題。
所以:我們優化了一下上面的那個命令,讓視頻的剪切更加精確:
ffmpeg -ss 10 -t 15 -accurate_seek -i pm.mp4 -codec copy output.mp4
注意:accurate_seek必須放在-i參數之前。
但是,可能又會有人發現,還是存在剪切不准確的現象,那是因為,上述命令只是進行了數據的轉封裝,會受到關鍵幀的影響,所以如果需要特別准確的剪切,只能使用ffmpeg進行重新編解碼的操作了,命令行如下:
ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a aac out.mp4
此命令行相對上面的轉封裝的剪切來說,速度明顯變慢,是因為對視頻數據重新編解碼了,但是精度相對轉封裝來說是大大提高了。
3. 提取視頻文件中的音頻數據,並保存為文件
相關命令:
ffmpeg -i pm.mp4 -vn -acodec copy output.m4a
命令說明:
將文件pm.mp4的視頻流禁用掉(參數為:-vn,如果禁用音頻流參數為-an,禁用字母流參數為-sn )。
然后將pm.mp4中的音頻流的數據封裝到output.m4a文件中,音頻流的編碼格式不變。
4. 將視頻中的音頻靜音,只保留視頻
相關命令:
ffmpeg -i pm.mp4 -an -vcodec copy output.mp4
命令說明:
將文件pm.mp4的音頻流禁用掉(參數為:-an )。
然后將pm.mp4中的視頻流的數據封裝到output.mp4文件中,視頻流的編碼格式不變。
5. 從mp4文件中抽取視頻流導出為裸H264數據:
相關命令:
ffmpeg -i pm.mp4 -an -vcodec copy -bsf:v h264_mp4toannexb output.h264
命令說明:
在指令中,我們舍棄了音頻數據(-an),視頻數據使用mp4toannexb這個bitstreasm filter來轉換為原始的H264數據。(注:同一編碼也會有不同的封裝格式)。
驗證播放:
可以使用ffplay命令進行嘗試播放,如果能播放成功,則說明生效。
6. 將視頻推送到流媒體服務器上:
ffmpeg -re -i pm.mp4 -acodec copy -vcodec copy -f flv rtmp://127.0.0.1/rh/mylive
命令說明:
將mp4文件的音視頻數據的編碼格式不變,按照rtmp的方式,將視頻推送到流媒體服務器上。
7. 將流媒體服務器上的流dump到本地:
ffmpeg -i rtmp://127.0.0.1/rh/mylive -acodec copy -vcodec copy -f flv test.flv
命令說明:
將流媒體服務器的數據,不進行轉碼,通過轉封裝的方式保存到本地。
8. 給視頻添加水印
ffmpeg -i pm.mp4 -i xxx.png -filter_complex "overlay=5:5" out.mp4
命令說明:
使用ffmpeg濾鏡功能,將對mp4添加水印。
9. 倒放音視頻
// 1.視頻倒放,無音頻 ffmpeg.exe -i inputfile.mp4 -filter_complex [0:v]reverse[v] -map [v] -preset superfast reversed.mp4 // 2.視頻倒放,音頻不變 ffmpeg.exe -i inputfile.mp4 -vf reverse reversed.mp4 // 3.音頻倒放,視頻不變 ffmpeg.exe -i inputfile.mp4 -map 0 -c:v copy -af "areverse" reversed_audio.mp4 // 4.音視頻同時倒放 ffmpeg.exe -i inputfile.mp4 -vf reverse -af areverse -preset superfast reversed.mp4
10. 將幾個MP4視頻文件合並為1個視頻.
實現思路:
1.先將MP4文件轉化為同樣編碼形式的ts流(ts流支持concate)
2.第二步,連接(concate)ts流
3.最后,把連接好的ts流轉化為MP4.
// 轉換為ts流
ffmpeg -i 0.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 0.ts ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 1.ts ffmpeg -i 2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 2.ts ffmpeg -i 3.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 3.ts ffmpeg -i 4.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 4.ts ffmpeg -i 5.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 5.ts // 合並ts流為mp4 ffmpeg -i "concat:0.ts|1.ts|2.ts|3.ts|4.ts|5.ts" -acodec copy -vcodec copy -absf aac_adtstoasc FileName.mp4