ffmpeg concat produces DTS out of order errors

Andy picture Andy · Jul 29, 2015 · Viewed 18.4k times · Source

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.

Answer

sr9yar picture sr9yar · May 6, 2019

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