Understanding video trimming
Keyframes determine where you can cut.
Why a video can't be sliced at every frame, the difference between I/P/B frames, and the two approaches every trim tool uses.
Frames aren't all equal.
Modern video codecs (H.264, H.265, AV1, VP9) compress by encoding only the differences between frames, not whole pictures. There are three frame types. I- frames (intra-coded) are full pictures — independent, can be decoded alone. P- frames (predicted) only encode differences from a previous frame. B-frames (bi- directional) encode differences from frames in both directions. The compression win is huge — P/B frames are tiny compared to I-frames — but you can only start decoding at an I-frame.
The keyframe-snap trade.
Stream-copy trimming (FFmpeg's -c copy) only cuts at I-frames. The start of the trim snaps to the nearest preceding I-frame; the end of the trim snaps to the nearest following I-frame (or runs to the end). Fast (sub-second per minute of source), no quality loss, but imprecise — typical keyframe interval is 2-10 seconds, so cuts can be wrong by several seconds. Good for "roughly chop the first minute"; bad for "the cut must start exactly at 1:23.45".
Re-encode for precision.
The alternative: decode the source, cut at the exact requested frame, re-encode the output. Frame-accurate cuts. Slower (real-time-ish encoding speed), one generation of lossy quality degradation. For most trim use cases — exporting a shareable clip, removing a few seconds of dead air — the precision matters more than the quality loss. For archival or further-editing-needed clips, stream-copy is the right choice and you live with the imprecision.
A worked trim.
Trim a 5-minute screen recording to seconds 30-180. Stream-copy: ffmpeg -ss 30 -t 150 -i in.mp4 -c copy out.mp4 — runs in under a second; the actual start is "the I-frame closest to second 30", which might be second 28 or 32. Re-encode: same flags but with explicit encoder ( -c:v libx264 -crf 18); runs at roughly real-time (~3 minutes for a 5-minute clip), frame-accurate, slight quality loss.
Stream-copy
-c copy ; keyframe-aligned cuts
Fast, lossless, imprecise by 2-10 seconds.
ffmpeg -ss 30 -t 150 -i in.mp4 -c copy out.mp4
= Sub-second runtime
Re-encode
-c:v libx264 ; frame-accurate cuts
Slow, lossy, exact endpoints.
ffmpeg -ss 30 -t 150 -i in.mp4 -c:v libx264 -crf 18 out.mp4
= Real-time runtime, exact cuts
Audio sync after trimming.
Audio and video tracks are stored separately inside the container, with their own timestamps. A trim that cuts the video at an I-frame must offset the audio start to match — most tools handle this correctly, but home-rolled scripts often forget. The symptom is audio drifting earlier or later than the visible action. Fix: ensure both tracks use the same start time after the trim, or do the trim via a single FFmpeg command that handles both.
Forcing a keyframe at the cut.
Hybrid approach: re-encode just enough of the source to insert a keyframe at the desired cut point, then stream-copy the rest. Gets you frame-accurate cuts with most of the speed of stream-copy. FFmpeg's -force_key_frames option plus a tactical re-encode segment does this. Worth the effort for batch jobs; overkill for one-off trims.