6

I have one 2-hour video file and want to add a 10-second title sequence to its start. The long file has perfect a/v sync from start to finish. However, when I use ffmpeg -f concat -i mylist.txt -c copy outfile.mp4 to concatenate the title file to the long file, the audio in the long file gradually goes out of sync, progressively becoming worse until at the end of 2 hours, the audio is a full second or two behind the video. I can understand why the concat might break the synchronization, but I don't understand why it would cause the synchronization to become progressively worse.

I want to avoid re-encoding the long file to maintain quality. If necessary, I can re-encode the title file because it's just white text on a black background.

I'd greatly appreciate any suggestions. I'm a digital video semi-noob and have faced a steep learning curve, but I am learning. I'm using Ubuntu Linux 16.04 and ffmpeg 2.8.6-1ubuntu2, which I think is the latest ffmpeg version. I have about 20 old 2-hour family video cassettes that I am digitizing.

File background:

  1. The long file is an MP4 file using H264 and AAC. It originated as a .ts file and I use ffmpeg to encode it into the mp4 format. Before concatenating the title file, it is in perfect a/v sync at all times. It's 720x480, with 127 audio bitrate. I captured the video from a Sony Handycam Video8 tape using a Hauppauge Live-2 USB converter, using the VLC CLI to generate the original .ts file. It's about 120 minutes long.

  2. The title file I created in Blender, and tried to duplicate the long file's format: 720x480, 127 audio bitrate, MP4 containing H264 and AAC. It actually has no audio, as it's just two "slides" of text. (I know that there probably is actually an audio track generated by Blender, but it's just silence as I don't add any audio tracks to the simple titles.) It's only 10 seconds long.

The results of ffmpeg -i longfile.mp4 is:

Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
encoder         : Lavf56.36.100
Duration: 01:17:06.58, start: 0.013000, bitrate: 2134 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p,
720x480 [SAR 32:27 DAR 16:9], 1997 kb/s, 29.97 fps, 29.97 tbr, 29971
tbn, 59.94 tbc (default)
Metadata:
handler_name    : VideoHandler
Stream #0:1(unk): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, 
fltp, 127 kb/s (default)
Metadata:
handler_name    : SoundHandler

The results of ffmpeg -i titlefile.mp4 is

Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
encoder         : Lavf56.40.101
Duration: 00:00:10.01, start: 0.012000, bitrate: 421 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
720x480 [SAR 1:1 DAR 3:2], 284 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 
59.94 tbc (default)
Metadata:
handler_name    : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 
stereo, fltp, 127 kb/s (default)
Metadata:
handler_name    : SoundHandler

1 Answer 1

9

Run

ffmpeg -i titlefile.mp4 -vf setdar=16/9 -video_track_timescale 29971 -ac 1 newtitle.mp4

and then run concat with the new title video.

Modern containers like MP4 have Presentation TimeStamps, which are denominated with reference to a timebase. So, if the timebase value is 1/500 and a frame's PTS is 200, then that tells the video player to show that frame at 200*(1/500) = 0.4 seconds. The tbn values shown in the readouts are the reciprocals of this timebase. Now, the concat demuxer, due to a design oversight (or choice!?) does not rescale the PTS values so that all inputs have frames with PTS using the same timebase. Your two videos have different TBs, and so the long video after the concat is being sped up. The difference is perceptually invisible - except for the audio drift. That tbn value is for the video stream. Audio streams have their own timebase, related to the sample rate, which is the same here.

3
  • 2
    That works! Thank you so much! Also, thank you for the many comments on similar threads you have contributed. It's greatly appreciated.
    – trinkner
    Commented Aug 27, 2016 at 1:13
  • Nice, this helped alot with my similar problem. Could you elaborate on the audio timebase a bit? How do I check that they are on the same timebase? (I can't see a tbn value in the output). And do I correct it in the same way?
    – Sebastian
    Commented Oct 31, 2016 at 13:46
  • 1
    Audio timebases are usually the same as the sample rate. You can run ffprobe -select_streams a -show_entries stream=time_base -of compact=p=0 video.mp4 to get the value.For audio, I'd just recommend re-encoding with an explicit sample rate specified i.e. -ar 48000.
    – Gyan
    Commented Oct 31, 2016 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.