使用ffmpeg垂直或水平堆叠(马赛克)几个视频? [关闭]
Posted
技术标签:
【中文标题】使用ffmpeg垂直或水平堆叠(马赛克)几个视频? [关闭]【英文标题】:Vertically or horizontally stack (mosaic) several videos using ffmpeg? [closed] 【发布时间】:2012-07-18 03:34:49 【问题描述】:我有两个完全相同长度的视频,我想使用 ffmpeg 将它们堆叠成一个视频文件。
我该怎么做?
【问题讨论】:
【参考方案1】:使用vstack(垂直)、hstack(水平)或xstack(自定义布局)过滤器。它比其他方法更容易、更快捷。
合并/堆叠两个视频或图像
垂直
使用vstack 过滤器。
ffmpeg -i input0 -i input1 -filter_complex vstack=inputs=2 output
视频必须具有相同的宽度。
水平
使用hstack 过滤器。
ffmpeg -i input0 -i input1 -filter_complex hstack=inputs=2 output
视频的高度必须相同。
带边框
使用pad 过滤器。此示例在两侧之间创建一个 5px 的黑色边框。
ffmpeg -i input0 -i input1 -filter_complex "[0]pad=iw+5:color=black[left];[left][1]hstack=inputs=2" output
带音频
缩混并使用原始频道位置
添加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 声道输出音频流而不是立体声。
将每个输入的所有音频放入单独的通道中
使用amerge(或amix)和pan过滤器:
ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3[a]" -map "[v]" -map "[a]" output
这假设每个输入都包含一个立体声音频流。
使用来自一个特定输入的音频
本例将使用来自input1
的音频:
ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" -map 1:a output
添加静音音频/如果一个输入没有音频
如果您混合有音频的输入和没有音频的输入,则合并将失败,因为每个输入都需要音频。您可以使用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 个视频或图片
ffmpeg -i input0 -i input1 -i input2 -filter_complex "[0:v][1:v][2:v]hstack=inputs=3[v]" -map "[v]" output
如果你想垂直使用 vstack 而不是 hstack。
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
使用hstack 和vstack
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 效率低。
带有文本的 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
4x4
使用xstack filter。总共 16 个视频的示例:
ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v][1:v][2:v][3:v][4:v][5:v][6:v][7:v][8:v][9:v][10:v][11:v][12:v][13:v][14:v][15:v]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4
如果您需要先缩放输入:
ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v]scale=iw/4:-1[v0];[1:v]scale=iw/4:-1[v1];[2:v]scale=iw/4:-1[v2];[3:v]scale=iw/4:-1[v3];[4:v]scale=iw/4:-1[v4];[5:v]scale=iw/4:-1[v5];[6:v]scale=iw/4:-1[v6];[7:v]scale=iw/4:-1[v7];[8:v]scale=iw/4:-1[v8];[9:v]scale=iw/4:-1[v9];[10:v]scale=iw/4:-1[v10];[11:v]scale=iw/4:-1[v11];[12:v]scale=iw/4:-1[v12];[13:v]scale=iw/4:-1[v13];[14:v]scale=iw/4:-1[v14];[15:v]scale=iw/4:-1[v15];[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14][v15]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4
调整/缩放输入
由于两个视频需要与 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
有关在保持纵横比的同时将任何尺寸的视频调整为特定尺寸的更高级方法,请参阅Resizing videos with ffmpeg to fit into static sized player。
您还可以使用scale2ref 过滤器自动调整一个视频的大小以匹配另一个视频的尺寸。
延迟/暂停视频
此示例将播放左上角的视频,同时暂停其他视频。一旦左上角的视频结束,右上角的视频就会播放,依此类推。
使用tpad、adelay、xstack 和amix 过滤器:
ffmpeg -i top-left.mp4 -i top-right.mp4 -i bottom-left.mp4 -i bottom-right.mp4 -filter_complex "[1]tpad=start_mode=clone:start_duration=5[tr];[2]tpad=start_mode=clone:start_duration=10[bl];[3]tpad=start_mode=clone:start_duration=15[br];[0][tr][bl][br]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v];[1:a]adelay=5s:all=true[a1];[2:a]adelay=10s:all=true[a2];[3:a]adelay=15s:all=true[a3];[0:a][a1][a2][a3]amix=inputs=4[a]" -map "[v]" -map "[a]" output.mp4
此示例假定每个输入的持续时间为 5 秒。根据需要调整 start_duration
和 adelay
值。
此命令需要 FFmpeg 4.3 或更高版本。
如果您不喜欢 xstack 的复杂性,您可以使用多个 hstack/vstack 来代替,如示例 4:2x2 网格所示。
【讨论】:
ffmpeg
报告No such filter: 'vstack'
。我必须先安装它吗?
@frans 你现在可能想通了,但是你的ffmpeg
太旧了。建议用户使用从当前 git master 分支派生的ffmpeg
构建。
Stream specifier ':a' in filtergraph description [0:v][1:v]vstack[v];[0:a][1:a]amerge=inputs=2[a] matches no streams.
为什么会得到这个?
@RaduM 这是因为您的一个视频中没有音频,您需要在其中添加音频或静音音频,使用两个带音频的视频尝试相同的命令,它会起作用,我正在发布因为我今天遇到了同样的问题,并使用静音音频添加解决了它。
ffmpeg -i front.avi -i front.avi -i front.avi -i front.avi -i front.avi -i front.avi -filter_complex "[0:v][1: v][2:v]hstack=3[top];[3:v][4:v][5:v]hstack=3[bottom];[top][bottom]vstack[v]"-map" [v]" output.avi ......但我无法打开 avi 文件【参考方案2】:
对于 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
【讨论】:
【参考方案3】:请参阅此问题的this answer,了解更新、更简单的方法。
旧版本: 您应该可以使用 FFmpeg 中的 pad、movie 和 overlay 过滤器来执行此操作。该命令将如下所示:
ffmpeg -i top.mov -vf 'pad=iw:2*ih [top]; movie=bottom.mov [bottom]; \
[top][bottom] overlay=0:main_h/2' stacked.mov
首先,应该在顶部的电影被填充到其高度的两倍。然后加载底部电影。然后底部影片以填充影片高度一半的偏移量覆盖在填充顶部影片上。
【讨论】:
以上是关于使用ffmpeg垂直或水平堆叠(马赛克)几个视频? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章