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.pngIn this command:
-i input.mp4: Specifies the input video file.-vf "select='not(mod(n\,10))'": Applies the video filter. Replace10with 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 vfrcan 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 at0.mod(n\, N): Computes the remainder of dividing the frame numbernbyN.not(...)oreq(..., 0): Inverts the result so that when the remainder is0, 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.pngExtracting 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.jpgA -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.pngPlacing -ss before the -i flag ensures
FFmpeg quickly seeks to the starting timestamp before decoding
frames.