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.

  • Input Seeking (Before -i): Fast, but often inaccurate for VFR because it jumps to the nearest keyframe based on estimated container timestamps.
  • Output Seeking (After -i): Slower, but highly accurate. It forces FFmpeg to decode the VFR stream from the beginning up to the specified timestamp, ensuring that every variable-duration frame is accounted for correctly.

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.