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.mp4

In this command:

  • select='not(mod(n\,2))' keeps every second frame (even-numbered frames).
  • setpts=N/FRAME_RATE/TB assigns each kept frame a new sequential PTS starting from 0, where N is the index of the filtered frame, FRAME_RATE is the input stream's frame rate, and TB is 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.mp4
  • select='gte(t\,10)' drops all frames before the 10-second mark.
  • setpts=PTS-STARTPTS subtracts 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.mp4

For 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.