Manatee

Audio out of sync after a conversion, and the drift that causes it

The original file plays perfectly. You convert it, and the copy is out of sync. Sometimes from the first second, sometimes only towards the end. Nothing in the conversion settings mentions synchronisation, so there is nothing obvious to change.

The usual cause is that the source recorded video at a frame rate that varies, and the conversion assumed it did not.

Variable frame rate, and why phones use it

A camera can record at a constant frame rate, producing exactly 30 frames every second, or at a variable one, producing frames as circumstances allow. Phones and screen recorders overwhelmingly use variable frame rate, because it saves a great deal of space: a static scene needs far fewer frames than a moving one, and skipping the redundant ones costs nothing visually.

In a variable frame rate file, each frame carries a timestamp saying when it belongs. The audio has its own timeline. Played back correctly, the timestamps keep them together.

Convert that file while treating it as constant frame rate, and the timestamps are discarded in favour of an assumption. Every frame gets placed at a fixed interval. Wherever the source actually deviated from that interval, the picture and sound separate, and the error accumulates across the file.

That is why the problem often looks like drift even though nothing drifted during recording.

Confirm the source is variable frame rate

Two figures from ffprobe tell you. r_frame_rate is the nominal rate; avg_frame_rate is the average actually achieved:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=r_frame_rate,avg_frame_rate,nb_frames,duration \
  -of default=noprint_wrappers=1 source.mp4

If those two values differ meaningfully (say 30000/1001 against 27413/1000), the source is variable frame rate. If they match exactly, it is constant, and your sync problem has a different cause covered further down.

For a more direct look, count how far apart consecutive frames actually sit:

ffprobe -v error -select_streams v:0 -show_entries frame=pkt_pts_time \
  -of csv=p=0 source.mp4 | head -40

Evenly spaced numbers mean constant. Irregular gaps mean variable.

The conversion that preserves sync

The fix is to tell the converter to honour the source timestamps rather than assume a cadence.

ffmpeg -i source.mp4 -c:v libx264 -crf 20 -preset medium \
  -vsync vfr -c:a aac -b:a 192k output.mp4

-vsync vfr passes the variable timing through. The output remains variable frame rate, which every modern player handles.

If you need a genuinely constant frame rate output, because an editor or a broadcast target requires it, convert properly rather than by assumption. This duplicates or drops frames as needed to hit the target cadence while keeping audio aligned:

ffmpeg -i source.mp4 -filter:v fps=30 -c:v libx264 -crf 20 \
  -c:a aac -b:a 192k output-cfr.mp4

The fps filter resamples the timeline correctly. It is doing real work, so it is slower than a straight copy, and it is the right tool when constant output is a requirement rather than a preference.

When the audio itself was re-encoded badly

A second cause, less common but worth knowing. If the conversion resampled the audio (changing 48 kHz to 44.1 kHz, for instance) and did so without correcting the timeline, the audio’s duration changes while the video’s does not.

The ratio between those two rates is about 1.088, which is large. Over a 30-minute file it produces roughly 159 seconds of error, and the audio also sounds low-pitched. If your symptom is that dramatic, this is the cause rather than variable frame rate.

Keep the sample rate unless you have a reason to change it:

ffmpeg -i source.mp4 -c:v copy -c:a aac -ar 48000 -b:a 192k output.mp4

Setting -ar explicitly to the source’s rate stops a converter from picking a different default.

When only the container changed

If you are moving from MOV to MP4, or MKV to MP4, without changing the codecs, do not re-encode at all. Copy the streams:

ffmpeg -i source.mkv -c copy output.mp4

-c copy moves the existing video and audio into the new container untouched. It takes seconds rather than minutes, cannot introduce sync errors of this kind, and loses no quality because nothing is decoded. This works whenever the codecs inside are compatible with the destination container, which for H.264 and AAC in MP4 they almost always are. Converting MKV to MP4 without losing quality covers when this is possible and when it is not.

If the copy fails with a complaint about the codec, then a re-encode is genuinely required, and the -vsync vfr advice above applies.

Repairing sync in a file you already made

If the misaligned copy is what you have, measure the error and correct it rather than converting again from scratch.

For a constant offset, shift the audio. Positive values delay it:

ffmpeg -i out-of-sync.mp4 -itsoffset 0.4 -i out-of-sync.mp4 \
  -map 0:v -map 1:a -c copy corrected.mp4

For an error that grows across the file, you need a stretch rather than a shift, and the method for measuring and applying it is in a two-hour recording that drifts out of sync.

Where possible, go back to the source and convert it properly instead. Correcting a bad conversion means a second encode, and why compressing a video twice makes it look worse explains what that costs.

If the source will not convert cleanly at all

Sometimes the sync problem is a symptom of a damaged source rather than a conversion setting. A file with a broken index, missing timestamps or a truncated tail can produce output that is out of sync no matter how carefully the conversion is configured, because the information needed to place the frames is not there.

Manatee reads what structure survives in a damaged video and writes a clean copy, working from a duplicate so the original is never modified, which gives a conversion something coherent to work from. It converts too, keeping timestamps intact by default so this particular failure does not arise. What it will not do is invent timing information that was never recorded, and it says so rather than producing a file that plays wrong.

Questions

Why did my phone video convert fine last year and not now? Most likely the recording settings changed rather than the converter. Higher frame rate modes and newer codecs push phones further into variable frame rate territory.

Does -vsync vfr work for every file? It is the right default for phone and screen recordings. For a source that is genuinely constant frame rate it changes nothing, so it is safe to leave on.

The sync is fine in one player and wrong in another. Then the file is variable frame rate and one of the players is ignoring the timestamps. The file is not necessarily wrong. Converting to constant frame rate with the fps filter makes it behave consistently everywhere.

Can I check sync without watching the whole file? Compare the reported durations of the two streams. ffprobe -show_entries stream=codec_type,duration prints both. A difference of more than a few hundredths of a second is a strong hint before you watch anything.