Skip to content

Back to the catalog

Show HN: Overtone – Transcribe, correct and cut captions for any screen shape
github.comrepo

Show HN: Overtone – Transcribe, correct and cut captions for any screen shape

Overtone is a caption format (.overtone.json), a CLI and a video.js plugin that store each spoken word once and cut captions separately per screen shape (16:9, 9:16 or custom). The transcribe pipeline combines gpt-transcribe, Azure AI Speech and optional ElevenLabs Scribe, resolves disagreements with an LLM vote, and uses an LLM editor for corrections. A small public benchmark reports 5.3% word error rate and $0.023–0.025 per audio minute.

TL;DR Generates word-timed captions from audio with multiple ASR engines and an LLM editor, then cuts per-aspect-ratio caption layouts for video.js.
Document

What it claims

Overtone stores each spoken word once in .overtone.json, with its time and speaker, plus any number of "cuts" that point to those words, one per screen shape. WebVTT and TTML store finished cues, so a player can only rewrap them. Overtone instead cuts lines per profile using reading rules: no line ending on weak words like "the" or "of", names and numbers kept together, one speaker per caption, and pauses turned into breaks. On three English clips, 0.3% of its line breaks end on a weak word with no pause, against 28.8% for length-limit filling and 16.1% for ElevenLabs' SRT export.

How it works

flowchart LR
  A[Audio] --> T[gpt-transcribe: text]
  A --> Z[Azure Speech: times, speakers]
  A -.optional.-> E[ElevenLabs Scribe]
  T --> V[LLM text vote]
  E -.-> V
  V --> ED[LLM editor + glossary]
  Z --> W[Word times]
  ED --> W
  W --> R[Versioned rule set per profile]
  ED -.unsure edits.-> Q[Review list]

gpt-transcribe supplies the words, and Azure AI Speech supplies word times and speakers. ElevenLabs Scribe adds a second text hearing when ELEVENLABS_API_KEY is set. Where hearings disagree, the text model re-listens to the snippet and an LLM picks the words. An LLM editor then fixes names and terms from user context and glossary, labels speakers, and puts uncertain edits on a review list. The LLM never sets timestamps; code checks only the structure of its changes. Line cutting is deterministic: the same words and rule set give the same captions.

Evidence

Line breaks were tested on three English clips (20.8 minutes, 16:9, rule set 1). Overtone broke at all 47 speaker pauses of 0.5 to 1.5 s; the two baselines broke at 28% and 72% of them. Text was tested on six clips in four languages (20 minutes, 3 runs, October 23, 2026). On the 5 clips where every engine returned text, word error rate was 5.3%, against 6.2% for gpt-transcribe alone and 7.7% for Azure Speech alone. gpt-transcribe returned nothing for a quiet meeting in every run. Overtone retried with the language the other engines detected and scored 32.8% WER, against 42.9% for Azure alone. Cost was $0.023 to $0.025 per audio minute, or $0.029 with Scribe, at list prices.

How to use it

Re-cutting existing subtitles runs offline with no API key and no ffmpeg (Node.js 22.12+). Word times are estimated from the cues:

npx overtone-captions recut TOS-en.srt

This writes the .overtone.json, horizontal and vertical .vtt and .srt files, and a transcript. Output from WhisperX or stable-ts can be re-cut the same way. Transcription needs ffmpeg and OpenAI plus Azure keys. --dry-run shows where audio goes and the estimated cost without sending anything, and --local uses whisper.cpp and Ollama instead:

npm install -g overtone-captions
overtone transcribe talk.mp4 --language en --context "Panel about urban cycling" --dry-run

The player is videojs-overtone (video.js 8.5+, five style packs):

videojs('my-video').overtone({ src: 'talk.overtone.json' });

overtone-format has the types, JSON Schema, validator and exporters, with no runtime dependencies.

Limits

Full line-cutting and number rules exist only for English and Dutch. German, French, Spanish, Italian and Portuguese get language detection, and other languages get neutral rules. In Chinese, Japanese and Thai a "word" is a whole phrase, with one time per phrase. There is no translation, no sound tags such as [music], and no GUI editor. Media is limited to 2 hours. The authors call the benchmark small, and the line-break test is English-only at 16:9. The page states no licence.

Organisations named here

  • OpenAI
  • Microsoft
  • ElevenLabs
  • NASA
  • Azure AI Speech
  • Blender Foundation
  • ElevenLabs Scribe
  • gpt-transcribe
  • lonthq
  • Ollama
  • Overtone
  • stable-ts
  • Tears of Steel
  • WhisperX

Technologies named here

  • whisper.cpp
  • Ollama
  • FFmpeg
  • Node.js
  • LLM
  • OpenAI API
  • TypeScript
  • npm
  • Claude Code
  • Codex
  • Blender
  • Agent Skill for Claude Code and Codex
  • Azure AI Speech
  • ElevenLabs Scribe
  • gpt-transcribe
  • JSON Schema
  • Overtone
  • overtone-captions
  • overtone-format
  • SRT
  • stable-ts
  • video.js
  • videojs-overtone
  • WebVTT
  • WhisperX

Techniques named here

  • LLM editor pass
  • Multi-engine hearings with text vote
  • Recut of existing subtitles
  • Rule-based line cutting per aspect ratio