How to Use FFmpeg itsoffset to Sync Audio and Video

This guide explains how to fix audio and video desynchronization by muxing streams using the -itsoffset option in FFmpeg. You will learn the mechanics of timestamp offsets, how to delay either stream to achieve perfect synchronization, and how to approach dynamic or segment-based timing adjustments.

How -itsoffset Works

The -itsoffset flag alters the presentation timestamps (PTS) of the input file that immediately follows it in the command. It accepts an offset specified in seconds (e.g., 2.5) or in HH:MM:SS.mmm format.

Because it operates on inputs, its placement on the command line is critical:

  • Any -itsoffset flag applies only to the input (-i) declared right after it.
  • A positive offset delays the timestamps of that stream, making it play later relative to the other streams.

Delaying Audio to Match Video

If your audio plays ahead of your video, you need to delay the audio stream. Specify the video file first without an offset, add the offset, and then specify the audio file:

ffmpeg -i video.mp4 -itsoffset 1.5 -i audio.aac -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 output.mp4

In this command:

  • -i video.mp4: Ingests the video stream at baseline time (0.0).
  • -itsoffset 1.5 -i audio.aac: Delays the audio timestamps by 1.5 seconds.
  • -c:v copy -c:a copy: Stream-copies both tracks without re-encoding to preserve original quality and speed up the process.
  • -map 0:v:0 -map 1:a:0: Explicitly maps the first video stream from the first input and the first audio stream from the second input.

Delaying Video to Match Audio

If your video plays ahead of your audio, delay the video stream instead by applying the offset directly before the video input:

ffmpeg -itsoffset 0.85 -i video.mp4 -i audio.aac -c copy -map 0:v:0 -map 1:a:0 output.mp4

This delays the video track by 850 milliseconds relative to the unshifted audio input.

Working with Single Files (Separate Streams from One Source)

If your desynchronized audio and video are already packaged inside the same container (such as a single MP4 file), read the same file twice to apply the offset to only one stream:

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

This takes the video from the first instance (offset 0.0) and the audio from the second instance (delayed by 0.5 seconds).

Handling Dynamic or Variable Offsets

The -itsoffset option applies a static, uniform offset across the entire target input stream. If synchronization drifts dynamically over time (for example, drift caused by mismatched sample rates or dropped frames), resolve it using one of two methods:

Method 1: Split and Stitch

For streams where the required offset changes at specific points:

  1. Segment the inputs at the drift boundaries using -ss and -to.
  2. Apply specific -itsoffset values to each individual segment.
  3. Concatenate the corrected segments using FFmpeg's concat demuxer.

Method 2: Use Audio Filters for Continuous Drift

If the drift is progressive rather than a fixed delay, use filter graphs instead of -itsoffset. The aresample filter can dynamically stretch or compress audio timestamps to match the video clock:

ffmpeg -i input.mp4 -filter_complex "[0:a]aresample=async=1000[aout]" -map 0:v -map "[aout]" -c:v copy -c:a aac output.mp4

For discrete inline audio delays where you must re-encode, the adelay filter allows targeted delays per channel:

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

This introduces a 1500-millisecond delay to both the left and right audio channels directly within the processing pipeline.