ffmpeg滤镜使用
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 进行不同位置平铺
效果如下: