How to Seek Variable Frame Rate Video in FFmpeg

Seeking within variable frame rate (VFR) video files using FFmpeg can often result in inaccurate timestamps, audio-sync issues, or frozen frames because the time duration between frames is inconsistent. This article explains how to achieve precise seeking in VFR inputs by utilizing decoder-level seeking, forcing constant frame rates, and regenerating presentation timestamps.

Method 1: Use Output Seeking (Decoder Seeking)

The position of the seek parameter (-ss) in your FFmpeg command changes how FFmpeg processes the seek.

To seek accurately, place the -ss flag after your input file:

ffmpeg -i input_vfr.mp4 -ss 00:01:30 -c:v libx264 -c:a aac output.mp4

Method 2: Convert VFR to CFR During the Seek

If you need to perform fast input seeking (placing -ss before -i) but still want to avoid audio-video desync, you can force FFmpeg to convert the variable frame rate to a Constant Frame Rate (CFR) on the fly using the fps video filter.

Use -fflags +genpts to force FFmpeg to regenerate missing presentation timestamps, and apply the fps filter:

ffmpeg -fflags +genpts -ss 00:01:30 -i input_vfr.mp4 -vf fps=30 -c:v libx264 -c:a aac output.mp4

In this command: * -fflags +genpts regenerates the timestamps immediately after seeking. * -vf fps=30 resamples the video to a constant 30 frames per second, dropping or duplicating frames where necessary to maintain sync.

Method 3: Pre-Convert the VFR File to CFR

For complex editing, multiple seeks, or precise cuts, the safest workflow is to convert the entire VFR file into a CFR file before performing any seeking operations.

Run this command to convert the VFR file to a high-quality CFR file:

ffmpeg -i input_vfr.mp4 -vf fps=30 -c:v libx264 -crf 18 -c:a copy output_cfr.mp4

Once the conversion is complete, you can seek anywhere within output_cfr.mp4 instantly and accurately using standard FFmpeg seeking commands.