Extract Keyframes with FFmpeg Select Filter

Extracting only the keyframes (I-frames) from a video is a highly efficient way to generate thumbnails, summarize video content, or analyze scene changes. This article provides a straightforward guide on how to use the FFmpeg select filter to isolate and export only the keyframes of a video, along with the command-line options needed to customize your output.

The Basic Command

To extract only keyframes using the select filter, use the following FFmpeg command:

ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -vsync vfr output_%03d.png

Command Breakdown

  • -i input.mp4: Specifies the path to your input video file.
  • -vf "select='eq(pict_type,I)'": Applies the video filter (-vf). The select filter evaluates each frame. The expression eq(pict_type,I) checks if the picture type is an I-frame (keyframe) and selects it if true.
  • -vsync vfr: Stands for Variable Frame Rate. This parameter (which can also be written as -fps_mode vfr in newer FFmpeg versions) is crucial because it tells FFmpeg to drop the unselected frames instead of duplicating the selected keyframes to match the original video's frame rate.
  • output_%03d.png: The naming pattern for the exported images. %03d acts as a sequential placeholder formatted to three digits (e.g., output_001.png, output_002.png).

Alternative Shorthand Command

FFmpeg also provides a simpler shorthand expression specifically for selecting keyframes:

ffmpeg -i input.mp4 -vf "select=key" -vsync vfr output_%03d.png

Both the eq(pict_type,I) expression and the key constant achieve the exact same result.

Speed Optimization: Skipping Non-Keyframes

By default, the commands above decode the entire video stream to evaluate each frame, which can be slow for large files. To drastically speed up the extraction process, you can instruct the decoder to discard non-keyframes before the video is even filtered:

ffmpeg -skip_frame nokey -i input.mp4 -vf "select=key" -vsync vfr output_%03d.png

The -skip_frame nokey option tells FFmpeg to skip decoding any frame that is not a keyframe, making the extraction process almost instantaneous.