pip install git+https://github.com/dancolta/clipcut
clipcut takes/ --speed 1.15Not a clip finder. Not a caption burner. Not a cloud editor. It never rewrites what you said and never cuts for pace — only silence.
=== EDIT PLAN ===
cold-email-quotes-reviews (IMG_4451.MOV)
length 105.4s -> 96.6s (-8.8s, 8%)
speed 1.15x -> 84.0s final
cuts 9 captions 52
bleep 1 word(s) censored + beeped
CHECK 1 possible mis-transcription(s):
41.2s 'shadowing' (conf 0.44) -> did you mean 'scheduling'?
gates all pass
re-run with --yes to render
That CHECK line is the whole product. An automatic editor that mishears can't as can will burn the opposite of your meaning into 90 seconds of video, and you find out after publishing. clipcut flags it and stops.
Nine gates run before anything renders. The load-bearing one: a cut is a range of word indices, never a timestamp — so a cut landing inside a word isn't a bug to fix, it's a state that cannot be constructed.
Transcribes on-device (faster-whisper) → trims silence → burns word-by-word captions with the spoken word in an accent colour → masks and bleeps strong profanity → optionally retimes speed and ducks a music bed under the voice → one MP4 at −14 LUFS / −1 dBFS.
No account, no upload, no API key.
You need ffmpeg built with libass. The plain Homebrew ffmpeg formula is not, and will fail at render time rather than at startup.
brew install ffmpeg-full # macOS (not `brew install ffmpeg`)
sudo apt install ffmpeg # Debian/Ubuntu ships libass already
pip install git+https://github.com/dancolta/clipcutFirst run pulls the whisper weights (~1.5 GB) into ~/.cache and never re-downloads. Captions default to Outfit (OFL) — install it or pass --font anything you have. No fonts or music are bundled.
| Flag | Does |
|---|---|
--speed 1.15 |
Retimes video, audio and captions together, inside the existing encode pass |
--vocab "Grafana, Postgres" |
Biggest single lever on accuracy for proper nouns. Worth more than a bigger model |
--music bed.mp3 |
Your file, sidechain-ducked under the voice |
--scripts notes/ |
Names clips from your written scripts and checks suspect words against them |
--accent '#22D3EE', --font, --max-pause, --no-censor, --max-duration and the rest are in clipcut --help.
All nine gates — what each one blocks
All blocking and run before render, except where noted.
| Gate | Blocks |
|---|---|
no-mid-word-cut |
a cut boundary landing inside a spoken word |
no-orphan-fragment |
a cut leaving half a clause behind |
caption-cut-coherence |
a caption showing a word the edit removed |
caption-coverage-continuity |
frames inside a line with no caption — reads as flicker |
caption-sentence-integrity |
one line carrying the end of a sentence and the start of the next |
burned-text-fidelity |
the ASS field-count bug that renders a phantom leading comma |
protected-beats-intact |
a phrase you marked uncuttable being cut |
bleep-applied |
a word masked in the caption but left audible |
burned-text-recall |
OCR of the rendered frames disagreeing with the script — advisory, does not block |
python tests/test_gates.pySix cases are adversarial and are supposed to fail. Weaken a gate and they stop failing, and the suite tells on you. PRs that make them pass will not be merged.
Config — clipcut.toml, env vars, precedence
built-in defaults → clipcut.toml → CLIPCUT_* env vars → CLI flags
clipcut walks up from the working directory looking for clipcut.toml, then falls back to ~/.config/clipcut/clipcut.toml. See clipcut.toml.example.
[clipcut]
out_dir = "./shorts"
speed = 1.15
accent = "#A855F7"
margin_v = 400 # caption baseline, measured up from the bottom
vocab = "Grafana, Postgres, Terraform"margin_v is the one you will actually change — it is tuned to clear a centred talking head, and your framing is not mine. clipcut --print-config dumps what actually resolved.
Two findings from real use — audio clipping, and music licensing
Retiming after loudness normalisation clips. A 1.15x speed-up pushed a clean −0.8 dBFS master to +0.4 dBFS in testing. clipcut runs atempo before loudnorm so the signal being measured is the signal that ships.
Music on a Short over 60s is a licensing decision, not a taste one. A YouTube Short longer than 60 seconds carrying a Content ID claim is blocked globally, not merely demonetised. clipcut ships no music; --music takes a file you have cleared.
MIT. Built on faster-whisper and ffmpeg.
