Headless Mode
Free · open source

keycut

Lossless multi-range video cutting that snaps to keyframes instead of lying about it

In real use since

Cuts several ranges out of one video and joins them into a single file — losslessly, snapped to the file’s real keyframes instead of the extra footage a naive ffmpeg -ss … -c copy quietly keeps.

Why -c copy alone gets it wrong

A stream copy moves compressed packets without decoding them, so it can only start where a keyframe already sits — not at the timestamp asked for. ffmpeg snaps backward to the nearest keyframe at or before the cut point and hides the extra frames behind an edit list, so the clip looks the right length in a player and is not: the concat demuxer that joins multiple cuts reads packets, not edit lists, and plays every hidden frame back. Cut two adjacent ranges this way and the second one opens by replaying the tail of the first; cut around a range you meant to remove and part of it can come back.


What keycut does instead

It asks ffprobe where the keyframes actually are, then only ever cuts on one — snapping forward, never back. Ranges that overlap, or sit closer together than one GOP — a group of pictures, the span from one keyframe to just before the next — are merged first, so no join is left to replay anything. An optional exclude mask names seconds that must never survive the cut; keycut re-encodes just the ranges that need it, using codec and color settings read from the master itself, and stream-copies the rest.


Command line

1keycut master.mp4 highlights.mp4 -r 0:30 1:15 -r 4:00 4:45

--dry-run prints the plan — which ranges merged, where each cut was aligned, and which ranges will be copied versus re-encoded — without touching a byte.


The plan on a real file

The master here is a synthetic test clip generated for this page — a 30-second ffmpeg testsrc pattern, 640×360 at 30 fps, forced to a keyframe every 2 seconds. No customer footage is involved. What follows is keycut’s own output, pasted verbatim:

1$ keycut source.mp4 highlights.mp4 -r 0:05 0:11 -r 0:12 0:17 -r 0:21 0:27 --dry-run
2master:    source.mp4
3keyframes: 15
4merge gap: 2.100s
5requested: 3 range(s) -> 2 extraction(s)
6  [0] 6.000 -> 17.000  stream copy (start aligned +1.000s)
7  [1] 22.000 -> 27.000  stream copy (start aligned +1.000s)

Three ranges became two cuts. The first two sat 1 second apart — narrower than the merge gap on the row above, which is not the file’s literal keyframe spacing (2.0 s) but keycut’s effective GOP: the 95th-percentile gap between consecutive keyframes, plus a 5% margin for timestamp rounding, giving 2.100 s. Below that width there is no keyframe to cut on at all, so the two ranges merged, and the join that would have replayed a second of footage is simply not there to go wrong. Both surviving starts moved forward onto the next real keyframe, the +1.000s on each row, rather than back onto the previous one.


Requirements

Python 3.11+, and ffmpeg/ffprobe on PATH. No Python dependencies. The Windows installer above does not bundle ffmpeg — winget install -e --id Gyan.FFmpeg puts it on PATH (or choco install ffmpeg).


Documentation

keycut’s documentation lives in its repository, next to the code it describes — the README is the manual.

← All software