Andy
Andy

Reputation: 871

ffmpeg concat produces DTS out of order errors

I'm following the documentation on how to concatenate files with ffmpeg but during the process I'm seeing lots of warning and the output video stops after the first chunk but the audio keeps on playing.

This is the command I'm using to concatenate the files:

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

This are the warnings I'm seeing:

[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.

The video files are coming from an external source. My current solution is to re-encode every file separately to mp4 and then to concatenate them together and then to re-encode the complete file back to webm. That, of cause, that takes some significant time but I can't find another solution.

Upvotes: 34

Views: 36372

Answers (7)

HARSH CHOKSHI
HARSH CHOKSHI

Reputation: 16

listw.txt contains two files each having different frame per second.

Having different fps causing this error.

I solve my problem with below command:

ffmpeg -f concat -safe 0 -f concat -i listw.txt -vcodec libvpx-vp9 output.mp4

Upvotes: 0

BallpointBen
BallpointBen

Reputation: 13839

The way I solved this was to take the mp4s I wanted to concat and convert them to .ts first before performing the concat.

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"

Upvotes: 2

sr9yar
sr9yar

Reputation: 5320

All videos for FFMPEG concatenate should have matching encoding, fps and so on, otherwise you'll get unexpected results. I guess, it's hard to get by without re-encoding if your videos come from different sources. I had to look though lots of solutions, the working ones would suggest converting your videos to the same intermediate format and then running your concat command.

Although such approach does work, it doesn't explain what goes wrong. Gyan's comment answers it.

Firstly, test your input files with ffprobe: ffprobe video1.mp4

You'll get outputs like these.

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)

Even though my FPS and other params were the same, I got 58 sec video with 3.1 fps instead of the expected 8sec @24fps video. The important parameter here is timebase tbn , which is 12288 tbn vs 90k tbn. Concatenate doesn't re-encode the input videos, only the timebase from the first input video is used messing up all subsequent videos.

Change the timebase for the first file:

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

Now concatenate produces the correct result:

( 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

Upvotes: 43

Ed999
Ed999

Reputation: 3081

The following is a method for solving the "DTS out of order" error when concatenating a group of mp4 video files. It also avoids re-encoding them.

Although you will typically still see the "out of order" error message reported in the console window during processing, the concatenation will nevertheless succeed (and without loss of sync).

Run this code in a batch file. I wrote it on a machine running 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

Upvotes: 3

iamsk
iamsk

Reputation: 356

After a few days of investigation, I found make the videos have the same fps will solve this problem.

If a.mp4 and b.mp4 have different fps, Update them with 30(custom) 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

Write video paths into one file

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

Contact

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

Upvotes: 4

Andy
Andy

Reputation: 871

I fixed my issue my not using ffmpeg but mkvtoolnix using the mkvmerge command.

Upvotes: 3

aergistal
aergistal

Reputation: 31219

Your issues are caused by the -c copy copy argument. As the name of the argument implies, it will copy the source encoding. Since each file has different timestamps, potentially starting near zero, you will get a lot of warnings. The concat demuxer also requires the same codecs in the input files so make sure they're not mixed.

The solution is to re-encode by specifying the codecs you want to use for your output, eg. -c:v libvpx-vp9 -c:a libopus.

Upvotes: 9

Related Questions