Extract Frames by Timestamp with FFmpeg Select

Extracting specific frames from a video is a fundamental task in video editing and analysis. This guide explains how to use the FFmpeg select filter to extract precise frames based on timestamps, time ranges, or intervals, providing the exact commands and syntax needed to automate the process.

The select filter in FFmpeg allows you to keep or discard frames based on evaluation expressions. When working with timestamps, the key variable to use is t, which represents the presentation timestamp of the current frame in seconds.

Extracting a Frame at a Specific Second

To extract a single frame at an exact timestamp (for example, at the 5-second mark), you can use the eq (equal) function:

ffmpeg -i input.mp4 -vf "select=eq(t\,5)" -vframes 1 output.png

In this command: * -vf "select=eq(t\,5)" filters the input, selecting only the frame where the time t is exactly 5. Note that the comma must be escaped with a backslash. * -vframes 1 limits the output to a single frame, ending the process immediately once the target frame is written.

Extracting Frames Within a Specific Time Range

If you want to extract all frames within a specific duration, use the between function. For example, to extract all frames between the 10th and 12th seconds:

ffmpeg -i input.mp4 -vf "select='between(t,10,12)'" -fps_mode passthrough output_%03d.png

In this command: * between(t,10,12) selects frames where the timestamp t is greater than or equal to 10 and less than or equal to 12. * -fps_mode passthrough (which replaces the legacy -vsync 0 flag) is required to prevent FFmpeg from duplicating or dropping frames to match the original video’s frame rate. * output_%03d.png outputs sequential images (e.g., output_001.png, output_002.png).

Extracting Frames at Regular Time Intervals

You can also use mathematical operators to extract frames at regular intervals, such as one frame every 10 seconds, by using the modulo operator (mod):

ffmpeg -i input.mp4 -vf "select='not(mod(t,10))'" -fps_mode passthrough output_%03d.png

Here, not(mod(t,10)) evaluates to true (non-zero) only when the current timestamp t is a multiple of 10, resulting in one frame extracted at 10s, 20s, 30s, and so on.