FFmpeg FPS Filter: Custom Frame Rate Drop and Dup
This article provides a direct guide on using FFmpeg’s
fps video filter to alter a video’s frame rate while
controlling exactly how frames are duplicated or dropped. You will learn
the syntax of the fps filter, how its rounding mathematical
rules determine frame selection, and how to implement these settings in
your command-line workflows.
To change a video’s frame rate, FFmpeg must decide which original
frames to keep, drop, or duplicate to fit the new timeline. While the
basic -r option can change frame rates, the
fps video filter (-vf "fps=...") offers
precise control over this process by exposing parameters for rounding
and timestamp behavior.
Basic Syntax of the
fps Filter
The most basic usage of the filter defines only the target frame rate:
ffmpeg -i input.mp4 -vf "fps=fps=30" output.mp4In this command, FFmpeg converts the input video to 30 frames per second. By default, it uses “near” rounding, which maps input frames to the closest target timestamps.
Customizing
Drop and Duplicate Rules with round
To customize how FFmpeg drops or duplicates frames, you must use the
round option. The round parameter tells FFmpeg
how to handle timestamps that fall between target frame intervals.
The syntax is:
-vf "fps=fps=target_fps:round=rounding_method"There are five rounding methods available:
near(Default): Rounds to the nearest target timestamp. This creates the smoothest visual transition by choosing the closest available frame.zero: Rounds towards zero.inf: Rounds away from zero.down: Rounds down towards negative infinity. This is useful if you want to bias the filter toward dropping frames rather than duplicating them.up: Rounds up towards positive infinity. This biases the filter toward duplicating frames earlier in the timeline.
Example: Forcing Frame Dropping (Rounding Down)
If you are downsampling a video (e.g., 60 fps to 24 fps) and want to
strictly drop frames mathematically rather than letting FFmpeg
interpolate to the nearest neighbor, use down:
ffmpeg -i input.mp4 -vf "fps=fps=24:round=down" output.mp4Example: Biasing Towards Duplication (Rounding Up)
If you are upsampling (e.g., 25 fps to 30 fps) and want to bias the
duplicate frames upward to shift the timeline slightly forward, use
up:
ffmpeg -i input.mp4 -vf "fps=fps=30:round=up" output.mp4Managing the Start and End of the Video
To further customize frame rate conversion, you can control how FFmpeg handles the very beginning and the very end of the stream.
Setting the Start Time
By default, the fps filter assumes the first frame
starts at timestamp 0. If your input video has a presentation timestamp
(PTS) offset, this can cause unexpected frame drops or duplicates at the
start. You can manually define the starting timestamp using the
start_time option:
ffmpeg -i input.mp4 -vf "fps=fps=30:start_time=0" output.mp4Defining End of File (EOF) Behavior
You can control how the filter behaves when it reaches the end of the
video using the eof_action parameter:
round(Default): Applies the same rounding rule to the final remaining frame.pass: Passes the exact source end timestamp through, which can sometimes result in a variable frame rate for the very last frame to prevent unnecessary duplication.
ffmpeg -i input.mp4 -vf "fps=fps=30:round=near:eof_action=pass" output.mp4