How to Extract Every Nth Frame with FFmpeg Select

Extracting frame intervals from a video is a common requirement for creating preview galleries, performing computer vision analysis, or generating datasets. This guide explains how to use the FFmpeg select filter to extract every nth frame from any video file, detailing the necessary syntax, required flags, and practical examples.

The Basic Command

To extract every nth frame, use the select filter combined with modulo arithmetic (mod). The core expression tests whether the current frame index n divided by your target interval leaves a remainder of zero.

ffmpeg -i input.mp4 -vf "select='not(mod(n\,10))'" -vsync vfr frame_%04d.png

In this command:

  • -i input.mp4: Specifies the input video file.
  • -vf "select='not(mod(n\,10))'": Applies the video filter. Replace 10 with your desired interval n. The comma must be escaped with a backslash (\,).
  • -vsync vfr: Sets the video synchronization method to "Variable Frame Rate". This prevents FFmpeg from duplicating dropped frames to maintain the original frame rate. In modern FFmpeg versions, -fps_mode vfr can also be used.
  • frame_%04d.png: Formats the output image filenames with sequential, zero-padded numbers (e.g., frame_0001.png, frame_0002.png).

Understanding the Filter Syntax

The select filter evaluates an expression for every frame. If the expression evaluates to a non-zero value, the frame is kept; if zero, it is discarded.

  • n: The sequential index of the current frame, starting at 0.
  • mod(n\, N): Computes the remainder of dividing the frame number n by N.
  • not(...) or eq(..., 0): Inverts the result so that when the remainder is 0, the expression evaluates to true (1).

An alternative, equivalent syntax is:

ffmpeg -i input.mp4 -vf "select='eq(mod(n\,10)\,0)'" -fps_mode vfr frame_%04d.png

Extracting Frames as JPEGs

To extract the frames as JPEG images rather than PNGs, change the file extension and include the -q:v flag to control compression quality:

ffmpeg -i input.mp4 -vf "select='not(mod(n\,30))'" -fps_mode vfr -q:v 2 frame_%04d.jpg

A -q:v value between 2 and 5 offers high visual quality, where 2 represents very low compression.

Limiting the Frame Extraction to a Time Range

If you only need frames from a specific portion of the video, combine the command with fast seeking using -ss (start time) and -to or -t (duration):

ffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp4 -vf "select='not(mod(n\,15))'" -fps_mode vfr frame_%04d.png

Placing -ss before the -i flag ensures FFmpeg quickly seeks to the starting timestamp before decoding frames.