Twenty languages in two days. Zero lines written by hand.

It started with a 64-minute guide on YouTube. Today, it exists in 20 languages beyond Johan's English original. Switch tracks, and you will hear his own cloned voice speaking fluent Thai, Farsi, or German — in exact sync with what happens on screen. The result is 21 hours of finished audio, and the whole job took two days.

The problem was that there was no off-the-shelf product to do this. Dubbing services exist, but none of them reads the script with a specific voice, cuts it in exactly according to the subtitle timecodes, and lets us control every single line. So we had to build the machinery from scratch. Day one, GPT-5.6 in Codex wrote the first version. Day two, we had Anthropic Fable 5 in Claude Code debug and rebuild it all, after viewers had reached out with feedback. This is the story of how we solved the puzzle, and what happened when things didn't sound the way they should.

Dubbed languages
20
Movie, per language
64 min
Speech takes generated
12,550
Finished dubbed audio
21 h
Start to upload
2 days
Lines written by hand
0

02

Block by block becomes gibberish

The first problem had nothing to do with the audio. The subtitles were already translated, but they had been processed the way subtitles usually are: by machine, block by block. When GPT-5.6 scanned the text ahead of the dubbing, the Farsi version got a red light. It simply was not good enough to read. When we looked closer, we saw the same pattern everywhere.

A subtitle block is just what fits on the screen in the moment, not a complete thought. Of the movie's 580 block boundaries, 457 cut the text in the middle of a sentence. Translating them in isolation was asking for trouble. In the German track, for example, there was a block that ended with the word "To". The machine translated it straight to "Um", only to repeat it in the next block. The two German blocks even managed to flip from the informal "du" to the formal "Sie" — because they had no connection to each other.

Language after language had the same damage: dangling clauses, half product names, and in the worst cases, sentences that said the exact opposite of the original.

The German installation passage in three versions: the English source, the block-by-block translation, and the new whole-sentence translation.
The German installation passage in three versions: the English source, the block-by-block translation, and the new whole-sentence translation.

Twenty translations had to be torn down and redone. Putting a human voice on a broken script would only make the error painfully obvious.

03

Forty agents and a shared glossary

So we stepped out of the language and into the structure. We had a script read the 580 English blocks and melt them down into 106 whole sentences. Each sentence was tagged with the right chapter and a blocklist for words that could not be touched. A central glossary kept order: Obsidian's "vault" is a workspace in the app, not a bank vault. Menus and buttons like "Settings", "Restricted mode", and "Browse" should be called exactly what was on screen, regardless of language.

Then we spun up one translator agent per language. The instructions were precise, down to pronouns: Brazilian Portuguese had to use "você", European Portuguese "tu", and Ukrainian the formal "ви". The agents translated sentence by sentence in full context, and then cut the text back across the original block boundaries.

Right after, a reviewer agent stepped in. It compared the new, split subtitles with the English source, line by line. A script monitored the timecodes and made sure the text length was right: 50 characters for a Latin line, 32 for Japanese, and only 24 for Chinese.

What the twenty reviewers corrected, per language.
What the twenty reviewers corrected, per language.

When the dust settled, the reviewers had logged 2,531 corrections. Seven out of ten were about segmentation — moving the actual break point so the viewer gets to pause their breath where the language demands it. French and German got the most changes because they were used as testbeds. Farsi got its very own extra round in full context to straighten out the mess from the start.

Only when a total of 11,600 blocks passed the tests without a single warning, did we push the button for the audio.

04

One script for the eye, one for the ear

Now we faced a choice that came to shape the rest of the process. We had to separate the text the viewer sees from the text the voice reads.

Subtitles are written language. If Johan types "Tags", "Ctrl+1", or "/*" in the movie, it has to say so in the text. But if you feed "/*" into a voice model, it usually goes completely silent. "Ctrl" risks being spelled out letter by letter. That is why we added a separate spoken script parallel to the subtitles for all twenty languages. In that layer, the fragments were merged into whole sentences, locked to the timecodes, and rewritten phonetically.

The same lines from the German release in both layers.
The same lines from the German release in both layers.

The rule was strictly set: if the translation was wrong, we fixed both layers. If it just sounded strange, we changed the pronunciation in the spoken layer. The viewer sees "Tags". The voice reads "Täggs".

05

The machinery behind the voice

The audio came from ElevenLabs' multilingual model, fed with Johan's cloned voice. Around it, we built a pipeline in Python that sent one API call per line and then cached the audio file based on a unique hash of the text and settings.

The pipeline from subtitles to finished tracks. The orange loop shows that a text edit only regenerates the lines that were affected.
The pipeline from subtitles to finished tracks. The orange loop shows that a text edit only regenerates the lines that were affected.

That cache was crucial. If the credit balance ran out in the middle of a generation, the system froze, ready to pick up the thread again as soon as the card was charged. And if we later discovered that a single sentence sounded wrong, we could correct it and just ask for that specific audio clip again, along with its neighbors so the tone matched at the seams. Without that detailed control, the project would never have been completed in two days.

Finally, a renderer took over. It stacked the lines on the movie's timeline, measured and compared against the publication. Out came a crash report for each track: exact length, deviations against the subtitle start times, warnings about clips that risked clipping, and pure audio levels. We did not compromise; every language went through the exact same check.

06

"A sleepy robot from Quebec"

When the first version went live, it did not take long for the verdict to fall.

"It's just impossible for me to listen to. It sounds like a bored or sleepy robot speaking Quebec French," a French viewer wrote.

A German viewer added: "German works surprisingly well. Grammar is correct and pronunciation is only slightly wooden."

Both comments caught the exact same problem. English is compact, so when the text is translated, the line often takes significantly less time to read. Our first version solved the gap by simply stretching the generated voice in software until it reached the edge of the subtitle window.

Measured from the render reports of the first version: every language was played slower than natural speech.
Measured from the render reports of the first version: every language was played slower than natural speech.

The numbers spoke clearly. French was played at 82 percent of its normal speed. For Thai, the situation was extreme — 0.65×. A third of everything said in the entire movie was literally in slow motion.

BEFORE · 0.82×
The movie's opening in French in the first version: all speech is stretched until it fills the windows.
AFTER · natural pace
The same opening after re-rendering: natural speed, real pauses, and a faint room tone under the silences.

07

The fix: the air goes between the words

The error was obvious: we put the time gap in the wrong place. The extra time should not be stretched over the vowels, it should be in the pauses.

We fired up Anthropic Fable 5 in Claude Code to rewrite the renderer. In the new version, the speech was locked exactly at the time the subtitle required. The speed was allowed to slow down by a maximum of five percent, which the ear barely perceives. The rest of the time was squeezed in where we humans actually rest — at periods, commas, and colons. And since ElevenLabs delivers character-level timestamps, we could place the pauses exactly right.

A real line from the French dub: 1.28 seconds of voice is missing, and the time gap is distributed across the line's four punctuation marks instead of being stretched over the vowels.
A real line from the French dub: 1.28 seconds of voice is missing, and the time gap is distributed across the line's four punctuation marks instead of being stretched over the vowels.

If there was still time left over, it was left as pure silence, usually where the original movie also took a pause to show something on screen. So the silence would not turn off the mood in the room, a faint pink noise was embedded as room tone.

The same 75 seconds of the French dub before and after. The gap in the middle is a demo passage where the original is also silent.
The same 75 seconds of the French dub before and after. The gap in the middle is a demo passage where the original is also silent.

Thanks to the caching system, we could throw the entire re-rendering of the 20 languages at existing audio files. The update did not require a single new API call to the voice model.

08

False friends strike

The German viewer left one more comment, though. It was about the word "tags". Sometimes the model stumbled and pronounced it in English, sometimes as the German word for day — "Tag". Same spelling, two completely different pronunciations.

BEFORE · "Tag"
The German line about the "50 mm" tag, recreated with the same settings as the first version: the model reads "Tag" as the German word for day.
AFTER · "Tägg"
The same line with the phonetic respelling in the spoken layer: now it sounds like the English tag, consistently.

There were more potholes in the road. In a chapter about hiding folders, Johan clicks in the characters "/_*" and reads them out loud. The German voice saw shapeless symbols and skipped them completely.

BEFORE · silent
"Ich gebe ein": the voice model skips the characters entirely.
AFTER · spoken
"Ich gebe Schrägstrich, Unterstrich, Sternchen ein": the characters are written out as words in the spoken layer.

We looked at ElevenLabs' built-in pronunciation dictionaries, but the documentation showed that the multilingual model ignores phonetic rules. A global automatic replacement, always forcing a German "Tägg", lacks context. Then the model would suddenly have talked about "Tägg" even when it read out a date. The only way forward was to adjust the pronunciation by hand in the text layer, line by line.

False friends the audit later found in other languages: Italian pane is bread, French panne is a breakdown, Polish notes is a notepad.
False friends the audit later found in other languages: Italian pane is bread, French panne is a breakdown, Polish notes is a notepad.

09

Auditing languages you do not understand

The suspicion was raised immediately: if German had this problem, what was hiding in the other languages? Since none of us speak Thai, Ukrainian, or Farsi, we turned to the agents again. Four auditors got to plow through all twenty spoken scripts in search of mispronunciations, linguistic collisions, and errors that had been inherited in the translations.

The net was tight. The agents found that "Ctrl" was spelled out pretty much everywhere. The number "15,000" was pronounced as "fifteen point zero" in languages where the comma stands for decimals. The slash in "/Journal" was forgotten. Thai was missing spaces in 66 lines where Latin script broke off. In Turkish, ordinal numbers had been cut right in half by the block boundaries. And four different languages had stiffly translated the word "funny" into "comical", instead of "fun".

The repair round per language. German tops with the Tägg-respelling.
The repair round per language. German tops with the Tägg-respelling.

The corrections were made in a single batch: 966 lines were regenerated and the timelines were rendered again. Every single respelling resulted in a separate little audio clip for our manual review.

10

The tally: two days in numbers

Here is what the effort looked like. Day one: the subtitles were translated from scratch by forty agents. GPT-5.6 in Codex wrote the entire dubbing pipeline, the voice was cloned, and 20 languages were generated. Day two: the viewers gave feedback. Anthropic Fable 5 in Claude Code rebuilt the renderer to distribute the air in pauses instead of stretching the sound. Four agents vacuumed the spoken scripts, and then the corrected lines were generated.

The end result is 20 audio tracks and just over 21 hours of speech. Each track is 64 minutes and 15 seconds long. The tracks are baked into the published movie on YouTube, which itself chooses the track based on the viewer's native language. As a bonus, the English got a run-through: 33 small grammar errors in the English original were found and fixed, as well as all the knock-on errors they had created in twelve of the languages.

And the "bored" French robot voice? It sounded completely normal once it was played back at the intended speed. What was perceived as a voice problem was really just a math problem.

11

Proof of the technology

In the end, the project proved one thing. Agentic workflows deliver in production. And they do it even when you are dealing with audio, exact timelines, and twenty languages that nobody on the team understands.

The method worked because it is built on machine-monitored acceptance criteria for length, sync, pronunciation, and terminology. The audio is cached systematically so that a change only costs API money for the exact lines being rewritten. The AI agents do the heavy lifting and audit the volume, but a human always makes the final decisions.

The machinery is driven by standard components: subtitle files, an API for voice generation, tools like ffmpeg, attention to detail, and AI models that wrote the code. That is the kind of workflow we at TokenTek build and automate.

Want to apply the method to your content?

We use exactly the same approach when we build production systems for our clients: a clear direction, agents pulling the heavy load during development, and quality criteria that are consistently tracked. Get in touch, and we will discuss what it could mean for you.