What You’ll Learn

  • How to add a delay to audio with the adelay filter
  • How to shift video or audio forward/backward with -itsoffset
  • How to handle both “audio too early” and “audio too late” cases
  • How to estimate the delay with ffprobe

Tested with: FFmpeg 6.1 (verified on ubuntu-latest / CI)
Platform: Windows / macOS / Linux


Two Kinds of Audio Sync Problems

Lip-sync errors fall into two broad categories:

PatternSymptomTypical cause
Audio is behind the videoSound arrives after the mouth movesMicrophone latency, recording settings
Audio is ahead of the videoSound arrives before the mouth movesCapture-device latency mismatch

Method 1: adelay — Add Delay to the Audio

Use adelay when the audio is ahead of the video and you need to push it back in time.

Add 500 ms of delay to stereo audio

ffmpeg -i input.mp4 \
  -af "adelay=500|500" \
  -c:v copy \
  output.mp4

500|500 applies 500 ms of delay independently to the left and right channels of a stereo track.

Mono audio

ffmpeg -i input.mp3 \
  -af "adelay=300" \
  output.mp3

adelay Parameter Details

adelay=delays[|delays...]
  • Delays are specified per channel, separated by pipes (|)
  • The unit is milliseconds (ms)
  • 0 means no delay
# Stereo: different delay per channel
ffmpeg -i input.mp4 -af "adelay=200|400" -c:v copy output.mp4

# 5.1 surround (6 channels)
ffmpeg -i input.mp4 -af "adelay=300|300|300|300|300|300" -c:v copy output.mp4

Method 2: -itsoffset — Shift Input Timestamps

-itsoffset shifts the timestamps of an input file. By loading the same file twice and applying the offset to only one of them, you can shift video or audio independently.

Delay audio by 0.5 s (audio is ahead of the video)

ffmpeg -i input.mp4 -itsoffset 0.5 -i input.mp4 \
  -map 0:v -map 1:a \
  -c:v copy -c:a copy \
  output.mp4
  1. 0:v — video from the first input (original timestamps)
  2. 1:a — audio from the second input (offset by 0.5 s)

Advance audio by 0.5 s (audio is behind the video)

ffmpeg -itsoffset 0.5 -i input.mp4 -i input.mp4 \
  -map 0:v -map 1:a \
  -c:v copy -c:a copy \
  output.mp4

This time itsoffset is applied to the video (0:v). Delaying the start of the video by 0.5 s is equivalent to moving the audio 0.5 s earlier in relative terms.


Method 3: Trim the Start of the Audio with atrim

If the audio lags the video, another option is to trim the leading part of the audio to line it up.

ffmpeg -i input.mp4 \
  -vf "setpts=PTS-STARTPTS" \
  -af "atrim=start=0.3,asetpts=PTS-STARTPTS" \
  -c:v libx264 \
  output.mp4

atrim=start=0.3 drops the first 0.3 seconds of audio, which effectively advances everything that follows.


Check Audio Delay with ffprobe

ffprobe -v quiet -print_format json -show_streams input.mp4 2>&1 | grep "start_time"

The difference between the start_time values of the video and audio streams gives you a rough estimate of the delay.


Align the start_time of Video and Audio

Some files have mismatched start_time values for video and audio. You can normalize them with:

ffmpeg -i input.mp4 -c:v copy -c:a copy -avoid_negative_ts make_zero output.mp4

-avoid_negative_ts make_zero forces both streams to share a zero-based timeline.


Practical Workflow

Step 1: Confirm the drift

Play the file in a media player (e.g. VLC) and estimate the offset in seconds.

Step 2: Decide the direction

  • Mouth moves first, sound arrives late → audio is behind → delay the video with -itsoffset (not adelay, since it can only add delay to audio)
  • Sound arrives first, mouth moves later → audio is ahead → delay the audio with adelay

Step 3: Run the command

# Example: audio is 300 ms ahead (delay the audio with adelay)
ffmpeg -i input.mp4 -af "adelay=300|300" -c:v copy output.mp4

Anti-Pattern

Bad: passing a single channel value to adelay on a stereo file
ffmpeg -i input.mp4 -af "adelay=500" -c:v copy output.mp4

When you feed a single value (adelay=500) to a stereo file, the delay is applied only to the left channel while the right channel stays in place. Always match the number of values to the channel count.


Notes

  • adelay only adds delay to audio — it cannot subtract (advance) it.
  • To move audio earlier, use -itsoffset or atrim.
  • Using -c:a copy avoids audio re-encoding (no quality loss), but adelay requires re-encoding because it rewrites the samples.

  • asetpts — manipulate audio timestamps
  • setpts — manipulate video timestamps
  • atrim — trim audio

Frequently Asked Questions

Why does audio drift later in long videos?

Variable framerate (VFR) source plus stream copy is the typical cause — audio runs at a constant clock while video frames arrive irregularly. Convert to CFR or re-encode to keep them in sync.

What does -itsoffset do?

It shifts the input timestamps of a stream relative to the others. -itsoffset 0.5 -i audio.aac delays the audio by 500 ms before muxing. Use a negative value to advance it.

How can I detect the offset automatically?

Use ffmpeg -i video.mp4 -i audio.wav -filter_complex "[0:a][1:a]axcorrelate" -f null - and parse the lag with the highest correlation peak.

Does this fix Bluetooth-induced lag?

No — Bluetooth latency is added at playback time and is device-specific. Hardware lip-sync or post-process re-mux is the only fix once the file is exported.

Will trimming change the offset I should use?

Yes — once you start with -ss, the offset is measured from the new zero. Apply trim and offset together carefully, ideally re-encoding to avoid keyframe drift.