FFmpeg 除了具有強大的封裝/解封裝、編/解碼功能外,還包含了一個非常強大的組建---濾鏡avfilter。avfilter組建經常用於進行多媒體的處理與編輯,FFmpeg中包含多種濾鏡
1.FFmpeg 濾鏡filter的引數排列方式
為了便於理解Filter,下面用最簡單的方式來描述Filter使用時的引數排列方式:
[輸入流或標記名]濾鏡引數[臨時標記名];[輸入流或標記名]濾鏡引數[臨時標記名]...
文字描述的排列方式很明確,接下來列舉一個簡單的例子:輸入兩個檔案,一個視訊input.mp4,一個圖片logo.png,將logo進行縮放,然後放在視訊的左上角
複製程式碼
ffmpeg -i test.mp4 -i logo.png -filter_complex "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" filter.mp4
將logo.png的影像六縮放為176*144解析度,然後定義一個臨時標記名logo,最後將縮放後的影像[logo]鋪在輸入的視訊test.mp4的視訊流[0:v]的左上角
複製程式碼
2.FFmpeg 濾鏡filter時間內建變數
在使用Filter時,經常會用到根據時間軸進行操作的需求,在使用FFmpeg的Filter時可以使用Filter的時間相關的內建變數,下面先來了解下這些相關的變數,如下表,在下面可以使用到
變數 | 說明 |
---|---|
t | 時間戳以秒錶示,如果輸入的時間戳時位置的,則是NAN |
n | 輸入幀的順序編號,從0開始 |
pos | 輸入幀的位置,如果位置則是NAN |
w | 輸入視訊幀的寬度 |
h | 輸入視訊幀的高度 |
3.FFmpeg 為視訊新增水印
FFmpeg可以為視訊新增水印,水印可以時文字,也可以時圖片,主要用來標記視訊歸屬
3.1 文字水印
在視訊中增加文字水印需要準備的條件比較多,需要有文字字型檔處理的相關檔案,在編譯FFmpeg時需要支援FreeType、FontConfig、iconv,系統中需要有相關的字型檔,在FFmpeg中增加純字母水印可以使用drawtext濾鏡進行支援,下面就是drawtext的濾鏡引數
複製程式碼
引數 | 型別 | 說明 |
---|---|---|
fontfile | 字串 | 字型檔案 |
text | 字串 | 文字 |
textfile | 字串 | 文字檔案 |
fontcolor | 字串 | 字型顏色 |
box | 字串 | 文字區域背景框 |
boxcolor | 字串 | 展示字型顏色的區域快的顏色 |
fontsize | 字串 | 顯示字型的大小 |
font | 字串 | 字型名稱(預設為Sans字型) |
x | 字串 | 文字顯示的x座標 |
y | 字串 | 文字顯示的y座標 |
使用舉例
ffmpeg -i out2.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='hello world ':x=20:y=20" waterfont.mp4
執行後即可在視訊左上角增加hello world 文字水印,文字顏色為純黑,為了讓水印更柔和,可以通過drawtext濾鏡的fontcolor引數調節顏色,比如設為綠色
ffmpeg -i out2.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='hello world ':x=20:y=20:fontcolor=green" waterfont.mp4
還可以呼叫一些系統資料,比如水印按當前時間來顯示
ffmpeg -re -i out2.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':x=20:y=20:fontcolor=green" waterfont4.mp4
複製程式碼
3.2 圖片水印
FFmpeg除了可以向視訊新增文字水印外,還可以向視訊新增圖片水印,視訊跑馬燈等,為視訊新增水印可以使用movie濾鏡,下面就是movie濾鏡的一些引數
引數 | 型別 | 說明 |
---|---|---|
filename | 字串 | 輸入的檔名,可以是檔案、協議、裝置 |
format_name_,f | 字串 | 輸入的封裝格式 |
stream_index,f | 整數 | 輸入的流索引編號 |
seek_point,sp | 浮點數 | Seek輸入流的時間位置 |
stream,s | 字串 | 輸入的多個流的流資訊 |
loop | 整數 | 迴圈次數 |
discontinuity | 時間差值 | 支援跳動的時間戳差值 |
下面舉例說明,在FFmpeg中加入圖片水印有兩種方式,一是通過movie指定水印檔案路徑,另外一種方式是通filter
讀取輸入檔案的流並指定為水印,這裡重點介紹如何讀取movie圖片檔案作為水印
ffmpeg -i out2.mp4 -vf "movie=water_pic.png[wm];[in][wm]overlay=30:10[out]" waterPic.mp4
圖片就會出現在視訊的左上角
也可以用movie與colorkey濾鏡配合做成半透明效果,例如
ffmpeg -i out2.mp4 -vf "movie=water_pic.png,colorkey=black:1.0:1.0 [wm];[in][wm]overlay=30:10[out]" waterPicAlpha.mp4
此時圖片以30%透明度顯示在左上角,[wm]作用為給前面命名
複製程式碼
3.3 overlay的濾鏡用法
overlay又稱視訊疊加技術,overlay視訊技術使用非常廣泛,常見的例子有上面的圖片水印以及下面會提到的畫中畫功能,畫中畫功能值得是在一個大視訊播放視窗中還存在一個小播放視窗,兩個視窗不同的視訊內容同時播放。 overlay 技術中設計兩個視窗,通常把較大的視窗稱為背景視窗,較小的視窗稱為前景視窗,兩者皆可以播放視訊或顯示圖片.
overlay濾鏡說明如下
描述 | 說明 |
---|---|
語法 | overlay[=x:y[[:rgb={0, 1}]]引數x和y是可選的,其預設值為0 rgb引數是可選的,其值為0或1 |
x | 從左上角開始的水平座標,預設為0 |
y | 從左上角開始的垂直座標,預設為0 |
rgb | rgb = 0…輸入的顏色空間不改變,預設值rgb = 1…輸入的顏色空間設定為RGB |
main_w 或者 W | 主輸入(背景視窗)寬度 |
main_h 或者 H | 主輸入(背景視窗)高度 |
overlay_w 或者 w | overlay輸入(前景視窗)寬度 |
overlay_h或者h | overlay輸入(前景視窗)高度 |
eof_action | 遇到eof標誌時的處理方式。預設為重複 repeat(值為0) :重複前一幀 endall(值為1) :停止所有幀 pass(值為2) :保留主圖層 |
format | 設定output的畫素格式。預設為yuv420 yuv420(值為0) yuv422(值為1) yuv444(值為2) rgb(值為3) |
shortest | 布林值,終止最短視訊時全部終止(預設關閉) |
overlay濾鏡用法
使用overlay命令列基本格式如下:
ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output
使用一個簡單例子,將圖片疊在視訊的右上角,效果如下圖
ffmpeg -i test.mp4 -i chenyao.png -filter_complex overlay=W-w:56 -max_muxing_queue_size 1024 overlay.mp4
複製程式碼
3.4 FFmpeg生成畫中畫
除了上述overlay新增圖示在視訊上外,在使用FFmepg處理流媒體檔案時,有時需要使用畫中畫效果。在FFmpeg中,可以通過overlay將多個視訊流、多個多媒體採集裝置、多個視訊檔案合併到一個介面中,生成畫中畫效果。在前面的濾鏡使用中和以後的濾鏡使用中,與視訊操作相關的處理,大多數會與overlay濾鏡配合使用,尤其時用在圖層處理與合併場景中
從上面3.3的引數列表中可以看到,主要引數並不多,但實際上在overlay濾鏡使用中,還有很多組合的引數可以使用,可以使用一些內部變數,例如overlay圖層的寬、高、座標等,下面列舉幾個畫中畫的例子
ffmpeg -re -i out2.mp4 -vf "movie=output.avi,scale = 480*320[test]; [in][test] overlay [out]" -vcodec libx264 videoInvideo.mp4
複製程式碼
上圖為顯示畫中畫的最基本方式,如果希望子視訊顯示在指定位置,例如顯示在畫面右下角,則需要用到overlay中x座標與y座標的內部變數,如同上面圖片疊加視訊的用法
ffmpeg -re -i out2.mp4 -vf "movie=output.avi,scale = 480*320[test]; [in][test] overlay=x=main_w-500:main_h-500 [out]" -vcodec libx264 videoInvideo.mp4
複製程式碼
以上兩種視訊畫中畫的處理均為靜態位置處理,使用overlay還可以配合正規表示式進行跑馬燈進行畫中畫處理
ffmpeg -re -i out2.mp4 -vf "movie=output.avi,scale = 480*320[test]; [in][test] overlay=x='if(gte(t,2),-w+(t-2)*20,NAN)':y=0 [out]" -vcodec libx264 videoInvideo.mp4
圖片就不上了,效果為一個視訊從左到右緩緩移動
複製程式碼
3.4 FFmpeg 濾鏡圖,濾鏡鏈,濾鏡之間的關係
濾鏡圖(filtergraph):跟在 -vf 之後的就是一個濾鏡圖 濾鏡鏈(filterchain):一個濾鏡圖包含多個濾鏡鏈 濾鏡(filter):一個濾鏡鏈包含多個濾鏡 概括來說就是:濾鏡 ∈ 濾鏡鏈 ∈ 濾鏡圖 FFmpeg支援多種濾鏡,檢視全部濾鏡
$ ffmpeg -filters
一個濾鏡圖的例子如下:
ffmpeg -i out2.mp4 -vf [in]scale=640.0:480.0[wm]; movie='logo.png',scale=92.25:30.0[logo];
[wm][logo]overlay=main_w-overlay_w-24.0:24.0[out] output.mp4
複製程式碼
在該示例中,有三個濾鏡鏈:
- [in]scale=640.0:480.0[wm]
- movie='logo.png',scale=92.25:30.0[logo]
- [wm][logo]overlay=main_w-overlay_w-24.0:24.0[out] 可以看到,濾鏡鏈是使用分號 ";" 來分隔,濾鏡鏈中的濾鏡使用逗號 "," 來分隔;濾鏡鏈沒有指定輸入或者輸出,預設使用前面的濾鏡鏈的輸出為輸入,並輸出給後面的濾鏡鏈作為輸入,
簡單濾鏡和複雜濾鏡(Simple filtergraphs 和 Complex filtergraphs)
- Simple filtergraphs(簡單濾鏡):該濾鏡只有一個輸入和一個輸出,實際就是新增在解碼和編碼步驟之間的操作,如下圖所示。
簡單filtergraphs配置了每個流的篩選器選項(與視訊和音訊分別-vf和-af別名)。
- Complex filtergraphs(複雜濾鏡):複雜filtergraphs是那些不能被描述為簡單的線性處理鏈的濾鏡組。例如,當濾鏡組具有多個輸入和/或輸出,或當輸出流的型別是不同於輸入。它們可以被表示為以下圖:
複雜濾鏡圖使用
-filter_complex
選項來表示,與-vf
不同在於他有多個輸入。該選項是全域性的, -lavfi 選項等同於-filter_complex
,一個具體的例子就是,overlay
濾鏡,該濾鏡有兩個視訊輸入,一個視訊輸出,輸出視訊是一個輸入視訊覆蓋在另一個視訊之上的結果,音訊有同等的amix
濾鏡
-map :-vf、-filter_complex合併
有事會遇到有的使用-vf
,有的又必須使用-filter_complex
,怎樣將這兩項整合起來呢,下面有幾個示例,總體的思路就是將單輸入輸出的-vf
整合到 -filter_complex
中去,這時會用到 第三條中的媒體流選擇 -map
示例(該示例我未驗證過)
************************* vf 與 filter_complex結合·示例一 **************************
ffmpeg -i input.mp4
-vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=720x720"
-an -c:v libx264 -profile:v high -level 4.1 -preset superfast -crf 20
output.mp4
========================================
ffmpeg -i input.mp4 -filter_complex \
"[0:v]trim=0:4.95,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=4.95:6.75,setpts=PTS-STARTPTS[v2]; \
[0:v]trim=6.75:8,setpts=PTS-STARTPTS[v3]; \
[v2]setpts=PTS/0.1[vslow2]; \
[v1][vslow2][v3]concat=n=3:v=1:a=0[out]" \
-map [out] -an -c:v libx264 -profile:v high -level 4.1 \
-preset superfast -crf 20 -r 30 output.mp4
=================合成====================
ffmpeg -i input.mp4 -filter_complex \
"[0:v]crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)',scale=720x720,split=3[1v][2v][3v]; \
[1v]trim=0:4.95,setpts=PTS-STARTPTS[v1]; \
[2v]trim=4.95:6.75,setpts=(PTS-STARTPTS)/0.1[v2]; \
[3v]trim=6.75:8,setpts=PTS-STARTPTS[v3]; \
[v1][v2][v3]concat=n=3:v=1:a=0[out]" \
-map [out] -an -c:v libx264 -profile:v high -level 4.1 \
-preset superfast -crf 20 -r 30 output.mp4
複製程式碼
參考:
-
FFmpeg從入門到精通 -劉岐
-
FFmpeg中的濾鏡(filter)知識點記錄
-
FFmpeg中overlay濾鏡用法-水印及畫中畫