ffmpeg實現畫中畫效果
FFmpeg中,可以通過overlay將多個視頻流、多個多媒體采集設備、多個視頻文件合并到一個界面中,生成畫中畫的效果
FFmpeg 濾鏡 overlay 基本參數
-
x和y x坐標和Y坐標
-
eof action 遇到 eof表示時的處理方式,默認為重復。
repeat(值為 0):重復前一幀。
endcall(值為 1):停止所有的流
pass(值為 2):保留主圖層 -
shortest 終止最短的視頻時全部終止(默認false)
-
format 設置 output 的像素格式,默認為 yuv420。
yuv420(值為 0)
yuv422(值為 1)
yuv444(值為 2)
rgb (值為 3)
針對如上參數做詳細分析:
- eof action為1時,當子畫面時長較主畫面短時,當子畫面先播放完時此時主畫面也停止播放
- eof action為2時,子畫面先播完子畫面直接消失,保留主畫面繼續播放
- 設置shortest以兩個畫面誰的時長短為準終止所有視頻流播放
背景:現在有2個mp4文件,一個文件分辨率是854x480,另一個是320x240,想要通過ffmpeg實現把多路視頻流進行拼接,實現不同效果
ffmpeg -i input_854x480.mp4 -i input_320x240.mp4 -filter_complex "[1:v]scale=240:-1,setsar=1[small]; [0:v][small]overlay=W-w-10:H-h-10:shortest=1" -c:v libx264 -preset fast -c:a copy output_overlay.mp4
overlay 濾鏡將 ?320x240? 的小視頻作為畫中畫展示在右下角,如下圖所示:
下面針對各個參數做解釋:
- 縮放小視頻(320x240 → 240x135)
[1:v]scale=240:-1,setsar=1[small]
- scale=240:-1?:將小視頻寬度縮放到 240px,高度按比例自適應(原始寬高比 320:240=4:3 → 縮放后 240x135,保持 16:9)
- setsar=1?:強制設置像素寬高比為 1:1(防止播放時變形)
- 疊加到主視頻右下角
[0:v][small]overlay=W-w-10:H-h-10:shortest=1
- W-w-10?:X 坐標 = 主視頻寬度 (854) - 小視頻寬度 (240) - 右邊距 (10px) → 854-240-10=604
- H-h-10?:Y 坐標 = 主視頻高度 (480) - 小視頻高度 (135) - 下邊距 (10px) → 480-135-10=335
- ?shortest=1?:以最短的輸入流時長為準(若兩路視頻時長不同)
- 其他參數
- c:a copy?:直接復制主視頻的音頻流(若需混合兩路音頻,改用 amix 濾鏡)
- ?-preset fast?:平衡編碼速度與壓縮率
ffmpeg視頻添加水印
圖片水印
在FFmpeg中為視頻添加圖片水印,可以使用 overlay 濾鏡。這個濾鏡允許你將一個視頻或圖片疊加到另一個視頻上,從而實現水印效果。以下是一個基本的示例:
ffmpeg -i input_854x480.mp4 -i 1.jpeg -filter_complex "overlay=10:10" output.mp4
示例中,overlay 濾鏡被用于將 1.jpeg 圖片疊加到 input_854x480.mp4視頻上。參數解釋如下:
-
overlay:指定水印的位置,以像素為單位。這里的 10:10 表示在視頻的左上角添加水印。
你可以根據需要進行調整以滿足你的要求。如果你想要水印在視頻的不同時間段內逐漸出現或消失,你可以結合使用時間內置變量來實現,類似于之前提到的 drawtext 濾鏡的方法。 -
測試問題
實際測試發現圖片展示比較大而視頻分辨率較小導致畫面被整個占滿,考慮把圖片水印縮放后再疊加到視頻中。 -
解決方案
filter_complex濾鏡鏈中增加scale濾鏡調整水印尺寸,再通過overlay濾鏡疊加到視頻指定位置
ffmpeg -i input_854x480.mp4 -i 1.jpeg -filter_complex "[1:v]scale=iw*0.2:ih*0.2[wm];[0:v][wm]overlay=10:10" output_log_picture.mp4
?關鍵參數說明?
-
[1:v]scale=iw0.2:ih0.2[wm]
[1:v] 表示第二個輸入(水印圖片)的視頻流
iw0.2:ih0.2代表將水印圖片按原尺寸比例縮放至20%
[wm]是縮放后水印流的別名,供后續overlay濾鏡使用 -
[0:v][wm]overlay=10:10
將主視頻流 [0:v] 和縮放后的水印流 [wm] 疊加,位置在左上角坐標 (10,10) 處效果如下:
另外,你可以使用 x 和 y 參數來進一步調整水印的位置,以及使用 alpha 參數來設置水印的透明度。以下是一個更復雜的示例:
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=x=main_w-overlay_w-10:y=10:alpha=0.5" output.mp4
在這個示例中,水印被放置在視頻的右上角,同時設置了透明度為0.5。
ffmpeg多宮格展示多路視頻流
將三路視頻流通過hstack濾鏡水平方向展示,首先需要通過scale濾鏡將三個視頻流統一分辨率大小
ffmpeg -i input1.mkv -i input2.mp4 -i input3.flv -filter_complex "[0:v]scale=640:360[out1];[1:v]scale=640:360[out2];[2:v]scale=640:360[out3];[out1][out2][out3]hstack=inputs=3" output_hstack_multivideo.mp4
參數解釋:
- [0:v]scale=640:360[out1]
[0:v]代表第一路輸入視頻流
scale=640:360 通過scale濾鏡調整分辨率
[out1]是第一路視頻流別名,后續會用到
其他流同樣 - [out1][out2][out3]hstack=inputs=3
hstack濾鏡指定輸入流個數為3
進階想要展示2x2效果
ffmpeg -i input1.mkv -i input2.mp4 -i input3.flv -i input4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v]scale=320x240[upperleft];[1:v]scale=320x240[upperright];[2:v]scale=320x240[lowerleft];[3:v]scale=320x240[lowerright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320[tmp2];[tmp2][lowerleft]overlay=shortest=1:y=240[tmp3];[tmp3][lowerright]overlay=shortest=1:x=320:y=240" out_2x2.mp4
- overlay=shortest=1 確保以最短輸入流的時長為準輸出,避免因時長不一致導致黑屏
通過nullsrc 創建 overlay畫布,畫布大小 640:480,使用[0:wI[1:v][2:1[3:]將輸入的4個視頻流去除,分別進行縮放處理,然后基于nulsrc 生成的畫布進行視頻平鋪,命令中自定義 upperleft,upperright,lowerleft,lowerright 進行不同位置平鋪
效果如下: