Extract Keyframes with the FFmpeg Select Filter
Extracting keyframes—also known as intra-frames or I-frames—allows
you to capture the primary, fully rendered frames of a video without
decoding intermediate motion data. This guide demonstrates how to
isolate and export only the keyframes from any video file using FFmpeg's
built-in select video filter, explaining the command
syntax, the parameters required to prevent duplicated frames, and how to
customize the output format.
The Keyframe Extraction Command
To extract all keyframes from a video and save them as individual image files, run the following command in your terminal:
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -vsync vfr keyframe_%04d.jpgFor newer versions of FFmpeg (version 5.0 and later),
-fps_mode is preferred over the deprecated
-vsync option:
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -fps_mode vfr keyframe_%04d.jpgBreakdown of the Command Options
-i input.mp4: Specifies the path to your source video file.-vf "select='eq(pict_type,I)'": Applies the video filter (-vf). Theselectfilter evaluates each frame against a condition. In this case,eq(pict_type,I)checks whether the frame's picture type is an I-frame (keyframe). Frames that evaluate to true are passed through; all others are dropped. You can also write this aseq(pict_type,PICT_TYPE_I).-vsync vfr/-fps_mode vfr: Sets the output to variable frame rate (VFR). By default, FFmpeg attempts to maintain a constant frame rate by duplicating the remaining frames to fill the gaps left by dropped frames. Usingvfrensures FFmpeg only outputs the frames that successfully passed through the filter.keyframe_%04d.jpg: Defines the output naming pattern.%04dformats the frame sequence as a zero-padded, four-digit number (e.g.,keyframe_0001.jpg,keyframe_0002.jpg).
Outputting to Different Image Formats
You can change the image format simply by modifying the file extension of the output pattern:
PNG (lossless):
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -fps_mode vfr keyframe_%04d.pngHigh-Quality JPEG:
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -fps_mode vfr -q:v 2 keyframe_%04d.jpgThe
-q:v 2flag sets the JPEG quality scale, where2provides high quality (values range from1to31, with1being the highest quality).
Saving Keyframes with Timestamps
If you need the filename to reflect the exact presentation timestamp
(PTS) of the keyframe rather than a sequential index, use the
showinfo filter or the metadata filter to
write the frame's timestamp directly into the file or its metadata:
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -fps_mode vfr -frame_pts true keyframe_%d.jpgSetting -frame_pts true substitutes the %d
token with the frame's presentation timestamp in the sequence, allowing
you to trace each keyframe back to its original position on the video
timeline.