Builds

perfect-srt: The Subtitle Fixer That Refuses Bad Captions (Names Protected, Timing Repaired)

· Builds

perfect-srt fixes machine subtitle drafts with protected names, inherited timing, and seven pass/fail gates before any file ships.

perfect-srt: The Subtitle Fixer That Refuses Bad Captions (Names Protected, Timing Repaired)

Last updated: November 11, 2026 · 6-minute read

19 name mangles in one machine draft — that is the count from a real job in this repo's examples folder, where a Korean broadcast transcript turned a group's own members into strangers and one line into "a snake". perfect-srt is the system I built so that class of error cannot ship quietly.

The problem it solves is specific. Machine subtitle drafts fail in predictable places — proper nouns, negations, idioms, lyrics — and the wrong text reads smoothly, so a general cleanup pass waves it through. perfect-srt takes the opposite approach: rebuild the track under rules, then refuse to write the final file until every gate passes.

Why Machine Drafts Get Names Wrong

A machine translator has no idea which words in a caption are names. To the model, a member's name is just an uncommon token sequence, and uncommon tokens are exactly what gets smoothed into something more common. The result is fluent, confident, and wrong — the worst kind of subtitle error, because the audience catches it instantly and forgives it never.

Negations fail the same quiet way. Drop one "not" and the sentence still parses; it just means the opposite of what was said. Lyrics fail loudest of all: sung lines over music arrive garbled at the transcription stage, before translation even starts.

The Three Rules Underneath It

The design rests on three disciplines, and everything else in the repo is machinery to enforce them.

  • The source track is the skeleton of truth. Timings are inherited from the source-language SRT exactly, by index range. The draft never gets to re-time anything.
  • Names are protected data. A per-artist names pack holds canonical spellings plus every known mangled variant. Variants are banned from the output by a validator, and counted in the old draft as before-and-after evidence.
  • Nothing is invented. Where the source captions cannot support a faithful translation — garbled live lyrics, chanting, noise — the span gets a music cue instead of fabricated words. Silence about the words, never invented words.

How a Job Runs

The pipeline has six stages, and the split between them is the point. Stages zero, one, three, four, and five are fully mechanical. Stage two — the correction itself — is agent judgment, deliberately.

python3 pipeline/perfectsrt.py checklist job/ python3 pipeline/perfectsrt.py repair job/ python3 pipeline/perfectsrt.py assemble job/ --out FINAL.srt

The tooling around stage two exists to make judgment complete and checkable: the interleaved view puts source and draft side by side, the checklist proves nothing was skipped silently, and the gates grade the result. The system never pretends a script can translate.

The Seven Gates

The assembler writes nothing when a gate fails. The gates, from the README:

A --force flag exists for emergencies and must be justified in the job log — a gate you can quietly override is not a gate. The validation report is the job's receipt: cue count, span, maximum duration, canonical-name counts, and the old draft's mangled-variant census. Any existing SRT can also be gated on its own with the validate command, without running a full job.

Two input rules matter as much as the code. Fetch the source-language caption track itself — never build on a platform's auto-translate caption endpoint, which rate-limits hard from datacenter IPs and produces exactly the class of draft this system exists to correct. And if you generate a machine draft, apply the names pack's source substitutions before translating, so names reach the translator already correct.

Where It Falls Short

The honest answer: perfect-srt is a disciplined workflow, not a product, and its limits are plain.

  • It is young and small. The repo was created on November 5, 2026, holds 16 commits, has no releases, and sits at zero stars as of November 11, 2026. It is a working system from my own subtitle jobs, not a community-tested tool.
  • There is no license file yet. The root of the repo has no LICENSE, so the code is public to read but carries no reuse terms. That needs fixing before anyone builds on it — including me telling you to.
  • Stage two needs a capable agent and a human ear. The gates catch shape, timing, and banned names. They cannot catch a translation that is grammatical, well-timed, and subtly wrong in tone. The checklist proves coverage, not taste.
  • Names packs are manual work. The reference pack covers one group properly. Every new artist means authoring a new pack of canonical spellings and known variants before the first job runs.
  • It fixes drafts; it does not create sources. If the source-language caption track itself is bad, the skeleton of truth is bent from the start.

The Verdict

perfect-srt earns its place in my stack for one reason: it treats subtitle quality as a verification problem instead of a generation problem. The correction can be creative; the shipping cannot. Seven gates, a coverage proof, and a names pack turn "the draft looked fine" into a receipt you can check.

It pairs naturally with the rest of the video toolkit here — the FFmpeg cheatsheet for the processing side, SupoClip for cutting long videos into captioned clips, and the full build list on the projects page.

---

Not affiliated with any broadcaster or artist. Sources: perfect-srt GitHub repository, including the worked example in its examples folder.

ansaribilal.com — technology, tested in public.