【FFmpeg筆記】 從零開始之濾鏡

FFmpeg 除了具備強大的封裝/解封裝、編/解碼功能外,還包含了一個很是強大的組建---濾鏡avfilter。avfilter組建常常用於進行多媒體的處理與編輯,FFmpeg中包含多種濾鏡html

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能夠爲視頻添加水印,水印能夠時文字,也能夠時圖片,主要用來標記視頻歸屬bash

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濾鏡的一些參數ide

參數 類型 說明
filename 字符串 輸入的文件名,能夠是文件、協議、設備
format_name_,f 字符串 輸入的封裝格式
stream_index,f 整數 輸入的流索引編號
seek_point,sp 浮點數 Seek輸入流的時間位置
stream,s 字符串 輸入的多個流的流信息
loop 整數 循環次數
discontinuity 時間差值 支持跳動的時間戳差值

下面舉例說明,在FFmpeg中加入圖片水印有兩種方式,一是經過movie指定水印文件路徑,另一種方式是通filter讀取輸入文件的流並指定爲水印,這裏重點介紹如何讀取movie圖片文件做爲水印oop

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命令行基本格式以下:ui

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濾鏡配合使用,尤爲時用在圖層處理與合併場景中google

從上面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座標的內部變量,如同上面圖片疊加視頻的用法spa

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
複製代碼

參考:

相關文章
相關標籤/搜索