ffmpeg第6篇:濾鏡語法

暖寶官方認證鏟屎官發表於2021-08-27

前言

哈哈,回來繼續填坑了,前段時間較忙沒時間寫,現在繼續~?

簡介

濾鏡是ffmpeg的一個很強大的功能,它支援許多有用的視訊處理功能,常見的濾鏡如:縮放、旋轉、水印、裁剪等
一個比較經典的濾鏡使用方法如下(來自ffmpeg官網):

                [main]
input --> split ---------------------> overlay --> output
            |                             ^
            |[tmp]                  [flip]|
            +-----> crop --> vflip -------+

上面的示意圖的流程是:將input複製A B兩份,A當作主畫面,B先裁剪,再垂直翻轉,然後將B覆蓋在A上當作水印
如果上面的事情用ffmpeg來實現的話,命令最終會是這樣

ffmpeg -i buck.mp4 -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" out.mp4 -y

如果是不瞭解濾鏡的同學,猛一看肯定是懵逼的,反正我當時是完全懵逼的狀態?,沒關係,慢慢來

看過之前文章(ffmpeg第2篇:簡單濾鏡與複雜濾鏡的區別)的同學應該知道,濾鏡分簡單濾鏡和複雜濾鏡,用-vf-lavfi來表示
而上面的命令用的是-vf,顯然這是一個簡單的濾鏡,因為它只有一個輸入和輸出

語法規則

分段

將濾鏡程式碼單獨拿出來

split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2

可以看到有分號(;)和逗號(,)兩種分隔符
那什麼時候用分號,什麼時候用逗號呢?簡單來說,規則就是:同一路的濾鏡間用逗號進行分割,不同路的濾鏡間用分號進行分割
怎麼理解上面的規則呢,不妨將整體濾鏡逐個拆解

  • split [main][tmp];
    這個動作就是將input複製兩份,一份名字是main,另一份名字叫tmp,後面跟了分號,因為拆完後已經兩路流了,不能再當一路流處理了,所以用分號隔開

  • [tmp] crop=iw:ih/2:0:0, vflip [flip];
    這個動作就是將tmp先剪裁(crop)再做垂直翻轉(vflip),輸出名字為flip的新資料流,對於裁剪和翻轉來說,都是處理的tmp這一路流,用逗號隔開即可。翻轉後面跟了分號,因為翻轉完我們們對它的操作結束了,後面要用它與main合併了,如果你還想繼續處理,那可以加個逗號繼續處理,比如我們們還想再給它壓縮一下解析度為640x360,就可以這樣
    [tmp] crop=iw:ih/2:0:0, vflip, scale=640:360 [flip];
    怎麼樣,現在能明白了吧?

  • [main][flip] overlay=0:H/2
    將最初的main流與經過處理的flip流合併

表示式

看一個新的命令
ffmpeg -i buck.mp4 -vf "split [main][tmp]; [tmp] crop=iw/4:ih/4:0:0 [crop]; [main][crop] overlay=y='if(lte(t,2),0,H-h)'" out.mp4 -y

相比上個命令,這個命令多了一對單引號包括起來的表示式:'if(lte(t,2),0,H-h)'
這個表示式中的t是ffmpeg內建的引數,表示的是timestamp時間戳的意思
其實對於程式設計師來說,一看就明白,它其實是個表示式,相當於在ffmpeg命令中執行程式,對於這種形式的命令(其它的還有諸如 gt、mod、between),ffmpeg要求使用單引號包括起來,便於ffmpeg解析,這是硬性要求,沒什麼不好理解的,知道有這個規則就好。

輸入輸出

每一個濾鏡都應該有輸入輸出,上面的命令ffmpeg -i buck.mp4 -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" out.mp4 -y中,我們們在分段章節拆分出了三個濾鏡,但是可以看到只有中間的濾鏡是有輸入([tmp])和輸出([flip])的,第一個沒有輸入,只有兩個輸出([main][tmp]),而最後一個只有兩個輸入([main][flip]),沒有輸出,為什麼?
因為這個命令中,只有一個輸入和輸出,所以:

  • 對於第一個濾鏡來說,預設將輸入(buck.mp4)當作它的輸入
  • 對於最後一個濾鏡來說,預設將輸出檔案(out.mp4)當作它的輸出

再看看這個命令
ffmpeg -i buck.mp4 -stream_loop -1 -i 3.mp4 -lavfi "[0:v] transpose [trans];[trans][1:v] overlay" -shortest out.mp4 -y

這個命令中,有兩個輸入(buck.mp4、3.mp4),對於第一個濾鏡([0:v] transpose [trans];)則需要手動指定具體是哪個輸入

結語

對於ffmpeg濾鏡來說,我覺得最難明白的就是它的語法,反正我學習下來感受是這樣的
對於掌握的同學來說,這些很簡單,但是對於不熟悉ffmpeg的同學來說,這個門檻可一點都不低
等了解了它的語法規則後我感覺你就學會了一半,剩下的無非是熟悉它支援哪些濾鏡,每個濾鏡的功能是什麼樣子的

文章目錄

ffmpeg第1篇:日誌級別控制、儲存日誌到指定檔案、處理進度查詢
ffmpeg第2篇:簡單濾鏡與複雜濾鏡的區別
ffmpeg第3篇:為視訊新增靜態水印
ffmpeg第4篇:為視訊新增動態水印
ffmpeg第5篇:讓水印圖片旋轉起來
ffmpeg第6篇:濾鏡語法

番外篇

ffmpeg番外篇:聽說這款水印曾經在某音很火?辦它!

有問題請留言溝通,歡迎轉載,轉載請註明出處

更多精彩內容,歡迎點選個人部落格地址:愉快程式設計

相關文章