Local, transcript-driven talking-head video editing. Record a few takes, review the edit as plain text, and render a finished, captioned video — fillers removed, pauses tightened, stumbles cut, word-timed karaoke captions burned in. No timeline scrubbing, no cloud, no subscriptions: everything runs on your machine.
vlogcut setup # one-time: check/install the dependencies
vlogcut ingest takes/*.mov # transcribe → words.json + edit.md
$EDITOR edit.md # review: reorder / mark / delete lines
vlogcut render -o final.mp4 # cut, recombine, caption, encode
The pipeline in full:
ingest → curate → plan → (review edit.md) → render → audit / inspect
- ingest — extract audio, transcribe with whisper.cpp (word-level DTW
timestamps), refine every word boundary against the actual audio energy,
detect the speaker's face for auto-framing, and write two artifacts:
words.json(every word with precise timings — the source of truth) andedit.md(one sentence per line — the edit decision list). - curate — conservatively mark likely false starts and restarts.
- plan (optional) — a language model derives the story: which lines, in what order, which deserve a zoom punch-in. It can only select and reorder lines you actually spoke — never invent text.
- review —
edit.mdis the interface. Delete or move lines, mark withx, strike single words with~~word~~, force framing with{zoom}/{wide}. - render — one ffmpeg pass: cuts derived from the transcript, de-clicked
splices, speed-ramped pauses, face-aware framing, zoom punch-ins, picture
overlays, burned-in captions.
--previewgives a fast draft with byte-identical audio. - audit / inspect — verification:
auditre-listens to every splice (audio-only render + whisper probes + energy checks) and reports audible defects a text diff cannot show;inspectdraws a waveform PNG of any source range with everythingwords.jsonbelieves about it.
docs/USAGE.md is the deep guide; docs/PRODUCT.md records the product rationale and docs/ARCHITECTURE.md the module boundaries.
git clone <this repo> && cd vlogcut
python3 -m pip install -e . # or run as: python3 vlogcut.py ...
vlogcut setup # doctor + installer (see below)
mkdir ~/my-vlog && cd ~/my-vlog
vlogcut ingest ~/footage/take*.mov --curate
$EDITOR edit.md # the one manual step
vlogcut render -o final.mp4 --preview # fast draft…
vlogcut render -o final.mp4 # …then the deliverable
vlogcut audit # re-listen to every splice (advisory)vlogcut setup checks every dependency (and tells you exactly what is
missing and how it will fix it), offers the installs only with your
explicit confirmation (--yes for non-interactive use, --check for a
strictly read-only report), and writes the resolved paths to
~/.config/vlogcut/config.yaml.
vlogcut itself is pure Python 3 (stdlib only, no packages). It drives four external tools:
| Tool | Required | Where it comes from |
|---|---|---|
ffmpeg + ffprobe with libass |
yes | brew install homebrew-ffmpeg/ffmpeg/ffmpeg — the Homebrew core bottle is built without libass, so its subtitles filter (caption burn-in) is missing; vlogcut setup detects this and offers the tap install. A static libass-enabled macOS arm64 ffmpeg download is not reliably available, so setup never attempts one. |
whisper-cli (whisper.cpp) |
yes | brew install whisper-cpp |
| a whisper ggml model | yes | vlogcut setup downloads ggml-large-v3.bin (~3.1 GB) from the official whisper.cpp HuggingFace repo, resumable, to ~/.config/vlogcut/models/ — or it finds one you already have in the common model caches |
afconvert |
no | built into macOS (audio extraction); when absent, ffmpeg produces the identical WAV |
Tool paths resolve through four layers (first hit wins): the project's
vlogcut.yaml (whisper_cli:, whisper_model:, ffmpeg:, ffprobe:) →
~/.config/vlogcut/config.yaml → $VLOGCUT_WHISPER_CLI /
$VLOGCUT_WHISPER_MODEL / $VLOGCUT_FFMPEG / $VLOGCUT_FFPROBE →
auto-detection (PATH, the Homebrew bin dirs, the common model caches).
Word-timestamp accuracy is what drives cut quality — every cut lands where
the transcript says a word starts or ends. ggml-large-v3 is strongly
recommended: 3.1 GB on disk, and transcription peaks at ~4.2 GB of RAM
(measured, see below). medium (~1.5 GB) and small (~0.5 GB) run faster
and lighter but their sloppier word timings mean less precise cuts; vlogcut
warns when it has to settle for one.
Measured on the author's machine — Apple M5 Pro, 64 GB RAM, macOS 26 —
with ggml-large-v3 (Metal-accelerated):
- transcription: a real 2.6-minute 4K take transcribes in ~12 s (~13× realtime); the whole cold ingest of that take (extract + transcribe + energy analysis + face detection) is ~27 s.
- peak transcription memory: 4.2 GB RSS (measured with
/usr/bin/time -l). - rendering: a ~2.5-minute captioned 4K-source render encodes in 15–35 s;
--previewroughly halves it. Re-rendering after anedit.mdtweak needs no re-ingest.
Everything below for other chips is an estimate extrapolated from published whisper.cpp benchmarks — clearly labeled, not measured here:
| Mac | Verdict | Notes |
|---|---|---|
| Apple Silicon Pro/Max/Ultra, 16 GB+ (M1 Pro and later) | Recommended | Comfortable. Large-v3 transcription well above realtime (est. 3–8× on M1 Pro–M4 Pro), RAM headroom for browsers alongside. |
| Apple Silicon base, 8 GB (M1/M2/M3 Air & friends) | Works | Large-v3 runs (Metal), transcription roughly realtime-ish (est. 1–3×). The 4.2 GB peak makes it memory-tight next to a browser — close tabs, or use --model medium and accept softer cut precision. |
| Intel Macs | Difficult | whisper.cpp runs CPU-only (no Metal): large-v3 is impractically slow (est. several× slower than realtime). small/medium are usable, but cut precision suffers — expect to lean on vlogcut audit and manual ~~strikes~~. |
| Any Mac, for rendering | Fine | Encoding is ffmpeg/libx264: any Mac that can play 4K can encode it — it is just time. |
Disk: the model (0.5–3.1 GB) plus your footage; the per-project
.vlogcut-cache/ stores transcripts (kilobytes, not media).
- macOS-first. Developed and used on Apple Silicon macOS; that is the supported path.
- Face-aware framing is macOS-only (Apple Vision via a tiny bundled
Swift helper, compiled on first use with
swiftc). Without it, framing degrades gracefully to a no-op with a warning — every other feature works. - Linux is untested. Nothing in the Python is macOS-specific and the afconvert→ffmpeg fallback exists precisely for platforms without it, but no one has run the pipeline end-to-end on Linux yet. Reports welcome.
vlogcut plan asks a language model to derive the story order. Two
backends: the claude CLI (default) or Ollama
(--backend ollama) for a fully local model. Neither is required — the
tool is fully usable with a hand-edited edit.md: ingest generates it,
curate marks the false starts, and you reorder/delete lines in any editor.
All optional, all flat key: value files in the project dir, all documented
in docs/USAGE.md: vlogcut.yaml (pauses, zoom, framing,
speed ramps, tool overrides), captions.yaml (style), overlays.yaml
(picture overlays), corrections.yaml (durable transcription fixes),
framing.yaml (per-take framing).
python3 tests/run_checks.py
Runs the full check suite (~350 checks) on hand-built word lists and the
tiny synthetic fixtures in testdata/takes/ (ffmpeg testsrc pattern +
say-synthesized voice — no real footage). No network, no model needed.
vlogcut is open source under the GNU General Public License v3.0 (see LICENSE). You may use, study, share, and modify it — including commercially; GPL-3.0 is a copyleft license, so derivative works must remain GPL-licensed with source available. Contributions are accepted under the same license — see CONTRIBUTING.md.