No black box. Every stage below says what it does, which service runs it, roughly how long it takes and where it falls over. If you are weighing us against building this yourself, this is the honest version of that comparison.
Roughly fifteen minutes end to end. Transcription dominates and everything else is cheap by comparison.
Indicative timings for a 120-minute film into three languages. Upload overlaps with nothing else; the rest runs in sequence.
Click through them. Every one is here because skipping it produces a subtitle track a native speaker will reject.
Your browser slices the file into 5 MB pieces and posts them one at a time, so a multi-gigabyte master uploads reliably and a dropped connection resumes instead of starting over. While that happens, the browser also reads the runtime straight out of the container — which is how the exact cost appears before you have committed to anything.
Nothing is re-encoded. The picture is never touched, because nothing we do modifies it. The file sits in temporary storage under a random name and is deleted the moment the transcript comes back.
Chunked upload · 5 MB pieces · runtime read client-side · media deleted within minutes
What we need back is not a paragraph of text — it is a timestamp for every individual word plus a speaker identifier for every utterance. Sentence-level timing is not precise enough to build cues from; you end up guessing where inside a five-second block a phrase actually fell.
Our recogniser reads the audio track straight out of your container. No demux, no transcode, no audio extraction step anywhere. Long files are split internally and worked on in parallel, which is why a two-hour feature does not take two hours to transcribe.
Word-level timestamps · speaker separation up to 32 voices · runs once per job, not once per language
A flat list of timed words is not yet dialogue. We group them into segments that end on sentence-final punctuation, on a change of speaker, on a pause longer than nine-tenths of a second, or once a line gets too long to be one cue.
These segments are the unit everything downstream works with. Getting the boundaries right here is what stops a translated line from straddling two people's dialogue.
Break on: sentence end · speaker change · pause > 0.9 s · 140 characters
Diarization returns anonymous labels — speaker 0, speaker 1, speaker 2. On its own that is nearly useless. What the translation stage needs is to know that speaker 1 is a woman speaking informally to a colleague and formally to her employer.
Speaker ids travel with every line into the translation prompt. Skip this and every gendered language in your target list starts guessing: in Hebrew the verb form, the pronoun and the adjective all come out wrong together, in the same line, and a native speaker spots it instantly.
Speaker ids attached per segment · carried into every translation call
The obvious approach is to translate each subtitle line on its own, because that keeps timing aligned. It also strips out every piece of context that makes translation work. A line like "I told her" carries no information about who "her" is, how formal the speaker is being, or whether this is a callback to two scenes ago.
Instead, forty segments go over at a time with their speaker ids attached, plus the tail of the previous block as context so pronouns and register carry across the seam. Line boundaries are preserved, so timing stays intact while the model gets everything it needs.
40 segments per pass · 4-line context overlap · line ids preserved end to end
Translated text is almost never the same length as the source. Hebrew tends to run shorter than English; German and Hindi run longer. Drop a translation onto the original timings unchanged and half your cues become unreadable.
So the text is re-cut against hard limits: 17 characters per second, one to seven seconds on screen, two lines of 42 characters split near the middle at a word boundary, and 80 milliseconds of clear air between consecutive cues. Anything still over the limit after all that is flagged rather than quietly shipped.
17 cps · 1–7 s · 2 × 42 chars · 80 ms gap · over-limit cues flagged
The conformed cue list is format-agnostic internally, so writing WebVTT, SRT or a plain transcript is a serialisation step rather than a separate job. That is why re-exporting a title you have already processed costs nothing.
Right-to-left languages get their direction settings written into the VTT cues, and the SRT output carries a UTF-8 byte order mark with RLM marks per line. Both of those exist because players get this wrong otherwise.
WebVTT · SRT with BOM · plain transcript · re-export always free
Recognition and translation are the parts everyone talks about. Conformance is the part that decides whether the output is publishable or merely plausible, and it is the part we built.
Part 01
Reads the audio track out of your video without touching the picture. Returns a timestamp for every individual word and separates the voices, so cues can be built from real timing rather than guessed from paragraph blocks. It runs once per job however many languages you order.
90+ source languages · word-level timing · up to 32 voices separated
Part 02
Turns a flat list of timed words into dialogue. Segments break on sentence-final punctuation, on a change of speaker, on a pause longer than nine tenths of a second, and once a line grows past what one cue can carry. Getting these boundaries right is what stops a translated line from straddling two people talking.
Sentence end · speaker change · pause > 0.9 s · 140 characters
Part 03
Forty segments go across at a time with their speaker labels attached, plus the tail of the previous block so pronouns and formality carry over the seam. Line boundaries survive intact, which keeps timing aligned while the translation still gets the context it needs to resolve gender and register.
Scene-sized blocks · speaker context · 4-line overlap · ids preserved
Part 04
Cue cutting, reading-speed enforcement, line breaking at clause boundaries, bidirectional isolation for right-to-left scripts, confidence scoring and format writing. This is the part with no shortcut available, and the reason the same transcript produces a usable track here and an unusable one elsewhere.
17 cps · 1–7 s · 2 × 42 chars · 80 ms gap · flagged when it still will not fit
Recognition is the expensive step and it only needs to happen once. Ordering five languages runs one recognition pass and five translation passes, not five of each. That is also why the timing is byte for byte identical across every language you order — which matters the moment a viewer switches tracks mid-scene and expects the subtitles to stay where they were.
Flagged cues exceeded the reading-speed limit and are worth a look before publishing. Everything else conformed cleanly.
What lands in your dashboard when a job finishes: cue counts, flag counts and every format, per language.
These are not preferences. They come out of decades of broadcast practice and eye tracking, and breaking them is what makes machine subtitles feel wrong even when every word is correct.
CHARACTERS / SEC
17
Above this a viewer cannot finish the line before it goes. Broadcast work often tightens to 15.
LINE LENGTH
42
Characters per line, two lines maximum. Never three — the eye leaves the picture entirely.
DURATION
1–7s
Under a second reads as a flash. Over seven and the viewer thinks the track has frozen.
GAP
80ms
Clear air between cues, so the eye registers that the text changed rather than seeing a smear.
First we try extending the cue into whatever silence follows it. If there is none, the text is split across two cues and the time divided proportionally. If it still exceeds the limit after that — which happens with dense, fast dialogue — the cue is flagged rather than silently shipped.
Typical flag rates: three to six percent on interviews and lectures, ten to fifteen percent on feature films with a score under the dialogue. You see the number per language before you download anything.
This is the chart most vendors will not show you. Recognition quality tracks the mix, not the market.
Indicative word accuracy by content type, on clean source audio. These are the shapes we see, not a guarantee for your material — which is why every cue carries its own confidence score and a few dollars buys you the real number for your own catalogue.
Exact runtime is not known until the file is processed, but nobody should process before being paid. So the wallet holds an estimate and reconciles it afterwards.
Straight from the file's own metadata, before a single byte uploads. The cost appears live as you pick languages.
Debited from the wallet with a ledger row marked hold. Nothing is spent yet in the sense that matters — it is reserved.
We take whichever is larger: what your browser reported, or where speech actually ends. Never silently under-bill, never invent length either.
Shorter than estimated, you get the difference back. Longer, the balance is charged. Either way it shows in the ledger with the balance after it.
A failed or cancelled job releases the whole hold automatically. There is no dispute process because there is nothing to dispute.
Long jobs on ordinary infrastructure fail in predictable ways. Each of these was a design decision, not an afterthought.
Chunks are appended at a known offset. A dropped connection picks up from the last confirmed piece rather than restarting a 2 GB transfer.
Translation happens one block at a time and the position is saved after each. A job interrupted at block 180 of 270 continues at 181.
A job being worked on carries a timestamp lock. If a worker dies mid-run, the job frees itself after five minutes instead of sticking forever.
If a translation pass fails for Tamil, the other five still deliver. You are billed only for the ones that produced files.
If the translation model skips an id, that cue falls back to the source text rather than leaving a silent hole in the middle of a scene.
Every wallet movement stores the balance after it. You can audit the whole account by reading down one column.
Most vendor pages end with a triumph section. You will hit these in week two anyway, so you may as well hear them from us first.
Plenty of teams try, and the running cost genuinely is small. That is not the part that costs you.
| Approach | Per hour, per language | Time to first output | What you are actually buying |
|---|---|---|---|
| Vidora Labs | $4.00 first hour, then $1.00 / 15 minutes | Minutes | The conformance engine, the resumability, and someone else's problem when a vendor changes an endpoint. |
| Roll your own on raw APIs | ~$0.50 in API spend | Weeks to months | A file. Turning that into publishable subtitles is the work, and it is most of the work. |
| Freelance subtitler | $60 – $120 | 2 – 5 days | Genuine craft. Worth it on your flagship title, impossible across a catalogue. |
| Subtitling house | $150 – $400 | 3 – 10 days | Deliverable specs, QC sign-off and someone to sue. Real value for prestige releases. |
Our honest recommendation: machine pass for the catalogue, a human for the two or three titles that carry your brand. That mix is what most of our customers settle on.
No. The picture is never touched. The transcription service reads the audio track out of your container directly, so there is no demux, no transcode and no quality loss anywhere in the chain. What you get back is a text file that sits alongside your existing encode.
Because transcription is the expensive step and it only needs to happen once. Ordering five languages runs one transcription and five translation passes, not five of each. It also means the timing is identical across every language you order, which matters if a viewer switches tracks mid-scene.
Not through the interface yet. This is the single highest-value thing on our list, because feeding character names and their grammatical gender into the translation prompt improves Hebrew, Arabic, Hindi and Spanish output sharply. If you have a series where this matters, contact us — we will wire it for you by hand in the meantime.
The job fails with a clear message and the hold is released in full. You are not billed for a silent file.
Not published yet. The application is built on one internally, so exposing it is a documentation problem more than an engineering one. If you would integrate against it, tell us — that is what moves it up the list.
The default is 17 characters per second, which suits streaming. Broadcast deliverables often require 15, and some accessibility specs are tighter still. Ask and we will set the profile on your account.
Create an account, top up the wallet, and process a title you actually care about. A feature film in two languages costs about $16.00, so you can judge the output on real material rather than on a demo clip.