ffmpeg concat导致DTS乱序错误

时间:2015-07-29 05:36:17

标签: video ffmpeg webm

我正在关注如何使用ffmpeg concatenate文件的文档,但在此过程中我看到很多警告,输出视频在第一个块之后停止,但音频继续播放。

这是我用来连接文件的命令:

ffmpeg -f concat -i mylist.txt -c copy output.webm

这是我看到的警告:

[concat @ 0x7fee11822a00] DTS 0 < 2500 out of order
[webm @ 0x7fee11011000] Non-monotonous DTS in output stream 0:0; previous: 2500, current: 0; changing to 2500. This may result in incorrect timestamps in the output file.

视频文件来自外部来源。我目前的解决方案是将每个文件重新编码为mp4,然后将它们连接在一起,然后将整个文件重新编码回webm。原因是,这需要一些重要的时间,但我找不到另一种解决方案。

6 个答案:

答案 0 :(得分:6)

您的问题是由-c copy复制参数引起的。正如参数的名称所暗示的那样,它将复制源编码。由于每个文件都有不同的时间戳,可能从零开始,因此会收到很多警告。 concat demuxer在输入文件中也需要相同的编解码器,因此请确保它们不会混合。

解决方案是通过指定要用于输出的编解码器来重新编码,例如。 -c:v libvpx-vp9 -c:a libopus

答案 1 :(得分:3)

经过几天的调查,我发现让视频具有相同的fps将解决这个问题。

如果a.mp4和b.mp4有不同的fps,请用30(自定义)fps更新它们

ffmpeg -i a.mp4 -vcodec mpeg4 -vf fps=30 a.output.mp4
ffmpeg -i b.mp4 -vcodec mpeg4 -vf fps=30 b.output.mp4

将视频路径写入一个文件

echo "file a.output.mp4" > videos.txt;
echo "file b.output.mp4" > videos.txt;

联系

ffmpeg -f concat -i videos.txt -c copy final.mp4

答案 2 :(得分:2)

我修复了我的问题,我没有使用ffmpeg,而是使用mkvmerge命令使用mkvtoolnix。

答案 3 :(得分:1)

以下是连接一组mp4视频文件时解决“DTS乱序”错误的方法。它还避免重新编码。

虽然在处理过程中您通常仍会看到控制台窗口中报告的“乱序”错误消息,但串联仍然会成功(并且不会丢失同步)。

在批处理文件中运行此代码。我是在运行Windows 7的机器上写的。

::  *** Concatenate .MP4 files : Stream Copy ***

    ::  You can't concatenate .mp4 files. You have to convert them to an
    ::  intermediate format that can be concatenated, such as .mpg:
    ::  
    ::    1. Convert the .mp4 videos to .mpg, using ffmpeg.
    ::    2. Then run a file level concatenation command on
    ::       the .mpg files, to create a combined .mpg file.
    ::    3. Convert the concatenated .mpg file to .mp4,
    ::       using ffmpeg.

    ::  If the mp4 files contain a h264 stream, use the .TS format (MPEG-TS)
    ::  as the intermediate format (instead of .MPG)

    ::  Convert the .MP4 files to intermediate .TS
    ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input1.ts
    ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input2.ts
    ffmpeg -i input3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input3.ts
    ffmpeg -i input4.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input4.ts
    ffmpeg -i input5.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input5.ts

    ::  MP4 Options
    SET options=-bsf:a aac_adtstoasc -movflags faststart

    ::  Concatenate the TS files & Convert the output back to MP4
    ffmpeg -i "concat:input1.ts|input2.ts|input3.ts|input4.ts|input5.ts" -c copy -video_track_timescale 25 %options% -f mp4 -threads 1 output.mp4



    ::  Report
    echo.  &  ffmpeg  -i input1.mp4 -f nul
    echo.  &  ffmpeg  -i input1.ts  -f nul
    echo.  &  ffmpeg  -i output.mp4 -f nul

答案 4 :(得分:0)

所有用于FFMPEG的视频都应具有匹配的编码,fps等,否则您将得到意想不到的结果。 我想,如果您的视频来自其他来源,那么不重新编码就很难解决。我必须查看许多解决方案,但可行的建议将建议将视频转换为相同的中间格式,然后运行concat命令。

尽管这种方法确实有效,但不能解释出什么问题了。 Gyan's comment answers it

首先,使用ffprobe测试您的输入文件: ffprobe video1.mp4

您将获得类似这样的输出。

video1.mp4:

Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 1556 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)

video2.mp4:

Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 6454 kb/s, 24 fps, 24 tbr, 90k tbn, 48 tbc (default)

即使我的FPS和其他参数相同,我也能以3.1 fps的速度拍摄58秒的视频,而不是预期的24秒的8秒的视频。此处的重要参数是时基 tbn ,即12288 tbn90k tbn。 并置不会重新编码输入视频,仅使用第一个输入视频的时基来弄乱所有后续视频。

更改第一个文件的时基:

ffmpeg -i video1.mp4 -video_track_timescale 90000 video1_fixed.mp4

现在串联产生正确的结果:

( echo file 'video2.mp4' & echo file 'video1_fixed.mp4' ) | ffmpeg -y -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -c copy output.mp4

答案 5 :(得分:0)

我解决这个问题的方法是在执行 concat 之前先获取我想要连接的 mp4 并将它们转换为 .ts

echo > concat.txt

for filename in file1 file2 file3; do
    ffmpeg -y -i "$filename.mp4" -c:a copy -c:v copy -bsf:v h264_mp4toannexb -f mpegts "$filename.ts"
    echo "$filename.ts" >> concat.txt
done

ffmpeg -y -f concat -i "concat.txt" -c copy "out.mp4"