使用ffmpeg垂直或水平堆叠多个视频?

Jos*_*ian 17 ffmpeg video-processing

我有两个相同长度的视频,我想用ffmpeg将它们叠加到一个视频文件中.

我怎样才能做到这一点?

llo*_*gan 75

使用vstack(垂直),hstack(水平)或xstack(自定义布局)过滤器.它比其他方法更容易,更快捷.

示例1:合并/堆叠两个视频

垂直

使用vstack过滤器.

在此输入图像描述

ffmpeg -i input0 -i input1 -filter_complex vstack=inputs=2 output
Run Code Online (Sandbox Code Playgroud)

视频必须具有相同的宽度.

使用hstack过滤器.

在此输入图像描述

ffmpeg -i input0 -i input1 -filter_complex hstack=inputs=2 output
Run Code Online (Sandbox Code Playgroud)

视频必须具有相同的高度.

带边框

使用过滤器.此示例在双方之间创建5px黑色边框.

在此输入图像描述

ffmpeg -i input0 -i input1 -filter_complex "[0]pad=iw+5:color=black[left];[left][1]hstack=inputs=2" output
Run Code Online (Sandbox Code Playgroud)

示例2:与上面相同,但带有音频

来自两个输入的组合音频

添加amerge过滤器以组合来自两个输入的音频通道:

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output
Run Code Online (Sandbox Code Playgroud)
  • -ac 2如果两个输入都包含多声道音频,则包括降混到立体声.例如,如果两个输入都是立体声,如果省略,您将获得一个4声道输出音频流而不是立体声-ac 2.

使用来自一个特定输入的音频

此示例将使用以下音频input1:

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" -map 1:a output
Run Code Online (Sandbox Code Playgroud)

添加静音音频/如果一个输入没有音频

如果混合具有音频的输入和没有音频的输入,则amerge将失败,因为每个输入都需要音频.您可以使用anullsrc过滤器添加静音音频以防止这种情况:

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];anullsrc[silent];[0:a][silent]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output.mp4
Run Code Online (Sandbox Code Playgroud)

示例3:三个视频

在此输入图像描述

ffmpeg -i input0 -i input1 -i input2 -filter_complex "[0:v][1:v][2:v]vstack=inputs=3[v]" -map "[v]" output
Run Code Online (Sandbox Code Playgroud)

例4:2x2网格

在此输入图像描述

使用xstack

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v][2:v][3:v]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]" -map "[v]" output
Run Code Online (Sandbox Code Playgroud)

使用hstackvstack

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[v]" -map "[v]" output
Run Code Online (Sandbox Code Playgroud)

这种语法更容易理解,但效率低于使用xstack,如上所示.


示例5:带有文本的2x2网格

在此输入图像描述

使用drawtext过滤器:

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex
"[0]drawtext=text='vid0':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v0];
 [1]drawtext=text='vid1':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v1];
 [2]drawtext=text='vid2':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v2];
 [3]drawtext=text='vid3':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v3];
 [v0][v1][v2][v3]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]"
-map "[v]" output
Run Code Online (Sandbox Code Playgroud)

示例6:调整输入大小/缩放

由于两个视频都需要与vstack相同,并且hstack的高度相同,因此您可能需要缩放其他视频以匹配另一个视频:

简单缩放过滤器示例,将input0的宽度设置为640并自动设置高度,同时保留纵横比:

ffmpeg -i input0 -i input2 -filter_complex "[0:v]scale=640:-1[v0];[v0][1:v]vstack=inputs=2" output
Run Code Online (Sandbox Code Playgroud)

  • @RaduM因为你的一个视频中没有音频,你需要在其中添加音频或静音音频,使用带有音频的两个视频尝试相同的命令,它会起作用,因为我今天遇到同样的问题而发帖使用无声音频添加进行纠正. (2认同)

bla*_*lah 17

请参阅此问题的答案,以获得更好的方法.


旧版本:
您应该可以使用FFmpeg中的pad,movieoverlay过滤器来完成此操作.该命令看起来像这样:

ffmpeg -i top.mov -vf 'pad=iw:2*ih [top]; movie=bottom.mov [bottom]; \
  [top][bottom] overlay=0:main_h/2' stacked.mov
Run Code Online (Sandbox Code Playgroud)

首先,应该在顶部的电影被填充到其高度的两倍.然后加载底部电影.然后底部电影覆盖在填充的顶部电影上,偏移量为填充电影高度的一半.