1. 程式人生 > >黃聰:FFmpeg視頻轉碼技巧之-crf參數(H.264篇)

黃聰:FFmpeg視頻轉碼技巧之-crf參數(H.264篇)

文件中 one log 它的 忽略 enter center tail vcd

昨天,有個朋友給我出了個難題:他手上有一個視頻,1080P的,49秒,200多兆;要求在確保質量的情況下把文件壓縮到10M以內。

這是什麽概念呢?按照文件大小10M來計算,碼率是:10 x 8 / 49 = 1.6 Mbps。也就比VCD的質量略好一點(註:VCD的標準碼率是1150 Kbps)。談何“確保質量”?mission impossible啊!

咱還是現實一點吧。在不明顯損失畫質的前提下,看看使用FFmpeg能夠幫到多少忙。用iPhone拍了一個1920 x 1080的視頻,33秒,46.3 MB,編碼格式是H.264。考慮到H.264目前尚是主流的視頻格式,為了播放的兼容性,我們在使用FFmpeg轉碼時同樣選擇H.264。

命令行參數-crf

在優先保證畫面質量(也不太在乎轉碼時間)的情況下,使用-crf參數來控制轉碼是比較適宜的。這個參數的取值範圍為0~51,其中0為無損模式,數值越大,畫質越差,生成的文件卻越小。從主觀上講,18~28是一個合理的範圍。18被認為是視覺無損的(從技術角度上看當然還是有損的),它的輸出視頻質量和輸入視頻相當。

我們的策略是,在保證可接受視頻畫質的前提下,選擇一個最大的crf值——如果輸出視頻質量很好,那就嘗試一個更大的值;如果看起來很糟,那就嘗試一個小一點的值。

讓我們先執行下面這條命令(關於FFmpeg運行環境的配置,請參閱這篇文章):

ffmpeg -i D:\src.mov -c:v libx264 -preset veryslow -crf 18 -c:a copy D:\dest1.mp4

意思是:將D盤的源文件src.mov,以“非常慢”的速度重新編碼成H.264格式,保存為D:\dest1.mp4。其中,-preset指定的編碼速度越慢,獲得的壓縮效率就越高。而-c:a copy又是什麽意思呢?因為音頻的碼率一般都比較小,我們就不折騰它了,況且解碼後重新編碼也會損害音質,於是,就將音頻數據從源文件中以原有編碼格式直接拷入目標文件吧。

小提示:想知道-c:v 後面的參數值怎麽填嗎?或者說FFmpeg到底支持哪些音視頻編碼格式?執行ffmpeg –encoders看一下吧。另外,執行ffmpeg -i D:\src.mov -c:v libx264 -preset -tune D:\dummy.mp4可以看到-preset參數的取值範圍,如下:

技術分享

有個小疑問:既然不在乎等待時間,為什麽不給-preset指定一個最慢的placebo呢?那是因為:與 veryslow相比,placebo以極高的編碼時間為代價,只換取了大概1%的視頻質量提升。這是一種收益遞減準則:slow 與 medium相比提升了5%~10%;slower 與 slow相比提升了5%;veryslow 與 slower相比提升了3%。

另外,針對特定類型的源內容(比如電影、動畫等),還可以使用-tune參數進行特別的優化。但如果你不確定該用哪個選項,還是忽略這個參數吧。

對比效果

執行完一條轉碼命令之後,調整-crf參數值,分別設為19、20、28、51,重新轉碼輸出為不同的MP4文件。記錄數據,對比如下:

crf = 18

crf = 19

crf = 20

crf = 28

crf = 51

文件大小(MB)

46.3

36.7

31.2

26.5

7.95

1.25

縮減比率

21%

33%

43%

83%

97%

嘗試播放這些文件。發現crf取值為18~28的情況下生成的文件,其畫質沒有明顯的差異,而以-crf 51生成的視頻畫質已經慘不忍睹了!在實際應用中,多試幾個crf值,在畫質和壓縮比之間找到一個你能接受的平衡點即可。

參考文章:ffmpeg與x264編碼指南

黃聰:FFmpeg視頻轉碼技巧之-crf參數(H.264篇)