Reel 01Go CLIffmpeg + Deepgramsrt · vtt · txt · json
Cut subtitles
straight from the file.
subkit extracts the audio, transcribes it, shapes the words into cues and renders every format you asked for — from one command, with every stage cached so the next run is instant.
Nobody tells you that the hard part of subtitling isn't the words. It's deciding where to cut them. Ninguém nos diz que a parte difícil das legendas não são as palavras. --language pt-PT 42 characters a line. 17 a second. Two lines, never three. --subtitle-algorithm netflix
subkit subtitle movie.mp4
Needs ffmpeg on your PATH and a DEEPGRAM_API_KEY. Full setup →
What comes out
Four artefacts,
one transcription.
Ask for as many outputs as you like in a single command. They are all rendered from the same cached transcript, so extra formats cost nothing but the write.
1 00:00:12,040 --> 00:00:15,900 Nobody tells you that the hard part of subtitling isn't the words. 2 00:00:16,400 --> 00:00:18,880 It's deciding where to cut them.
WEBVTT 00:00:12.040 --> 00:00:15.900 Nobody tells you that the hard part of subtitling isn't the words. 00:00:16.400 --> 00:00:18.880 It's deciding where to cut them.
Nobody tells you that the hard part of subtitling isn't the words. It's deciding where to cut them. Every provider hands back a wall of tokens with timestamps attached, and the shaping is left as an exercise for the reader.
[
{
"index": 0,
"text": "nobody",
"punctuated": "Nobody",
"start": 12.04,
"end": 12.44,
"confidence": 0.99873,
"speaker": 0,
"channel": 0,
"language": "en-US"
},
{ "index": 1, "text": "tells", … }
]
The pipeline
Five stages.
Each one an artefact.
Every stage writes a cached artefact keyed by the source media hash, the step options, the pipeline version and — for audio — the ffmpeg build. Stop at any one of them, or run the lot.
Provider-neutral transcript
Words carry text, punctuation, start and end, confidence, speaker, channel and language. Segments carry type and word ranges. Deepgram today, without a schema that assumes it.
Whole seasons at a time
Pass files or globs. Four run concurrently by default, a live terminal view tracks each one, and failures are collected into a summary instead of killing the queue.
Audio stays temporary
Normalized audio is run-local by default because it grows fast. Pass --cache-audio when you want it kept and reused between runs.
Progress that adapts
An interactive Bubble Tea view in a terminal, plain log lines when output is redirected. Force either with --progress tui or --progress plain.
Cue shaping
The hard part
isn't the words.
Transcription gives you tokens and timestamps. Deciding where a cue starts, where a line breaks and how long it stays on screen is a different problem — and subkit ships two answers to it. Same audio, same transcript, below:
1 00:00:12,040 --> 00:00:14,180 [speaker 0] Nobody tells you that the hard part of 2 00:00:14,180 --> 00:00:17,640 subtitling isn't the words. It's deciding where to 3 00:00:17,640 --> 00:00:18,880 cut them.
1 00:00:12,040 --> 00:00:15,900 Nobody tells you that the hard part of subtitling isn't the words. 2 00:00:16,400 --> 00:00:18,880 It's deciding where to cut them.
deepgram is a faithful port of deepgram-go-captions — fixed-size chunks, timing taken straight from the first and last word. netflix follows the Timed Text Style Guide: it never spans a speaker change or a long silence, packs whole sentences while they fit, splits oversized ones at the best linguistic break, and favours bottom-heavy line breaks. Read the full comparison →
Caching
Run it twice.
Pay once.
Cache keys hash the source media, the step options, the pipeline version and the ffmpeg version string. Change a subtitle flag and only the cue and render stages rebuild — the transcription is reused. Delete an output file and it comes straight back from the render cache.
subkit subtitle movie.mp4 --rerun transcribe # one stage subkit subtitle movie.mp4 --rerun audio,cues # several subkit subtitle movie.mp4 --refresh # rebuild all subkit subtitle movie.mp4 --no-cache # touch nothing
subkit cache path # where it lives subkit cache list # what's in it subkit cache clean # empty it subkit --cache-dir ./.subkit-cache subtitle movie.mp4
Distribution
Install it
A single static binary, built for amd64 and arm64 on all three platforms. No runtime to install beyond ffmpeg.
winget install AndreSantos.Subkit
Or run the .msi installer from the releases page.
subkit_darwin_arm64.dmg
Disk images and .zip archives on the releases page.
curl -sSL …/subkit_linux_amd64.tar.gz | tar xz
Move the subkit binary anywhere on your PATH.
go install github.com/andrerfcsantos/subkit-codex/cmd/subkit@latest
Builds from source, everywhere Go runs.
Prerequisites: ffmpeg on your PATH and a DEEPGRAM_API_KEY environment variable. Per-platform notes, verification and shell setup are in the install guide.