A shell function to fix video and audio sync lag

Every now and then a screen recording comes out with the audio slightly off from the video. The fix is to offset the audio track by a fraction of a second, and ffmpeg can do that in one line. I never remember the exact flags, so I keep it as a function in my dotfiles.

# Fix video/audio sync lag by offsetting the audio track
# Arguments:
#   $1 - delay in seconds (e.g., -0.2 for 200ms earlier, 0.2 for 200ms later)
#   $2 - input file (e.g., input.mp4)
# Output: Creates a new file with "_output" suffix (e.g., input_output.mp4)
# Example: fixlag -0.2 input.mp4
function fixlag() {
  local delay="$1"
  local input_file="$2"

  local base="${input_file%.*}"
  local ext="${input_file##*.}"
  local output_file="${base}_output.${ext}"

  clear

  echo "Creating: $output_file"
  ffmpeg -itsoffset "$delay" -i "$input_file" -i "$input_file" -map 1:v -map 0:a -c copy "$output_file"

  if [ $? -eq 0 ]; then
    echo "✓ Successfully created $output_file"
  fi
}

The trick is -itsoffset, which shifts the timestamps of the next input. I load the file twice: once with the offset to grab the video, and once without it to grab the audio. Then -map 1:v -map 0:a picks the video from the second input and the audio from the first, so only the audio gets nudged.

A negative delay pulls the audio earlier, a positive one pushes it later. So if the sound lands a touch after the picture, I run:

fixlag -0.2 recording.mp4

That writes recording_output.mp4 with the audio shifted 200ms earlier. Because of -c copy nothing gets re-encoded, so it finishes almost instantly and the quality stays exactly the same. I usually try a couple of values until it looks right.

Did you enjoy this post?