Lips and voice do not match, or the sound is 1.5 seconds behind the picture after a conversion. FFmpeg can fix audio that went out of sync during recording, streaming or converting. Find out which way the audio is off, then pick the matching option. In many cases you do not need to re-encode.

Identify the Direction of the Offset

Condition Meaning Fix
Audio is later than video Sound arrives after the action (clap → sound) Shift audio earlier, or delay video
Audio is earlier than video Sound arrives before the action (sound → clap) Shift audio later

Check the Start Times with ffprobe

# Check start_time of video and audio streams
ffprobe -v error -show_entries stream=codec_type,start_time \
  -of default=noprint_wrappers=1 input.mp4

Example output:

codec_type=video
start_time=0.000000
codec_type=audio
start_time=1.536000

start_time shows when each stream starts in the file. Here the audio starts 1.536 seconds after the video. That is not always an offset: if the offset is in the recording itself, the start_time values are the same, so check by playing the file.

Command Examples

1. -itsoffset to Delay Video (audio is late, no re-encoding)

Open the same file twice. Take the video from the second input, which gets the offset, and the audio from the first. The video is delayed to line up with the late audio.

# Fix: audio is 1.5 seconds behind video
ffmpeg -i input.mp4 -itsoffset 1.5 -i input.mp4 \
  -map 1:v -map 0:a -c copy output.mp4
  • -itsoffset 1.5: delays the timestamps of the next -i (the second input) by 1.5s
  • -map 1:v: video from the second input (delayed by 1.5s)
  • -map 0:a: audio from the first input (unchanged)
  • -c copy: no re-encoding (fast, no quality loss)

2. -itsoffset to Delay Audio (audio is early)

# Fix: audio is 1.0 second ahead of video
ffmpeg -i input.mp4 -itsoffset 1.0 -i input.mp4 \
  -map 0:v -map 1:a -c copy output.mp4
  • -itsoffset is on the second input and the audio comes from that input, so the audio plays 1.0s later

3. adelay Filter — Delay Audio by Milliseconds

# Delay audio by 1500ms (1.5 seconds) — stereo
ffmpeg -i input.mp4 -af "adelay=1500|1500" -c:v copy output.mp4
  • adelay=1500|1500: delay the left channel by 1500ms and the right channel by 1500ms
  • Separate the delay for each channel with | (stereo needs two values)
  • This filter can only delay audio. It cannot move audio earlier

4. -async to Fill Gaps in the Audio Timestamps

# Fill gaps in the audio timestamps with silence
ffmpeg -i input.mp4 -async 1 -c:v copy output.mp4
  • -async 1: fills gaps in the audio’s own timestamps with silence and cuts overlaps. It does not compare the audio with the video, and it does not change the pitch
  • Gaps shorter than 0.1 seconds are left as they are
  • It only works when FFmpeg converts the audio on the way, for example from PCM to AAC. With AAC in and AAC out it changes nothing (see Problem 5)

5. Fix Sync While Re-Encoding

# Fix 1.5s late audio + re-encode to H.264
ffmpeg -i input.mp4 -itsoffset 1.5 -i input.mp4 \
  -map 1:v -map 0:a \
  -c:v libx264 -crf 23 -c:a aac output.mp4

Correction Method Comparison

Method Re-encoding Handles Precision
-itsoffset + -c copy None Both directions High (timestamp-level)
adelay filter Audio only Audio early only High (millisecond)
-async 1 Audio only Gaps in the audio timestamps Coarse (gaps over 0.1 s)
aresample filter Audio only Gaps in the audio timestamps (async above 1 also stretches or squeezes) Sample-level

Which one to use:

  • No re-encoding wanted → -itsoffset + -c copy
  • Known fixed offset → -itsoffset or adelay
  • Gaps in the audio timestamps → -af aresample=async=1

Option Reference

Option / Filter Meaning Recommended Value
-itsoffset N Delay the timestamps of the next -i by N seconds The offset in seconds
-map 0:a Select audio stream from input 0 Used with itsoffset
-map 1:v Select video stream from input 1 Used with itsoffset
-af adelay=N|N Delay audio channels by N milliseconds Drift × 1000 (ms)
-async N Fill and trim audio to match its own timestamps (only when the audio is converted) 1
-c copy Copy without re-encoding When using itsoffset

Troubleshooting

Problem 1: adelay With -c copy Stops With an Error

Cause: adelay is a filter, so the audio must be re-encoded. With -c copy, FFmpeg stops with Filtering and streamcopy cannot be used together.
Fix: Copy the video and re-encode the audio:

ffmpeg -i input.mp4 -af "adelay=1500|1500" -c:v copy -c:a aac output.mp4

Problem 2: -itsoffset Applied But Sync Is Still Off

Cause: -itsoffset is not directly before the -i it should affect, or -map picks the wrong input
Fix: Check the order of the options:

# Correct order (audio is late)
ffmpeg -i input.mp4 -itsoffset 1.5 -i input.mp4 \
  -map 1:v -map 0:a -c copy output.mp4
# -itsoffset only affects the -i right after it (the second input, used for 1:v)

Problem 3: Sync Drift Remains After Fix

Cause: The offset you measured was wrong
Fix: Check the start times with ffprobe, then confirm the offset by playing the file at a moment you can both see and hear. An offset in the recording itself does not show up in start_time:

ffprobe -v error -show_entries stream=codec_type,start_time \
  -of default=noprint_wrappers=1 input.mp4

Problem 4: Audio Cuts Out or Has Silence Gaps After Fix

Cause: Any shift leaves a gap as long as the offset: silence, or no picture, at the start or end of the shifted stream
Fix: For large offsets, check how the source was recorded. To remove the gap at the start, cut it from the fixed file:

# Cut the first 1.5 seconds of the fixed file
ffmpeg -ss 1.5 -i output.mp4 -c:v libx264 -c:a aac trimmed.mp4

Problem 5: -async Changes Nothing

Cause: -async only goes to the resampler that FFmpeg adds when it has to convert the audio. With AAC in and AAC out, none is added, so the audio is only re-encoded
Fix: Use the aresample filter, which always runs:

ffmpeg -i input.mp4 -af aresample=async=1:min_hard_comp=0.1 -c:v copy output.mp4

FAQ

Q1. How do I measure the offset if I don’t know it?
A. Play the video, find a moment you can both see and hear (a clap or a hit) and estimate the offset. start_time from ffprobe only shows when each stream starts in the file; an offset in the recording itself does not show up there.

Q2. What units does -itsoffset use?
A. Seconds: 1.5 means 1.5 seconds. adelay uses milliseconds (1500 = 1.5 seconds), so do not mix them up.

Q3. Can I fix sync without re-encoding anything?
A. Yes, with -itsoffset and -c copy. Only the timestamps change. Nothing is decoded or encoded, so the quality stays the same.

Q4. What if the drift is less than 0.5 seconds?
A. Shift the audio by the measured amount with -itsoffset or adelay, as for a larger offset. -async 1 and aresample=async=1 only fill gaps in the audio’s own timestamps; they do not move the audio to match the video.

Q5. How do I use adelay with mono audio?

# Mono audio — specify a single value (no | separator needed)
ffmpeg -i input.mp4 -af "adelay=1500" -c:v copy output.mp4