<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rahul Rao</title>
    <description>The latest articles on DEV Community by Rahul Rao (@rahulrao85).</description>
    <link>https://dev.to/rahulrao85</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4174645%2F353ee4af-acae-4ab8-ac53-2aae8249d8f5.png</url>
      <title>DEV Community: Rahul Rao</title>
      <link>https://dev.to/rahulrao85</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rahulrao85"/>
    <language>en</language>
    <item>
      <title>Zubaan: I dubbed my English Shorts into Hinglish (same face, same voice) with open models</title>
      <dc:creator>Rahul Rao</dc:creator>
      <pubDate>Fri, 16 Oct 2026 09:58:13 +0000</pubDate>
      <link>https://dev.to/rahulrao85/zubaan-i-dubbed-my-english-shorts-into-hinglish-same-face-same-voice-with-open-models-34jf</link>
      <guid>https://dev.to/rahulrao85/zubaan-i-dubbed-my-english-shorts-into-hinglish-same-face-same-voice-with-open-models-34jf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I run a small AI channel, &lt;a href="https://youtube.com/@groundedailab" rel="noopener noreferrer"&gt;Grounded AI Lab&lt;/a&gt;, for Indian viewers. On 11 October I switched it to Hinglish only, because that's how my audience actually talks. That left four finished English Shorts stuck on hold. Re-recording them meant another evening in front of the camera for videos that were already done.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Zubaan&lt;/strong&gt;. In Hindi, &lt;em&gt;zubaan&lt;/em&gt; means "tongue", and it also means "language". This tool changes both. You give it an English Short and get back the same Short in Hinglish, with my face, my voice, my lips moving to the new words, and Hinglish captions. The cards, cuts, music and sound effects all stay where they were.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who pays for this:&lt;/strong&gt; Indian creators, teachers and coaches who record in English and want the much bigger Hindi-speaking audience, without recording everything twice. Paid dubbing tools charge per minute of video. Writing &lt;em&gt;natural&lt;/em&gt; Hinglish (Roman-script Hindi with the English tech words left alone) is the hard part, and that's exactly the job I gave an open model.&lt;/p&gt;

&lt;p&gt;What I'd charge: &lt;strong&gt;₹99 per Short, or ₹1,499 a month for 20.&lt;/strong&gt; My cost per 70-second Short is under ₹1 of DigitalOcean inference plus about 1,000 characters of the creator's own voice-clone plan. The GPU work runs on a gaming card I already owned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Side by side: English original on the left, Hinglish dub on the right (with the Hinglish audio):&lt;/strong&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/Eh_l5wJd3Vs" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Same frame, same moment. Top: the English original. Bottom: Zubaan's Hinglish lip sync.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdorc8jimy76nd90fltq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdorc8jimy76nd90fltq1.png" alt="Before and after: English original on top, Hinglish lip sync below" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The finished Hinglish Short (unlisted demo):&lt;/strong&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/BbB2-YPP6-Q" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rahulrao85" rel="noopener noreferrer"&gt;
        rahulrao85
      &lt;/a&gt; / &lt;a href="https://github.com/rahulrao85/zubaan" rel="noopener noreferrer"&gt;
        zubaan
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Dub an English YouTube Short into Hinglish with the creator's own face and voice. Whisper + Gemma 4 on DigitalOcean + LatentSync.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Zubaan&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Zubaan&lt;/em&gt; (zu-baan) is Hindi for "tongue", and also for "language". This tool changes both.&lt;/p&gt;
&lt;p&gt;Turn an English YouTube Short into a Hinglish one, with the creator's own face and voice
Open models handle the transcript, translation and lip sync, and the only closed piece is the creator's voice clone.&lt;/p&gt;
&lt;p&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge, Week 2: Side Hustle&lt;/a&gt;
on Shorts from my channel &lt;a href="https://youtube.com/@groundedailab" rel="nofollow noopener noreferrer"&gt;Grounded AI Lab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/rahulrao85/zubaan/post/cover_2000x840.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frahulrao85%2Fzubaan%2FHEAD%2Fpost%2Fcover_2000x840.png" alt="English original vs Hinglish dub"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Pipeline&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Open?&lt;/th&gt;
&lt;th&gt;Runs on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;English speech → timed transcript&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github.com/SYSTRAN/faster-whisper" rel="noopener noreferrer"&gt;faster-whisper&lt;/a&gt; &lt;code&gt;small.en&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Open (MIT)&lt;/td&gt;
&lt;td&gt;Laptop CPU, 70 s of audio in ~31 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transcript → spoken Hinglish, line by line&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 4 31B&lt;/strong&gt; via DigitalOcean Serverless Inference&lt;/td&gt;
&lt;td&gt;Open weights (Apache 2.0)&lt;/td&gt;
&lt;td&gt;DigitalOcean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hinglish → creator's voice + word timings&lt;/td&gt;
&lt;td&gt;ElevenLabs voice clone (&lt;code&gt;eleven_v4&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Closed&lt;/td&gt;
&lt;td&gt;ElevenLabs API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Face video → lips that match the Hinglish&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/bytedance/LatentSync" rel="noopener noreferrer"&gt;LatentSync 1.5&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Open (Apache 2.0 code, OpenRAIL++ weights)&lt;/td&gt;
&lt;td&gt;RTX 3060 12 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rahulrao85/zubaan" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Five steps. Every one except the voice uses open software.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Where it runs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;English speech → timed transcript&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Whisper&lt;/strong&gt; (&lt;code&gt;faster-whisper&lt;/code&gt;, small.en)&lt;/td&gt;
&lt;td&gt;My laptop's CPU: 70 s of audio in 31 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transcript → spoken Hinglish&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 4 31B&lt;/strong&gt; on &lt;strong&gt;DigitalOcean Serverless Inference&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;DigitalOcean, 6 s per Short&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hinglish → my voice + word timings&lt;/td&gt;
&lt;td&gt;ElevenLabs voice clone&lt;/td&gt;
&lt;td&gt;ElevenLabs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Face → lips that match the Hinglish&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;LatentSync 1.5&lt;/strong&gt; (ByteDance)&lt;/td&gt;
&lt;td&gt;RTX 3060 12 GB, under WSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Re-render with Hinglish captions&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;HyperFrames&lt;/strong&gt; + ffmpeg&lt;/td&gt;
&lt;td&gt;My laptop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Picking the translator.&lt;/strong&gt; I gave the same transcript to four open models on DigitalOcean and compared the output line by line:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemma 4 31B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6.4 s&lt;/td&gt;
&lt;td&gt;Most natural, consistent "aap", fixed both mishearings. &lt;strong&gt;Picked.&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek V4 Pro&lt;/td&gt;
&lt;td&gt;25 s&lt;/td&gt;
&lt;td&gt;The punchiest lines ("Catch? Hai na ek catch."), but it switched between "aap" and "tum"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama 4 Maverick&lt;/td&gt;
&lt;td&gt;24 s&lt;/td&gt;
&lt;td&gt;Translated "catch" as &lt;em&gt;pakad&lt;/em&gt;, which nobody says&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen 3.5 397B&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Came back empty; I didn't chase it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The bug that taught me something.&lt;/strong&gt; Whisper heard "GPT-6 Astra" as "Astra 6" and the model name "Jev" as "Gev". Gemma then translated the mistakes faithfully. Hand-written hints worked for that one video only, so I looked for a source of truth that every video already has: &lt;strong&gt;its own on-screen text&lt;/strong&gt;. The composition has an overlay that says &lt;em&gt;"Try GPT-6 Astra without a subscription"&lt;/em&gt;. &lt;code&gt;dub.py&lt;/code&gt; now pulls every overlay card out of the composition and gives it to Gemma as the spelling authority. Both names came out right, and Gemma even added &lt;em&gt;"har mahine"&lt;/em&gt; (every month) from a card, where the transcript had only said "the list keeps changing".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing (version 2).&lt;/strong&gt; Hinglish runs 10–15% longer than English. My first render placed each line at its English start time, and it looked wrong: the face kept talking in the gaps where the dub had already finished. Now Whisper's word timestamps give the exact span where each English line was spoken, and each Hinglish line is stretched or squeezed (0.85–1.2×) to fill that span. Most lines now start and end within about 0.1 s of the original. Two Hinglish lines are so much shorter than the English that they finish early even at 0.85×, and there the lip-sync model keeps the mouth at rest. In the 6 pauses where both the dub and the original are silent, the video switches back to the original frames, so the face is quiet when the voice is quiet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mistake that cost me 48 minutes.&lt;/strong&gt; My machine already had LatentSync installed from an earlier experiment, and I assumed it was version 1.6 (512 px). I ran it with the 1.6 config, and it took 48 minutes for 6 seconds of video while my 12 GB card spilled into system RAM. Then it produced a mouth that looked like crumpled foil. While I was downloading the "real" 1.5 weights, I compared fingerprints: &lt;strong&gt;the installed file &lt;em&gt;was&lt;/em&gt; 1.5&lt;/strong&gt;, byte for byte. With the correct 256 px config, the same 6 seconds took 3.3 minutes and looked right.&lt;/p&gt;

&lt;p&gt;Then the full 70-second run was killed for running out of memory. LatentSync keeps every frame in RAM, about 12 MB per 1440×1920 frame, so 70 seconds needed around 20 GB on a 24 GB machine. &lt;code&gt;lipsync.sh&lt;/code&gt; now cuts the video into chunks of 16 seconds or less &lt;strong&gt;at the pauses between dubbed lines&lt;/strong&gt; (&lt;code&gt;dub.py&lt;/code&gt;'s timing plan already knows where they are), syncs each chunk and joins them, so no word gets split. The final 70-second Short took about 23 minutes on the RTX 3060, in 5 chunks, with no visible seams. Both lessons are comments in &lt;code&gt;lipsync.sh&lt;/code&gt;, so nobody else loses that hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I couldn't use.&lt;/strong&gt; I wanted to run the lip sync on a DigitalOcean GPU Droplet (RTX 4000 Ada, $0.76/h, enough for the sharper 1.6 model). My new account didn't have GPU access yet, and the limit request is still pending. So the GPU step runs locally for now, and the Droplet is the obvious next step for anyone without a gaming card.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Three things here wouldn't have worked with a closed API:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The fix lives in my pipeline, not in someone's roadmap.&lt;/strong&gt; The on-screen-glossary trick works because I control exactly what goes into the model and can swap models freely. When Gemma's first run regressed on a name, I changed the prompt and re-ran it for well under a rupee. With a closed dubbing product, I'd have filed a ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model choice is a 10-minute experiment.&lt;/strong&gt; DigitalOcean serves a dozen open-weight models behind one endpoint, so comparing four translators cost less than a cup of tea, and I picked on quality, not on whichever vendor I happened to be locked into.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The expensive part runs on hardware I already own.&lt;/strong&gt; Lip sync is the GPU-heavy step, and an open model meant it ran free on my gaming card. A per-minute service would make this side hustle's margins depend on someone else's pricing page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Being honest about the one closed piece: &lt;strong&gt;the voice.&lt;/strong&gt; I kept the ElevenLabs clone my channel already uses, because my audience knows that voice. Testing an open voice-cloning model on Hinglish is the next experiment, and the voice step is a single function, so swapping it out is a small change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On consent:&lt;/strong&gt; the tool is built to dub &lt;em&gt;your own&lt;/em&gt; face and voice. The voice comes from your own clone, and lip sync only runs on footage you supply. The output gets YouTube's "altered or synthetic content" label, as it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Known Limitations
&lt;/h2&gt;

&lt;p&gt;I watched the first full render and didn't like it, so here's what's still wrong, from worst to least bad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The body still speaks English.&lt;/strong&gt; Lip sync only redraws the mouth and jaw. Head nods, eyebrows and hand gestures keep the rhythm of the original English sentences. Version 2's timing fix (above) removed the worst of it, the mouth moving with no voice, but a dubbed face is never as natural as a re-recorded one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The mouth is a little soft.&lt;/strong&gt; LatentSync 1.5 works at 256 px. The 512 px model (1.6) needs an 18 GB GPU, which is exactly what the DigitalOcean GPU Droplet was for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;English names in a Hindi voice.&lt;/strong&gt; A Hinglish voice may read "Astra" as the Hindi word &lt;em&gt;astra&lt;/em&gt; (weapon). Zubaan takes voice-only respellings (&lt;code&gt;--say "Astra=Ass-truh"&lt;/code&gt;) while the captions keep the real spelling. I listened to three versions and kept the plain spelling: in a Hinglish sentence, that is how my audience would say it anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where it works best:&lt;/strong&gt; Shorts where cards and screen recordings cover most of the face. For face-to-camera Shorts, my honest advice to creators is still to re-record, and to use Zubaan for the back catalogue they never would have.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;Me, as a creator, and I'm being strict about it. After watching version 1, I decided &lt;strong&gt;not&lt;/strong&gt; to publish the dubbed GAL-012 on the channel. For a face-to-camera Short, re-recording still looks better (see Known Limitations). Where Zubaan earns its place is my held English Shorts that are mostly cards and screen recordings, and that's where it goes next. Nobody has paid yet. The next test is whether a creator friend who records in English will pay ₹99 for one of theirs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of DigitalOcean&lt;/strong&gt;: Gemma 4 runs on DigitalOcean Serverless Inference as the translation core, and four open models were compared on the same endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;: Gemma 4 31B writes all the Hinglish, using the on-screen-glossary technique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs&lt;/strong&gt;: my ElevenLabs voice clone speaks the Hinglish, and its word-level timestamps drive the captions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code and post drafted with AI assistance (Claude Code); all results, numbers and design decisions reviewed by me.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
