ffmpeg 覆盖背景 color/image 与多个视频

ffmpeg overlay background color/image with multiple videos

我是 ffmpeg 的新手,我不确定如何继续。

我有两个视频,我想将它们合并为一个带有背景 color/image 叠加层的视频。

下图是我想要实现的,矩形是主视频,圆形是另一个视频,红色是背景color/image。

视频信息:
一个.mp4
原始尺寸:1280x720
position/resized: (x20, y20, w980, h:keep-纵横比)

two.mp4
原始尺寸:1280x720
position/resized: (x-bottom, y-buttom-left, w:keep-aspect-ration, h200)

到目前为止,我只能添加一个背景颜色,但有一个问题,音频消失了,更不用说我什至没有添加第二个视频作为我命令的一部分。

ffmpeg -f lavfi -i color=c=white:s=1920x1080:r=24 -i video.mp4 -filter_complex "[0:v][1:v]overlay=shortest=1,format=yuv420p[out]" -map "[out]" output.mp4

关于如何实现它有什么建议吗? 提前致谢。

[编辑 3/19:为 OP 的需要添加了完整命令]

试试这个:

ffmpeg -i one.mp4, -i two.mp4, \
  -f lavfi -i color=c=white:s=1920x1080:r=30 \
  -f lavfi -i color=c=white:s=400x400:r=1,\
              format=yuva444p,\
              geq='lum(X,Y)':'cb(X,Y)':'cr(X,Y)':\
                  a='if(lt((X-200)^2+(Y-200)^2,200^2),0,255)' \
  -filter_complex \
    [0:v]scale=980:-1[L0];\
    [1:v]crop=600:600:20:20,scale=400:-1[L1];\
    [L1][3:v]overlay=shortest=1[L2];\
    [2:v][L0]overlay=20:20:shortest=1[L3];\
    [L3][L2]overlay=W-420:H-420[vout] \
  -map [vout] -map 0:a output.mp4
  • 第一个 color 输入 (2:v):这用作背景 canvas。它的帧率 r=30 将是输出帧率。
  • 第二个color输入(3:v):这是裁剪后的圆形遮罩two.mp4。请注意,我修复了 geq 滤镜,以便正确保持颜色(我之前拍摄的是灰度视频)
  • one.mp4(0:v) 被缩放到最终大小 -> [L0]
  • two.mp4(1:v) 首先被裁剪为正方形,捕获要在圆形切口中显示的内容。 crop 参数是 w:h:x:y,其中 x:y 是 upper-left 角的坐标。然后将裁剪后的帧缩放到最终大小(本例中为 400x400)-> [L1]
  • 裁剪和缩放后的 two.mp4 ([L1]) 然后被 3:v 输入屏蔽,以通过第一个 overlay 过滤器的圆形切口显示。
  • shortest=1 overlay 过滤器的选项在视频结束时结束(不是 color 将永远持续的来源)
  • 最后两个 overlay 过滤器将 2 个准备好的视频放在 canvas 上的所需位置。根据需要调整其参数以更改位置
  • 由于标清 (720p) 视频输入会转换为高清 (1080p) 视频输出,您可能不需要进行任何缩放。如果是这样,请从过滤器图中删除 scale 过滤器。对于 one.mp4,第一个过滤器链走了,所以在修改后的过滤器图中用 [0:v] 替换 [L0] 标签。

应该可以了。正如我们之前经历的那样,当您 运行 它时,请确保删除每个过滤器表达式中间的所有空格、换行符和反斜杠。

[原创]

我过去实施的一种方法是使用 geq 滤镜处理遮罩图像。您可以尝试以下方法:

为了便于说明,我使用了一个矩形,角为 upper-left (10,10),角为 lower-right (1500,900),圆心为 (1700, 950) 和半径 100.

ffmpeg -i input.mp4 \
  -vf color=c=red:s=1920x1080:r=1:d=1,\
      format=rgba,\
       geq=lum='lum(X,Y)':a='if(between(X,10,1500)*between(Y,10,900)+lt((X-1700)^2+(Y-950)^2,100^2),0,255)',\
      [v:0]overlay \
      output.mp4
  • color 源过滤器仅生成 1 帧(1 秒 1 fps)并且 overlay 将其应用于输入视频的每一帧
  • color 输出没有 alpha 通道,因此您需要转换为 pix_fmt
  • geq 设置所有像素的 alpha 值:如果坐标 (X,Y) 被屏蔽(因此它分配 alpha 值 255 = 不透明)或者如果 (X,Y) 未被屏蔽则为 True (alpha = 0,100% 透明)。参见 FFmpeg Expressions Documentation
  • overlay 获取输入视频流 v:0 并在其上叠加 geq 过滤器的输出。
  • 因为filtergraph是用-vf输出选项实现的,inpnnut音频流会自动映射

[编辑单行版本]

ffmpeg -i input.mp4 -vf color=c=red:s=1920x1080:r=1:d=1,format=rgba,geq=lum='lum(X,Y)':a='if(between(X,10,1500)*between(Y,10,900)+lt((X-1700)^2+(Y-950)^2,100^2),0,255)',[v:0]overlay output.mp4