How to Use FFmpeg setpts to Fix Timestamps
When you extract or drop specific frames using FFmpeg's
select filter, the surviving frames retain their original
Presentation Timestamps (PTS). This creates gaps in the timeline,
causing media players to freeze, stutter, or display inaccurate
durations. This guide demonstrates how to use the setpts
filter directly after the select filter to rewrite
timestamps sequentially, producing a smooth, continuous video
stream.
Why Timestamps Break After Frame Selection
The select filter evaluates an expression for each frame
and passes only the frames that evaluate to true. However, it does not
alter the PTS metadata. If you select frame 0, frame 50, and frame 100,
their original timestamps remain untouched, leaving multi-second freezes
between each rendered frame.
The setpts (Set Presentation Timestamp) filter
recalculates these values based on internal variables like the frame
index (N), the framerate (FRAME_RATE), or the
stream's time base (TB).
Resetting Timestamps for Constant Framerate Video
When selecting frames to create a standard, continuous video, the most reliable method is to recalculate timestamps based on the new frame count and the target framerate.
Use the expression setpts=N/FRAME_RATE/TB:
ffmpeg -i input.mp4 -vf "select='not(mod(n\,2))',setpts=N/FRAME_RATE/TB" -an output.mp4In this command:
select='not(mod(n\,2))'keeps every second frame (even-numbered frames).setpts=N/FRAME_RATE/TBassigns each kept frame a new sequential PTS starting from 0, whereNis the index of the filtered frame,FRAME_RATEis the input stream's frame rate, andTBis the time base.
Resetting Timestamps from the First Kept Frame
If you are trimming a contiguous segment or dropping an initial set
of frames, you can shift the timestamps so the first selected frame
starts at time zero using PTS-STARTPTS:
ffmpeg -i input.mp4 -vf "select='gte(t\,10)',setpts=PTS-STARTPTS" -an output.mp4select='gte(t\,10)'drops all frames before the 10-second mark.setpts=PTS-STARTPTSsubtracts the timestamp of the first output frame from all subsequent frames, resetting the beginning of the video to 00:00:00 without altering playback speed.
Handling Synchronized Audio
If your video filter removes frames and your audio stream must remain
synchronized, you must apply the aselect and
asetpts filters to the audio stream:
ffmpeg -i input.mp4 -vf "select='gte(t\,5)',setpts=PTS-STARTPTS" -af "aselect='gte(t\,5)',asetpts=PTS-STARTPTS" output.mp4For expressions relying on sample counts rather than start-time
offsets, use asetpts=N/SR/TB, where SR is the
audio sample rate.
Common Parameters Reference
N: The sequential index of the frame (starts at 0 for the first frame reaching the filter).STARTPTS: The PTS of the first frame processed.PTS: The original PTS of the current frame.FRAME_RATE: The nominal frame rate of the video stream.TB: The time base of the stream, defining the unit of measurement for timestamps.