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
我是 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_fmtgeq
设置所有像素的 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