{"slug": "translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one", "title": "Translating any podcast episode for about a dollar: the architecture, and the one rule that shaped it", "summary": "A developer built a pipeline that translates podcast episodes into other languages for about a dollar per episode, using the podcaster's own published transcript rather than speech-to-text to avoid compounding errors. The system, which reuses an existing AI-narrated audiobook architecture, only works on episodes that provide a transcript, ensuring accuracy and trust.", "body_md": "A friend of mine doesn't speak English. I do most of my podcast listening in English. Every so often I hit an episode worth passing on — an interview, some strange little history segment — and I want to send it to her, and I can't. A summary isn't the episode. A translated transcript isn't something you listen to on a walk.\n\nIt turned out I'd been sitting on the pieces to fix this for months. This is the architecture I landed on, and the one design rule that shaped everything else. No code — just the shape of the thing and the decisions that mattered.\n\nI'm building a personal audio library as a side project. One thing already shipped was **AI-narrated audiobooks**: take a manuscript, translate it if needed, run it through a neural text-to-speech voice, stitch the result into a real audio file. Two managed services doing the heavy lifting — machine translation on one side, neural TTS on the other — with my own orchestration in between.\n\nA podcast episode is, structurally, **a much shorter audiobook**. That's the whole thing. I didn't need to build \"podcast translation.\" I needed to point a pipeline I'd already written at a different kind of input.\n\nThat reframing is the most useful architectural move I know: before building a feature, check whether it's a new *shape* or just a new *input* to a shape you already have. This was the second.\n\n```\n Podcast RSS feed\n      │\n      ▼\n Find <podcast:transcript>  ──►  no transcript?  ──►  feature not offered\n      │                                                (hard stop — see below)\n      ▼\n Fetch the podcaster's own transcript text\n      │\n      ▼\n Machine translation  (per-character, managed service)\n      │\n      ▼\n Neural TTS  (per-character, managed voice)\n      │\n      ▼\n Stitch → single playable audio file\n      │\n      ▼\n Store in the requester's own library (household-scoped)\n```\n\nEverything interesting is in two places: the **hard stop** near the top, and the **scope** at the bottom.\n\nThe obvious architecture is: transcribe the audio with speech-to-text, translate that, narrate the result. I deliberately did **not** do that, and it's the single decision I actually agonized over.\n\nSpeech-to-text makes mistakes, and translation **compounds** them. A mis-heard word becomes a mistranslated sentence becomes a confidently narrated line that is simply wrong — with nothing in the output pointing back at where it broke. For a toy, that's an annoyance. For something a person might rely on to understand what someone actually said, it's a trust problem, and it gets worse the more the feature is used.\n\nSo the rule is: **this only works on episodes that publish a transcript.** Podcasting 2.0 added a `<podcast:transcript>`\n\ntag to the RSS spec a few years ago, and a meaningful and growing minority of shows already attach one. If a transcript exists, I translate the podcaster's *own published words*. If it doesn't, the feature isn't offered for that episode. No guessing, ever.\n\nArchitecturally this is a **quality gate placed at the input, not the output.** Instead of building elaborate confidence-scoring and error-handling downstream to cope with bad STT, I refuse the bad input at the door. The system can only be asked to do the thing it can do well. That single constraint deleted an entire category of downstream complexity — and it's why I trust the output enough to ship it.\n\nManaged translation and TTS both bill per character, so the unit economics are legible: cost is translation-per-character plus narration-per-character, marked up enough to be sustainable, and **capped so it never exceeds the up-front quote.**\n\nA real measurement, not a round marketing number: one episode of a (faintly ridiculous) British royal-gossip podcast that happened to be in my test feed — 8,570 characters of transcript, English to German — landed at **90 cents**. A typical 5–15 minute episode comes out around a dollar.\n\nThe architectural point: because the price is derived from the transcript length *before* any paid API call runs, I can **show the user the exact cost and get consent before spending anything.** No surprise bills, no \"estimated.\" The quote is the cap.\n\nI timed it from the database row's own timestamps rather than a stopwatch, because I wanted a number I could stand behind: a **9-minute episode, translated, narrated, and assembled into a playable file, in 93 seconds.**\n\nThat number changes the UX category. At 93 seconds, \"translate this episode\" stops being a batch job you plan around and becomes something you kick off while still looking at the episode list.\n\nTwo scope decisions are deliberately baked into the architecture:\n\nThat personal scope isn't a limitation I'm apologizing for; it's the line that makes the feature defensible to build at all.\n\nFour things generalize well beyond this:\n\nThe result is what I've started calling an **80% solution, on purpose**: one voice, transcript-only, personal-scope. If the alternative is *not understanding the episode at all*, 80% is a genuinely good outcome — and it's the difference between hearing something today and never hearing it, because nobody commissions a real translation for one podcast episode.\n\n*I write about building own.audio, a personal library for audiobooks, music, and podcasts you actually own. It's a pre-launch side project; the fuller write-up of this feature, with screenshots, is on the blog. The product-design side of this same decision — why shipping something deliberately imperfect was the right call — is a separate piece.*", "url": "https://wpnews.pro/news/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one", "canonical_source": "https://dev.to/kornel_maraz_5e66a3e4e27d/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one-rule-that-shaped-81a", "published_at": "2026-09-03 17:05:15+00:00", "updated_at": "2026-09-03 17:25:23.145326+00:00", "lang": "en", "topics": ["machine-learning", "natural-language-processing", "ai-products", "ai-tools", "developer-tools"], "entities": ["Podcasting 2.0"], "alternates": {"html": "https://wpnews.pro/news/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one", "markdown": "https://wpnews.pro/news/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one.md", "text": "https://wpnews.pro/news/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one.txt", "jsonld": "https://wpnews.pro/news/translating-any-podcast-episode-for-about-a-dollar-the-architecture-and-the-one.jsonld"}}