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

时间:2012-07-19 00:59:42

标签: ffmpeg video-processing

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

我该怎么做?

3 个答案:

答案 0 :(得分:51)

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

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

垂直

使用vstack过滤器。

enter image description here

ffmpeg -i input0 -i input1 -filter_complex vstack=inputs=2 output

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

水平

使用hstack过滤器。

enter image description here

ffmpeg -i input0 -i input1 -filter_complex hstack=inputs=2 output

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

带边框

使用pad过滤器。这个例子在双方之间创建了一个5px的黑色边框。

enter image description here

ffmpeg -i input0 -i input1 -filter_complex "[0]pad=iw+5:color=black[left];[left][1]hstack=inputs=2" output

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

来自两个输入的组合音频

添加amerge filter以合并两个输入的音频通道:

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
    如果两个输入都包含多声道音频,则包含
  • -ac 2以缩混为立体声。例如,如果两个输入都是立体声,如果省略-ac 2,则会得到一个4声道输出音频流而不是立体声。

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

此示例将使用input1

中的音频
ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" -map 1:a output

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

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

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

示例3:三个视频

enter image description here

ffmpeg -i input0 -i input1 -i input2 -filter_complex "[0:v][1:v][2:v]vstack=inputs=3[v]" -map "[v]" output

示例4:2x2网格

enter image description here

使用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

使用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

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

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

enter image description here

使用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

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

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

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

ffmpeg -i input0 -i input2 -filter_complex "[0:v]scale=640:-1[v0];[v0][1:v]vstack=inputs=2" output

答案 1 :(得分:15)

有关更简单的方法,请参阅this answer此问题。


旧版本:
您应该可以使用FFmpeg中的padmovieoverlay过滤器执行此操作。命令看起来像这样:

ffmpeg -i top.mov -vf 'pad=iw:2*ih [top]; movie=bottom.mov [bottom]; \
  [top][bottom] overlay=0:main_h/2' stacked.mov

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

答案 2 :(得分:1)

对于2个视频:

ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex hstack out.mp4

更多视频(在此示例中为3个):

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex hstack=3 out.mp4