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.