如何连接具有不同属性的ffmpeg中的视频?

Posted

技术标签:

【中文标题】如何连接具有不同属性的ffmpeg中的视频?【英文标题】:How to concatenate videos in ffmpeg with different attributes? 【发布时间】:2019-12-13 11:08:37 【问题描述】:

我正在尝试合并一些视频,但出现时间戳错误。

我尝试使它们都具有相同的尺寸、帧速率、采样率,并且还通过在没有音轨时添加音轨。

ffmpeg -i input1.mp4 -y -i audio1.mp3 -c:v copy -c:a aac -shortest output1.mp4
ffmpeg -i input2.mp4 -y -i audio2.mp3 -c:v copy -c:a aac -shortest output2.mp4
ffmpeg -y -safe 0 -f concat -i list.txt -c copy output.mp4

错误信息:

Non-monotonous DTS in output stream 0:0; previous: 8052684, current: 4127401; changing to 8052685. This may result in incorrect timestamps in the output file.

【问题讨论】:

请不要使用指向外部网站的链接。将所有相关信息放在问题本身中! 【参考方案1】:

由于我假设您的输入将是任意的,因此我建议使用 concat filter 而不是 concat demuxer,因为无论如何您都需要执行过滤以使所有内容符合一组通用参数,并且您可以在一个命令中完成所有操作。

将所有视频设为 1280x720、1:1 SAR、30 fps、yuv420p

使用scale(宽度 x 高度/分辨率)、setsar(纵横比)、fps(帧速率)、format(色度子采样)和concat(连接/连接)过滤器。

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

与上述相同,但也将音频处理为具有 48000 采样率的立体声

添加了aformat(采样率和通道布局)过滤器。

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];
 [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1];
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];
 [v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

带水印

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i logo.png -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];
 [1:a]aformat=sample_rates=48000:channel_layouts=stereo[a1];
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];
 [v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[vid][a];[vid][3]overlay=W-w-5:H-h-5[v]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

有关更多信息,请参阅overlay filter documentation 和 How to add and position watermark with ffmpeg?

为没有音频的输入添加静音虚拟音频

anullsrc 过滤器用于在您的输入之一不包含音频时提供静音虚拟音频。这可能是必需的,因为要连接的所有段必须具有相同数量和类型的流。换句话说,您不能将没有音频的视频连接到有音频的视频。所以可以像这个例子一样添加无声音频:

ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -t 0.1 -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v0];
 [1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1,fps=30,format=yuv420p[v1];
 [2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720::-1:-1,setsar=1,fps=30,format=yuv420p[v2];
 [0:a]aformat=sample_rates=48000:channel_layouts=stereo[a0];
 [2:a]aformat=sample_rates=48000:channel_layouts=stereo[a2];
 [v0][a0][v1][3:a][v2][a2]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac -movflags +faststart output.mp4

注意: 保持-t 0.1 不变:anullsrc 的持续时间只需短于相关视频输入的持续时间。 concat 过滤器将自动扩展无声音频以匹配相关视频输入的长度。

【讨论】:

嗨@llogan,如果我需要在上面添加第四个视频,会发生什么变化:[v0][a0][v1][a1][v2][a2]concat=n=3 :v=1:a=1[v][a]" ?非常感谢! @Philban [v0][a0][v1][a1][v2][a2][v3][a3]concat=n=4:v=1:a=1[v][a] 感谢您的帮助!我现在收到关于不匹配流的错误。我将打开一个单独的问题,以便我可以粘贴命令和错误日志。 这真的很有帮助!但是,当我尝试添加静音虚拟音频时,出现以下错误:[pad @ 0x7f861d50f200] Cannot find color '-1' [pad @ 0x7f861d50f200] Unable to parse option value "-1" as color [pad @ 0x7f861d50f200] Cannot find color '-1' [pad @ 0x7f861d50f200] Unable to parse option value "-1" as color [pad @ 0x7f861d50f200] Error setting option color to value -1. [Parsed_pad_11 @ 0x7f861d50f140] Error applying options to the filter. [AVFilterGraph @ 0x7f861d517500] Error initializing filter 'pad' with args '1280:720::-1:-1' 任何想法@llogan? @llogan 对不起,原来这是不相关的错误。现在可以正常使用了!

以上是关于如何连接具有不同属性的ffmpeg中的视频?的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg命令将不同类型和分辨率的视频连接成1个视频,可以在android中播放[重复]

FFMPEG为视频添加圆形蒙版,转换为黑白并连接

ffmpeg:连接图像和视频

用ffmpeg c连接视频和音频时如何计算pts和dts

如何使用FFmpeg连接两个MP4文件? concat视频过滤器concat demuxer concat协议

如何随机抽取每段视频画面中的一帧保存为图片格式?