FFmpeg recipe

FFmpeg: Frame-Accurate Trim of an MP4 (Re-Encode)

When stream-copy snaps to the nearest keyframe and you need exact-frame precision, re-encoding is the answer. Slower, but sample-accurate.

Command

ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:30 -c:v libx264 -crf 23 -c:a aac -b:a 192k -y output.mp4
Prefer no terminal?
Use the Video Trimmer in your browser
Open Video Trimmer →

What each flag does

-iInput file. Can be a video, audio, or image. Repeat for multiple inputs.
-ssSeek to this timestamp (HH:MM:SS or seconds). Place BEFORE -i for fast keyframe seek; AFTER -i for sample-accurate seek.
-toStop at this timestamp (absolute, not duration). Use -t instead for a relative duration.
-c:vVideo codec for output. e.g. libx264, libx265, libvpx-vp9.
-crfConstant Rate Factor — quality target (lower = better, larger file). 23 is visually lossless for libx264.
-c:aAudio codec for output. e.g. aac, libmp3lame, copy.
-b:aAudio bitrate, e.g. 192k.
-yOverwrite output file without confirmation.

Notes & gotchas

  • Place -ss AFTER -i for sample-accurate seek (slower, decodes to the timestamp).
  • CRF 23 is visually lossless. CRF 18 is mathematically near-lossless but file size doubles.

Check it worked

ffprobe -v error -select_streams v -show_entries frame=pkt_pts_time -read_intervals %+#1 -of csv=p=0 output.mp4

The first frame timestamp should be 0. Anything else means the trim carried an offset into the output.

What to change

-crf 18 is the qualityThis re-encodes, so the number matters. 18 is visually lossless, 23 is the usual default, 28 is visibly soft.
Use stream copy when you canIf the cut can move a second or two, the lossless version is instant and costs no quality.
Keyframe interval on the sourceFootage with keyframes every ten seconds is why frame-accurate trimming needs a re-encode at all.

If it fails

Encoding is far slower than the stream-copy version.

Why: Frame-accurate trimming re-encodes every frame rather than copying packets, so it costs roughly what a full transcode costs.

Fix: Accept it when the exact cut matters, or use -c copy when a keyframe-aligned cut is good enough.

Audio and video drift apart after the cut.

Why: The audio stream was copied while the video was re-encoded, so the two no longer share a start point.

Fix: Re-encode both, or add -async 1 so the audio is resampled to match the video clock.

Related recipes