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.mp4Prefer no terminal?
Use the Video Trimmer in your browser
What each flag does
| -i | Input file. Can be a video, audio, or image. Repeat for multiple inputs. |
|---|---|
| -ss | Seek to this timestamp (HH:MM:SS or seconds). Place BEFORE -i for fast keyframe seek; AFTER -i for sample-accurate seek. |
| -to | Stop at this timestamp (absolute, not duration). Use -t instead for a relative duration. |
| -c:v | Video codec for output. e.g. libx264, libx265, libvpx-vp9. |
| -crf | Constant Rate Factor — quality target (lower = better, larger file). 23 is visually lossless for libx264. |
| -c:a | Audio codec for output. e.g. aac, libmp3lame, copy. |
| -b:a | Audio bitrate, e.g. 192k. |
| -y | Overwrite 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.mp4The first frame timestamp should be 0. Anything else means the trim carried an offset into the output.
What to change
| -crf 18 is the quality | This re-encodes, so the number matters. 18 is visually lossless, 23 is the usual default, 28 is visibly soft. |
|---|---|
| Use stream copy when you can | If the cut can move a second or two, the lossless version is instant and costs no quality. |
| Keyframe interval on the source | Footage 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.