为视频提供圆形透明边缘,以便它可以使用 FFMPEG 覆盖在另一个视频上

Kev*_*sti 4 video ffmpeg

我试图将一个较小的视频(200x200)叠加在一个较大的视频(800x800)之上。

我已经使用 FFMPEG 覆盖过滤器来实现这一目标

    ffmpeg -i big.mp4 -vf "movie=small.mkv[clip2]; [in][clip2] overlay=1:5 [out]"  final.mp4
Run Code Online (Sandbox Code Playgroud)

挑战在于较小的视频需要将其边缘修圆。我曾尝试使用 alphaextract 和 alphamerge。关于 FFMPEG 的文档很少,我不知道如何去做。

fis*_*ion 7

虽然我认为现有的答案适用于圆形,但听起来您想要更多的“圆角矩形”。这是我如何做到的:

[1]format=yuva420p,geq=lum='p(X,Y)':a='if(gt(abs(W/2-X),W/2-10)*gt(abs(H/2-Y),H/2-10),if(lte(hypot(10-(W/2-abs(W/2-X)),10-(H/2-abs(H/2-Y))),10),255,0),255)'[rounded];
Run Code Online (Sandbox Code Playgroud)

关于format

α值不能在不具有现有的alpha通道的源极被改变。所以format=yuva420p过滤器添加一个(即ain yuva)。从我所看到的,yuva444p也很常见(在其他答案中使用),但其他格式rgba应该可以工作,前提是它们有一个 alpha 通道。我的原始来源是yuv420p所以我制作了我的yuva420p

关于geq

似乎你不能改变alpha 通道(如果你尝试,你会得到一个错误“亮度或 RGB 表达式是强制性的”),所以这lum='p(X,Y)'基本上是一个虚拟的无操作,允许你改变 alpha 而不改变其他任何东西。

为了不需要单独检查每个角,X和Y通过公式转换为左上象限:

X' = W/2-abs(W/2-X)
Y' = H/2-abs(H/2-Y)
Run Code Online (Sandbox Code Playgroud)

公式的第一部分检查是否X'Y'是否在茅草区域内:

左上象限

也就是说,是否:

    X' < 10
and Y' < 10
Run Code Online (Sandbox Code Playgroud)

如果不是,a则设置为255(即,显示像素)。

如果它们落在此区域内,则计算点(X,Y)与圆心之间的距离(10,10)。如果该点(X,Y)落在圆内,a则设置为255; 否则,a设置为0,并且该像素被隐藏。

可以更改半径以提供更多或更少的“舍入”。半径为的完整示例命令20是:

ffmpeg -f lavfi -i color=darkblue:size=800x600 -f lavfi -i color=gray:size=600x450 -frames:v 180 -filter_complex "[1]format=yuva420p,geq=lum='p(X,Y)':a='if(gt(abs(W/2-X),W/2-20)*gt(abs(H/2-Y),H/2-20),if(lte(hypot(20-(W/2-abs(W/2-X)),20-(H/2-abs(H/2-Y))),20),255,0),255)'[rounded];[0][rounded]overlay=x=(W-w)/2:y=(H-h)/2" example.mp4
Run Code Online (Sandbox Code Playgroud)

给出结果:

示例圆角矩形视频帧

在我的示例中,我使用1020作为圆的半径,但您可以将其更改为任何数字,以使拐角或多或少变得圆润。

  • 惊人的!为了方便起见,我用 shell 变量替换了边界半径的数字: `corner_radius=10` `ffmpeg -f lavfi -i color=darkblue:size=800x600 -f lavfi -i color=gray:size=600x450 -frames:v 180 -filter_complex "[1]format=yuva420p,geq=lum='p(X,Y)':a='if(gt(abs(W/2-X),W/2-${角半径})*gt(abs(H/2-Y),H/2-${角半径}),if(lte(hypot(${角半径}-(W/2-abs(W/2-X))) ,${corner_radius}-(H/2-abs(H/2-Y))),${corner_radius}),255,0),255)'[四舍五入];[0][四舍五入]叠加=x= (Ww)/2:y=(Hh)/2" 示例.mp4` (3认同)
  • 如果你的圆角是锯齿状的(锯齿),你可以最初将尺寸设置为两倍大(“... color=gray:size=1200x900 ...”),然后在这个更大的画布上运行“geq”,最后缩小规模。然后圆角就会消除锯齿并显得更平滑。(但是在这种情况下,最好对圆角使用百分比值。) (2认同)

dra*_*ke7 3

带有圆形覆盖层的主电影(第二部电影结果

ffmpeg \
-i "trailer_iphone.m4v" \
-i "sintel_trailer-480p.mp4" \
-filter_complex "\
[1]format=yuva444p,geq=lum='p(X,Y)':a='st(1,pow(min(W/2,H/2),2))+st(3,pow(X-(W/2),2)+pow(Y-(H/2),2));if(lte(ld(3),ld(1)),255,0)'[circular shaped video];\
[circular shaped video]scale=w=-1:h=200[circular shaped video small];\
[0][circular shaped video small]overlay" \
-filter_complex_threads 1 \
-map 0:a \
-metadata:s:a:0 title="Sound main movie" \
-disposition:a:0 default \
-map 1:a \
-metadata:s:a:1 title="Sound overlayed movie" \
-disposition:a:1 none \
-c:v libx264 \
-preset ultrafast \
-shortest \
"result.mp4"
Run Code Online (Sandbox Code Playgroud)

解释:

第 5 行:为了创建圆形蒙版,我们使用“geq”过滤器。这用于从第二个视频输入创建带有 alpha 通道的圆形视频

第 6 行:将圆形视频的高度缩放至 200px,保留宽高比

第 7 行:叠加视频

第 8 行:Gyan在这里为 geq 过滤器提出了这个解决方案。

您可以跳过第 9 - 14 行。然后 ffmpeg 将默认使用主电影的音轨。

第 9 行:可选:第一个输入的音频将是输出中的第一个音轨

第 10 行:可选:为输出中的第一个音轨命名(在 VLC 中工作)

第 11 行:可选:确保输出中的第一个音频轨道将作为默认轨道播放

第 12 行:可选:第二个输入的音频将是输出中的第二个音轨

第 13 行:可选:为输出中的第二个音轨命名(在 VLC 中工作)

第 14 行:可选:确保输出中的第二个音轨不会播放,除非您使用播放器 (VLC) 选择它

第 17 行:输出的持续时间将与最短输入一样长