FFMPEG - 连接来自不同来源的 mp4 - 无法停止 "Non-monotonous DTS in output stream" 警告
FFMPEG - concatenating mp4s from different sources - unable to stop "Non-monotonous DTS in output stream" warning
我需要连接来自不同来源的 mp4 文件,这意味着一些变量超出了我的控制范围,例如时基、纵横比和编码。所以为了解决这个问题,我重新编码并尝试在连接文件之前标准化文件。不幸的是,尽管如此,我在串联阶段收到 Non-monotonous DTS in output stream
警告,并且输出视频似乎总是在最后一段同步中断 audio/video。
我知道还有很多关于解决上述警告的其他问题,但我已经完成所有这些问题并查看了文档..但不幸的是我仍然无法解决它..
我认为我不明白的是:如果我有来自不同来源的 mp4,我究竟需要做什么才能确保文件始终整齐地串联在一起?
到目前为止我尝试了什么
我用来在连接之前标准化 mp4 文件的脚本如下(修改分辨率、帧速率、时基、音频比特率、视频比特率、音频编码和视频编码):
ffmpeg -y -i -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2' -r 30 -video_track_timescale 90000 -b:a 128K -b:v 1200K -c:a aac -c:v libx264
这是其中两个文件的 ffprobe
输出,存在一些差异,但我不确定它们是否重要?
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'intro.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:08.98, start: 0.000000, bitrate: 1210 kb/s
Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1069 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 132 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'middle.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:59.72, start: 0.000000, bitrate: 1200 kb/s
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1063 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
此时他们都有正常的视频和音频。
之后,我连接它们并使用以下内容添加水印(很糟糕,我需要在这里重新编码):
ffmpeg -y \
-f concat \
-safe 0 \
-i $INFILES \
-c:v libx264 \
-c:a copy \
-preset fast \
-vf drawtext=enable="'between(t, $DRAW_TEXT_DELAY, $DRAW_TEXT_DURATION)': fontfile=$FONT_DIR/$FONT: text='$TEXT': fontcolor=$FONTCOLOR: fontsize=$FONTSIZE: $POSITION" \
$OUTFILE
INFILES
是格式如下的文本文件的路径:
file /usr/src/app/data/test/out/intro.mp4
file /usr/src/app/data/test/out/middle.mp4
file /usr/src/app/data/test/out/outro.mp4
我在这里错过了什么?有没有办法进一步调试?
您的音频流具有不同的采样率,也可能具有不同的通道数。此外,压缩的 MPEG 音频流将在连接时引入轻微的异步。
使用
ffmpeg -y -i -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p' -r 30 -c:v libx264 -b:v 1200K -ac 2 -ar 48000 -c:a pcm_s16le -video_track_timescale 90000
标准化,但保存到 MOV。
然后在连接期间,将 -c:a copy
更改为 -c:a aac
。
在 FFmpeg 中有三种连接文件的方法。
Demuxer(你正在使用这个)
此方法可用于连接具有相同参数的文件,如编解码器、大小、PAR 等
$ ffmpeg -concat -i files.txt [...] output.mp4
协议
与第一个相同,但最重要的是,此方法对于可以一起复制的文件很有用按位 - 它不涉及重新编码(一些格式支持这一点,如 MpegTS 或一些无损格式)。
$ ffmpeg -i "concat:FILE_0| ... |FILE_N" [...] output.mp4
过滤器
如果您有不同编解码器的视频,则必须使用此方法:
$ ffmpeg -i <FILE_0> ... -i <FILE_N> [...] -filter_complex "[0:0][0:1]...[<N>:0][<N>:1] concat=n=<N>:v=1:a=1[v_out][a_out]" -map [v_out] -map [a_out] output.mp4
concat
过滤器解码视频并使用相同的参数重新编码。它还负责处理音频流。如果分辨率不同,我不完全确定它会做什么,但这应该是一个好的开始。
我需要连接来自不同来源的 mp4 文件,这意味着一些变量超出了我的控制范围,例如时基、纵横比和编码。所以为了解决这个问题,我重新编码并尝试在连接文件之前标准化文件。不幸的是,尽管如此,我在串联阶段收到 Non-monotonous DTS in output stream
警告,并且输出视频似乎总是在最后一段同步中断 audio/video。
我知道还有很多关于解决上述警告的其他问题,但我已经完成所有这些问题并查看了文档..但不幸的是我仍然无法解决它..
我认为我不明白的是:如果我有来自不同来源的 mp4,我究竟需要做什么才能确保文件始终整齐地串联在一起?
到目前为止我尝试了什么
我用来在连接之前标准化 mp4 文件的脚本如下(修改分辨率、帧速率、时基、音频比特率、视频比特率、音频编码和视频编码):
ffmpeg -y -i -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2' -r 30 -video_track_timescale 90000 -b:a 128K -b:v 1200K -c:a aac -c:v libx264
这是其中两个文件的 ffprobe
输出,存在一些差异,但我不确定它们是否重要?
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'intro.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:08.98, start: 0.000000, bitrate: 1210 kb/s
Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1069 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 132 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'middle.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:59.72, start: 0.000000, bitrate: 1200 kb/s
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1063 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
此时他们都有正常的视频和音频。
之后,我连接它们并使用以下内容添加水印(很糟糕,我需要在这里重新编码):
ffmpeg -y \
-f concat \
-safe 0 \
-i $INFILES \
-c:v libx264 \
-c:a copy \
-preset fast \
-vf drawtext=enable="'between(t, $DRAW_TEXT_DELAY, $DRAW_TEXT_DURATION)': fontfile=$FONT_DIR/$FONT: text='$TEXT': fontcolor=$FONTCOLOR: fontsize=$FONTSIZE: $POSITION" \
$OUTFILE
INFILES
是格式如下的文本文件的路径:
file /usr/src/app/data/test/out/intro.mp4
file /usr/src/app/data/test/out/middle.mp4
file /usr/src/app/data/test/out/outro.mp4
我在这里错过了什么?有没有办法进一步调试?
您的音频流具有不同的采样率,也可能具有不同的通道数。此外,压缩的 MPEG 音频流将在连接时引入轻微的异步。
使用
ffmpeg -y -i -vf 'scale=1280:720:force_original_aspect_ratio=1,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p' -r 30 -c:v libx264 -b:v 1200K -ac 2 -ar 48000 -c:a pcm_s16le -video_track_timescale 90000
标准化,但保存到 MOV。
然后在连接期间,将 -c:a copy
更改为 -c:a aac
。
在 FFmpeg 中有三种连接文件的方法。
Demuxer(你正在使用这个)
此方法可用于连接具有相同参数的文件,如编解码器、大小、PAR 等
$ ffmpeg -concat -i files.txt [...] output.mp4
协议
与第一个相同,但最重要的是,此方法对于可以一起复制的文件很有用按位 - 它不涉及重新编码(一些格式支持这一点,如 MpegTS 或一些无损格式)。
$ ffmpeg -i "concat:FILE_0| ... |FILE_N" [...] output.mp4
过滤器
如果您有不同编解码器的视频,则必须使用此方法:
$ ffmpeg -i <FILE_0> ... -i <FILE_N> [...] -filter_complex "[0:0][0:1]...[<N>:0][<N>:1] concat=n=<N>:v=1:a=1[v_out][a_out]" -map [v_out] -map [a_out] output.mp4
concat
过滤器解码视频并使用相同的参数重新编码。它还负责处理音频流。如果分辨率不同,我不完全确定它会做什么,但这应该是一个好的开始。