Seek to a Specific Keyframe in FFmpeg

Seeking to a specific keyframe index in FFmpeg requires a two-step process because FFmpeg natively seeks using time values (timestamps) rather than sequential frame indices. This article explains how to identify the timestamp of a specific keyframe using ffprobe and how to use that timestamp to seek directly to the keyframe using ffmpeg for ultra-fast, frame-accurate extraction or cutting.

Step 1: Find the Timestamp of the Keyframe Index

To seek to a specific keyframe index (for example, the 5th keyframe), you must first find its exact timestamp. You can extract a list of all keyframe timestamps using ffprobe.

Run the following command in your terminal:

ffprobe -loglevel error -skip_frame nokey -select_streams v:0 -show_entries frame=pkt_pts_time -of csv=p=0 input.mp4

This command filters the video to show only keyframes (-skip_frame nokey) and outputs their presentation timestamps (PTS) in seconds.

The output will be a list of timestamps, such as:

0.000000
2.502000
5.004000
7.507000
10.010000

In this list, each line represents a keyframe index. For example: * Index 0: 0.000000 seconds * Index 1: 2.502000 seconds * Index 2: 5.004000 seconds * Index 4 (5th keyframe): 10.010000 seconds

Identify the timestamp corresponding to your desired keyframe index.

Step 2: Seek to the Keyframe Using FFmpeg

Once you have the timestamp, you can seek to that exact position. For maximum speed, place the -ss (seek) parameter before the input file (-i). This utilizes input seeking, which jumps directly to the nearest keyframe without decoding the preceding video.

Option A: Extract a Single Image at the Keyframe

To extract the exact keyframe as an image, use the timestamp you found (e.g., 10.010000):

ffmpeg -ss 10.010000 -i input.mp4 -vframes 1 output.jpg

Option B: Cut the Video Starting from the Keyframe

To split or cut the video starting precisely at that keyframe without re-encoding (lossless copy):

ffmpeg -ss 10.010000 -i input.mp4 -c copy -to 00:01:00 output.mp4

Alternative: Direct Filtering (No Timestamp Needed)

If you want to extract a specific keyframe index in a single command without finding the timestamp first, you can use FFmpeg’s select filter. Note that this method is slower because FFmpeg must decode the video from the beginning to count the frames.

To extract the 5th keyframe (index 4, as counting starts at 0):

ffmpeg -i input.mp4 -vf "select='eq(pict_type\,I)',select='eq(n\,4)'" -vframes 1 output.jpg