<?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: navidseyedain</title>
    <description>The latest articles on DEV Community by navidseyedain (@navidseyedain).</description>
    <link>https://dev.to/navidseyedain</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%2F4049707%2Fbaf1909b-52bd-4694-a6a3-b53aa279fa5e.jpg</url>
      <title>DEV Community: navidseyedain</title>
      <link>https://dev.to/navidseyedain</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/navidseyedain"/>
    <language>en</language>
    <item>
      <title>How I Built an In-Place Android Screen Translator with Jetpack Compose, ML Kit, and Gemini Vision</title>
      <dc:creator>navidseyedain</dc:creator>
      <pubDate>Sat, 29 Aug 2026 13:29:23 +0000</pubDate>
      <link>https://dev.to/navidseyedain/how-i-built-an-in-place-android-screen-translator-with-jetpack-compose-ml-kit-and-gemini-vision-1667</link>
      <guid>https://dev.to/navidseyedain/how-i-built-an-in-place-android-screen-translator-with-jetpack-compose-ml-kit-and-gemini-vision-1667</guid>
      <description>&lt;p&gt;Language barriers in mobile apps, games, and foreign media are a constant friction point. Traditional screen translation tools on Android usually force users to take manual screenshots, freeze the screen, jump between applications, or deal with rigid line-by-line OCR card overlays that block the view.&lt;br&gt;
​To solve this, I built ALST (AI Live Screen Translation) — an open-source, real-time Android screen translator that translates any screen content in-place and renders the translated text directly over the original screen coordinates without ever leaving your active app.&lt;br&gt;
​In this article, I'll walk through the system architecture, how I integrated Gemini 3.6 Flash for single-pass vision translation, and how to prevent memory leaks during continuous high-density screen capturing in Android 14+.&lt;br&gt;
​🏗️ High-Level System Architecture&lt;br&gt;
​ALST is built following Clean Architecture and MVVM/MVI design patterns. The codebase is strictly partitioned into single-responsibility modules:&lt;br&gt;
​core/capture: MediaProjection, VirtualDisplay, &amp;amp; ImageReader pipeline&lt;br&gt;
​core/ocr: Google ML Kit Text Recognition v2 engine&lt;br&gt;
​core/translator: Dual translation engine (ML Kit On-Device + Gemini Flash)&lt;br&gt;
​core/overlay: WindowManager floating views &amp;amp; Compose Canvas rendering&lt;br&gt;
​service: ScreenTranslatorService (Foreground) &amp;amp; QSTranslateTileService&lt;br&gt;
​data: Jetpack DataStore preferences (BYOK API keys, language options)&lt;br&gt;
​ui: Material 3 Glassmorphic Dashboard &amp;amp; Overlay UI&lt;br&gt;
​🧠 1. Single-Pass Vision AI vs. Traditional Chaining&lt;br&gt;
​In conventional translation tools, the pipeline is split into three heavy steps:&lt;br&gt;
​Capture screen frame -&amp;gt; Run local OCR -&amp;gt; Extract text blocks &amp;amp; coordinates.&lt;br&gt;
​Send extracted raw text to a Translation API -&amp;gt; Receive translated strings.&lt;br&gt;
​Draw text cards over the screen.&lt;br&gt;
​While this works, it often loses contextual meaning (e.g., in video games, manga, or slang-heavy social posts).&lt;br&gt;
​With ALST, when running in Cloud AI Mode, the app uses Google's Gemini 3.6 Flash Multimodal Vision API:&lt;br&gt;
​Raw bitmap frame buffers are sent directly to the model.&lt;br&gt;
​In a single pass, Gemini extracts the text, understands local context/idioms, and returns both the translated text and exact bounding box coordinates (Rect).&lt;br&gt;
​This dramatically improves translation quality and contextual awareness while reducing pipeline complexity.&lt;br&gt;
​📴 2. Dual-Engine Architecture (Cloud + 100% Offline)&lt;br&gt;
​Recognizing that users aren't always connected to high-speed internet, ALST implements a flexible Dual-Engine System:&lt;br&gt;
​Cloud Engine (Gemini 3.6 Flash): Uses the com.google.ai.client.generativeai SDK with a Bring-Your-Own-Key (BYOK) model for deep contextual translation.&lt;br&gt;
​On-Device Engine (Google ML Kit): Combines ML Kit Text Recognition v2 with ML Kit On-Device Translation. It operates 100% offline with sub-50ms latency and zero server dependencies.&lt;br&gt;
​Users can toggle seamlessly between these two engines inside the app dashboard, persisted via Jetpack DataStore Preferences.&lt;br&gt;
​🔋 3. Zero-Leak Memory Engineering in Android 14+&lt;br&gt;
​Capturing raw 1440p / 4K screen frames produces bitmaps that consume over 15MB–20MB of RAM per frame. Doing this continuously using MediaProjection and ImageReader quickly leads to OutOfMemoryError (OOM) crashes if buffer recycling isn't managed strictly.&lt;br&gt;
​Here is how ALST handles zero-leak memory management inside ScreenCaptureManager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;captureSingleFrame&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imageReader&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;acquireLatestImage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="nd"&gt;@withContext&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;planes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;planes&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;buffer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;planes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pixelStride&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;planes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pixelStride&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;rowStride&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;planes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;rowStride&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;rowPadding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rowStride&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;pixelStride&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;screenWidth&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;bitmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;screenWidth&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rowPadding&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pixelStride&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;screenHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ARGB_8888&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copyPixelsFromBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;screenWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;screenHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// CRITICAL: Always close the image buffer immediately to return it to VirtualDisplay&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎯 4. In-Place Overlay &amp;amp; Spatial Coordinate Mapping&lt;br&gt;
​To render translated text boxes directly over original text without distorting the layout:&lt;br&gt;
​ALST creates a dynamic WindowManager view of type TYPE_APPLICATION_OVERLAY.&lt;br&gt;
​Coordinates returned from OCR/Gemini are scaled against physical screen density (DisplayMetrics) and system navigation/notch insets.&lt;br&gt;
​Using Jetpack Compose Canvas, dark translucent glassmorphic cards with rounded corners are drawn exactly over original bounding boxes, placing high-contrast translated text right where your eyes expect it.&lt;br&gt;
​📱 5. Deep System Integration&lt;br&gt;
​ALST integrates directly into Android system controls for maximum convenience:&lt;br&gt;
​Draggable Floating Action Button (FAB): A frosted overlay button with magnetic screen-edge snapping.&lt;br&gt;
​Quick Settings Tile (TileService): Allows users to trigger screen translation directly from the Android status bar pull-down menu.&lt;br&gt;
​Android 14/15 Compliance: Runs via a Foreground Service registered with foregroundServiceType="mediaProjection" and handles runtime permissions securely via a translucent trampoline activity.&lt;br&gt;
​🔒 6. Privacy First&lt;br&gt;
​ALST operates strictly on a Bring Your Own Key (BYOK) model:&lt;br&gt;
​No intermediary proxy servers.&lt;br&gt;
​No telemetry or user tracking.&lt;br&gt;
​API keys stay stored strictly inside local sandboxed DataStore storage.&lt;br&gt;
​Captured screen frames exist purely in volatile RAM during processing and are immediately garbage-collected.&lt;br&gt;
​📦 Source Code &amp;amp; Links&lt;br&gt;
ALST is 100% free and open-source under the &lt;strong&gt;MIT License&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐️ &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/navidseyedain/ALSTMobile" rel="noopener noreferrer"&gt;https://github.com/navidseyedain/ALSTMobile&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Latest Release (APK):&lt;/strong&gt; &lt;a href="https://github.com/navidseyedain/ALSTMobile/releases/tag/v1.0.0" rel="noopener noreferrer"&gt;https://github.com/navidseyedain/ALSTMobile/releases/tag/v1.0.0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;​If you find the architecture interesting or useful, feel free to drop a star ⭐️ on the GitHub repository or open an issue for feature requests and discussions!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>android</category>
      <category>kotlin</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>navidseyedain</dc:creator>
      <pubDate>Sat, 29 Aug 2026 12:53:19 +0000</pubDate>
      <link>https://dev.to/navidseyedain/-fpo</link>
      <guid>https://dev.to/navidseyedain/-fpo</guid>
      <description></description>
    </item>
    <item>
      <title>How I Built ALAD Mobile: Real-Time AI Audio Dubbing for Any Android App</title>
      <dc:creator>navidseyedain</dc:creator>
      <pubDate>Tue, 11 Aug 2026 01:07:52 +0000</pubDate>
      <link>https://dev.to/navidseyedain/how-i-built-alad-mobile-real-time-ai-audio-dubbing-for-any-android-app-4b9</link>
      <guid>https://dev.to/navidseyedain/how-i-built-alad-mobile-real-time-ai-audio-dubbing-for-any-android-app-4b9</guid>
      <description>&lt;p&gt;Have you ever wanted to watch a foreign YouTube video, a live stream on Twitch, or a show on Netflix without constantly staring at subtitles? &lt;/p&gt;

&lt;p&gt;To solve this, I built &lt;strong&gt;ALAD Mobile&lt;/strong&gt; (Live Audio Dubbing) — an open-source native Android application that captures internal system audio in real-time, streams it through Google's &lt;strong&gt;Gemini Multimodal Live API&lt;/strong&gt;, and instantly plays back the translated voice over any active media.&lt;/p&gt;

&lt;h2&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%2Ffrubzavjxt082dsdczvx.jpg" alt=" " width="800" height="1778"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  💡 What It Does
&lt;/h2&gt;

&lt;p&gt;ALAD Mobile creates a system-wide floating overlay widget that sits comfortably over your active applications. Once activated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎧 &lt;strong&gt;Intercepts Audio:&lt;/strong&gt; It captures the internal playback audio of &lt;strong&gt;any app&lt;/strong&gt; playing media.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Live Translation:&lt;/strong&gt; Streams audio chunks to Gemini's bidirectional Multimodal Live API via WebSockets.&lt;/li&gt;
&lt;li&gt;🎙️ &lt;strong&gt;Real-Time Playback:&lt;/strong&gt; Plays back the dubbed voice in real time in your selected language (supporting 78 languages).&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Seamless Overlay:&lt;/strong&gt; Lets you toggle dubbing or switch target languages without ever leaving YouTube, Netflix, or Spotify.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Tech Stack &amp;amp; Architecture
&lt;/h2&gt;

&lt;p&gt;Building low-latency real-time voice translation on mobile required a carefully structured stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Language:&lt;/strong&gt; 100% Kotlin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI Framework:&lt;/strong&gt; Jetpack Compose (Material 3)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Async Programming:&lt;/strong&gt; Kotlin Coroutines, &lt;code&gt;StateFlow&lt;/code&gt;, and &lt;code&gt;SharedFlow&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking &amp;amp; Streaming:&lt;/strong&gt; WebSockets for low-latency bidirectional audio streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android Audio APIs:&lt;/strong&gt; &lt;code&gt;MediaProjection&lt;/code&gt; / &lt;code&gt;AudioRecord&lt;/code&gt; for internal audio capture + &lt;code&gt;AudioTrack&lt;/code&gt; for low-latency playback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Service:&lt;/strong&gt; Floating Overlay Window using &lt;code&gt;TYPE_APPLICATION_OVERLAY&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Engine:&lt;/strong&gt; Google Gemini Multimodal Live API&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 How It Works Under the Hood
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Internal Audio Capture
&lt;/h3&gt;

&lt;p&gt;Using Android's &lt;code&gt;MediaProjection&lt;/code&gt; API and &lt;code&gt;AudioRecord&lt;/code&gt;, the app captures raw PCM audio streams from the device's internal sound engine without relying on external microphone input.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bidirectional Live WebSockets
&lt;/h3&gt;

&lt;p&gt;Traditional REST API requests introduce too much latency for live translation. ALAD Mobile opens a persistent WebSocket connection directly to Gemini's Live API, continuously streaming PCM audio chunks in real-time.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Audio Track Playback
&lt;/h3&gt;

&lt;p&gt;As Gemini processes and translates the stream, incoming audio payloads are decoded and pushed directly into a low-latency &lt;code&gt;AudioTrack&lt;/code&gt; buffer for smooth, near-instant voice playback.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Floating System Overlay
&lt;/h3&gt;

&lt;p&gt;To ensure zero friction, a Floating Control Widget built with Android's System Alert Window lets users control dubbing and switch target languages seamlessly over any running app.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Technical Challenges &amp;amp; Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimizing Latency:&lt;/strong&gt; Balancing buffer sizes between raw PCM capture and WebSocket transmission frames was crucial for keeping speech output synchronized with active playback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; Handling connection lifecycle events, audio buffer underruns, and background service states seamlessly using Kotlin &lt;code&gt;StateFlow&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌐 Open Source &amp;amp; How to Try It
&lt;/h2&gt;

&lt;p&gt;ALAD Mobile is &lt;strong&gt;100% Free and Open Source&lt;/strong&gt;. It runs using a free API key directly from &lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;Google AI Studio&lt;/a&gt; — no subscriptions or user accounts required.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/navidseyedain/ALAD-Mobile" rel="noopener noreferrer"&gt;navidseyedain/ALAD-Mobile&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find this project interesting, feel free to drop a ⭐ star on GitHub, submit a PR, or leave your architectural feedback below!&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building ALAD: Real-Time AI Video Audio Dubbing in Chrome with Gemini API &amp; WebSockets</title>
      <dc:creator>navidseyedain</dc:creator>
      <pubDate>Wed, 05 Aug 2026 22:05:14 +0000</pubDate>
      <link>https://dev.to/navidseyedain/building-alad-real-time-ai-voice-dubbing-in-chrome-with-gemini-35-websockets-2jh1</link>
      <guid>https://dev.to/navidseyedain/building-alad-real-time-ai-voice-dubbing-in-chrome-with-gemini-35-websockets-2jh1</guid>
      <description>&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%2F9a1sfo336i2q9jc8ldww.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%2F9a1sfo336i2q9jc8ldww.png" alt=" " width="400" height="404"&gt;&lt;/a&gt;&lt;br&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%2Fyu7c4e0bmyp5mq8kmtuu.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%2Fyu7c4e0bmyp5mq8kmtuu.png" alt=" " width="398" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building ALAD: Real-Time AI Video Audio Dubbing in Chrome with Gemini API &amp;amp; WebSockets&lt;br&gt;
Imagine watching a video, live stream, or online course in a language you don't speak, and hearing it dubbed in real-time into your native language—right inside your browser, with almost zero latency.&lt;/p&gt;

&lt;p&gt;That is exactly why I built ALAD (Live Audio Dubbing / LAD), an open-source Chrome Extension that leverages Google’s Gemini API and WebSockets to capture live tab audio, translate it on the fly, and play back natural dubbed audio alongside the original video.&lt;/p&gt;

&lt;p&gt;In this article, I’ll walk through why I created ALAD, how its architecture works under the hood, the technical hurdles of handling real-time audio in Chrome Manifest V3, and how you can try or contribute to the project!&lt;/p&gt;

&lt;p&gt;💡 The Problem: Why Real-Time Dubbing?&lt;br&gt;
Subtitles are great, but they require your constant visual attention. If you are watching a technical tutorial, a lecture, or a fast-paced presentation in a foreign language, scanning subtitles while trying to focus on code or visual slides can be exhausting.&lt;/p&gt;

&lt;p&gt;Existing dubbing solutions usually fall into two categories:&lt;/p&gt;

&lt;p&gt;Offline post-processing tools: High quality, but slow and impossible for live or streaming video.&lt;/p&gt;

&lt;p&gt;Heavy cloud SaaS platforms: Expensive, subscription-based, and locked behind proprietary players.&lt;/p&gt;

&lt;p&gt;I wanted a solution that was lightweight, open-source, privacy-friendly, and integrated directly into the browser.&lt;/p&gt;

&lt;p&gt;🚀 Introducing ALAD (Live Audio Dubbing)&lt;br&gt;
ALAD connects your active browser tab directly to Gemini's real-time multimodal capabilities using WebSockets.&lt;/p&gt;

&lt;p&gt;Key Features:&lt;br&gt;
🎙️ Real-Time Tab Audio Capture: Captures clear raw audio directly from YouTube, Udemy, Twitch, or any HTML5 video player without capturing room ambient noise.&lt;/p&gt;

&lt;p&gt;⚡ Low-Latency Streaming: Streams audio chunks over WebSockets for rapid response and minimal delay between visual speaker cues and audio output.&lt;/p&gt;

&lt;p&gt;🤖 Powered by Gemini API: Uses Gemini's advanced multimodal audio understanding and natural speech generation.&lt;/p&gt;

&lt;p&gt;🎚️ Smart Audio Ducking &amp;amp; Volume Balancing: Lowers the original video audio slightly while playing the dubbed translation so you can comfortably hear both or focus solely on the translated audio.&lt;/p&gt;

&lt;p&gt;⚙️ Manifest V3 Compliant: Built strictly for modern Chrome extension security and performance standards.&lt;/p&gt;

&lt;p&gt;🔑 BYO Key (Bring Your Own API Key): Keeps your requests private and cost-effective—your API key is stored locally in your browser.&lt;/p&gt;

&lt;p&gt;🛠️ Tech Stack &amp;amp; Architecture&lt;br&gt;
Here is how data flows through ALAD in real time:&lt;/p&gt;

&lt;p&gt;[ Active Tab (HTML5 Video) ]&lt;br&gt;
            │&lt;br&gt;
            ▼ (tabCapture API / Web Audio API)&lt;br&gt;
[ Audio Processing &amp;amp; PCM Chunking ]&lt;br&gt;
            │&lt;br&gt;
            ▼ (WebSocket Stream)&lt;br&gt;
[ ALAD Background Engine ]&lt;br&gt;
            │&lt;br&gt;
            ▼ (Gemini API Multimodal Endpoint)&lt;br&gt;
[ AI Translation &amp;amp; Audio Synthesis ]&lt;br&gt;
            │&lt;br&gt;
            ▼ (AudioBuffer Queue / Playback)&lt;br&gt;
[ Dubbed Audio Streamed to User ]&lt;br&gt;
Main Technologies Used:&lt;br&gt;
Frontend / Popup: HTML5, CSS3, Modern JavaScript (ESNext)&lt;/p&gt;

&lt;p&gt;Extension Platform: Chrome Extension API Manifest V3 (Service Workers, Offscreen Documents, tabCapture)&lt;/p&gt;

&lt;p&gt;Audio Engineering: Web Audio API (AudioContext, PCM 16-bit encoding)&lt;/p&gt;

&lt;p&gt;Real-Time Transport: WebSockets for low-latency full-duplex binary audio streaming&lt;/p&gt;

&lt;p&gt;AI Engine: Google Gemini API (Multimodal Live API)&lt;/p&gt;

&lt;p&gt;🔬 Under the Hood: Key Technical Challenges&lt;br&gt;
Developing a real-time audio extension on Manifest V3 came with a few interesting technical challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tab Audio Capture in Manifest V3
In Manifest V3, background scripts run inside transient Service Workers, which do not have access to the DOM or AudioContext.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this, ALAD utilizes Chrome’s Offscreen API (chrome.offscreen). When audio capturing starts:&lt;/p&gt;

&lt;p&gt;The background service worker spawns an offscreen document.&lt;/p&gt;

&lt;p&gt;The offscreen document calls chrome.tabCapture.getMediaStreamId() to capture the active tab's media stream.&lt;/p&gt;

&lt;p&gt;Raw audio is piped into a MediaStreamAudioSourceNode inside an AudioContext.&lt;/p&gt;

&lt;p&gt;...JavaScript&lt;br&gt;
// Offscreen script snippet for tab audio capturing&lt;br&gt;
const stream = await navigator.mediaDevices.getUserMedia({&lt;br&gt;
  audio: {&lt;br&gt;
    mandatory: {&lt;br&gt;
      chromeMediaSource: 'tab',&lt;br&gt;
      chromeMediaSourceId: streamId&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;const audioContext = new AudioContext({ sampleRate: 16000 });&lt;br&gt;
const source = audioContext.createMediaStreamSource(stream);&lt;br&gt;
// Process and chunk PCM audio data...&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PCM Audio Chunking &amp;amp; WebSocket Encoding
For Gemini to process live audio seamlessly, audio must be downsampled (typically to 16kHz mono) and chunked into base64-encoded PCM frames before being pushed through the WebSocket connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We process incoming audio buffer arrays, convert floating-point samples to 16-bit signed integers (PCM16), and dispatch small binary frames continuously:&lt;/p&gt;

&lt;p&gt;JavaScript&lt;br&gt;
function convertFloat32ToPCM16(buffer) {&lt;br&gt;
  let l = buffer.length;&lt;br&gt;
  let buf = new Int16Array(l);&lt;br&gt;
  while (l--) {&lt;br&gt;
    buf[l] = Math.min(1, Math.max(-1, buffer[l])) * 0x7FFF;&lt;br&gt;
  }&lt;br&gt;
  return buf.buffer;&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jitter-Free Audio Queue &amp;amp; Playback Synchronization
Receiving streamed audio chunks over a network means packet arrival times can fluctuate. If played back immediately upon receipt, the synthesized voice would sound choppy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ALAD implements a custom Audio Queue Scheduler. Received PCM chunks are decoded into AudioBuffer objects and scheduled sequentially on the timeline (audioContext.currentTime), creating continuous, stutter-free real-time dubbing.&lt;/p&gt;

&lt;p&gt;📦 How to Install and Run ALAD Locally&lt;br&gt;
You can test ALAD right now on your machine in just a few minutes:&lt;/p&gt;

&lt;p&gt;Prerequisites:&lt;br&gt;
Google Chrome (or any Chromium-based browser like Brave or Edge)&lt;/p&gt;

&lt;p&gt;A Gemini API key (obtainable for free from Google AI Studio)&lt;/p&gt;

&lt;p&gt;Installation Steps:&lt;br&gt;
Clone the repository:&lt;/p&gt;

&lt;p&gt;Bash&lt;br&gt;
git clone &lt;a href="https://github.com/navidseyedain/ALAD.git" rel="noopener noreferrer"&gt;https://github.com/navidseyedain/ALAD.git&lt;/a&gt;&lt;br&gt;
cd ALAD&lt;br&gt;
Load into Chrome:&lt;/p&gt;

&lt;p&gt;Open Chrome and navigate to chrome://extensions/&lt;/p&gt;

&lt;p&gt;Enable Developer mode (toggle in the top right corner).&lt;/p&gt;

&lt;p&gt;Click Load unpacked.&lt;/p&gt;

&lt;p&gt;Select the ALAD project directory.&lt;/p&gt;

&lt;p&gt;Configure &amp;amp; Start Dubbing:&lt;/p&gt;

&lt;p&gt;Click the ALAD icon in your Chrome toolbar.&lt;/p&gt;

&lt;p&gt;Paste your Gemini API key in the settings tab.&lt;/p&gt;

&lt;p&gt;Select your target language.&lt;/p&gt;

&lt;p&gt;Open any video on YouTube, click Start Live Dubbing, and enjoy!&lt;/p&gt;

&lt;p&gt;🛣️ What's Next? (Roadmap)&lt;br&gt;
ALAD is an active open-source project, and there are several exciting features planned:&lt;/p&gt;

&lt;p&gt;[ ] Multi-speaker Detection: Identifying different voices in the video and assigning distinct synthetic voices.&lt;/p&gt;

&lt;p&gt;[ ] Offline Cache &amp;amp; Subtitle Overlay: Generating dual synchronized subtitles alongside audio dubbing.&lt;/p&gt;

&lt;p&gt;[ ] Chrome Web Store Publishing: Packaging and releasing ALAD to the official Chrome Web Store for one-click installation.&lt;/p&gt;

&lt;p&gt;[ ] Custom Voice Parameters: Pitch, speed, and emotion adjustments for dubbed voices.&lt;/p&gt;

&lt;p&gt;🤝 Open Source &amp;amp; Contributions&lt;br&gt;
ALAD is completely open-source and released under the MIT License. Contributions are super welcome! Whether you want to fix a bug, improve audio synchronization, refine the UI, or add support for new languages, feel free to open an issue or pull request.&lt;/p&gt;

&lt;p&gt;🌐 GitHub Repository: &lt;a href="https://github.com/navidseyedain/ALAD" rel="noopener noreferrer"&gt;https://github.com/navidseyedain/ALAD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👤 Author: Navid Seyedain (&lt;a class="mentioned-user" href="https://dev.to/navidseyedain"&gt;@navidseyedain&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you find this project useful or interesting, please consider dropping a ⭐ Star on the repository to support development!&lt;/p&gt;

&lt;p&gt;Thank you for reading! Feel free to leave your thoughts, feedback, or questions in the comments below.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chromeextension</category>
      <category>javascript</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Gemini SEO - Parallel Multi-Agent SEO &amp; GEO Engine</title>
      <dc:creator>navidseyedain</dc:creator>
      <pubDate>Mon, 27 Jul 2026 17:39:41 +0000</pubDate>
      <link>https://dev.to/navidseyedain/gemini-seo-parallel-multi-agent-seo-geo-engine-17lh</link>
      <guid>https://dev.to/navidseyedain/gemini-seo-parallel-multi-agent-seo-geo-engine-17lh</guid>
      <description>&lt;p&gt;Search Engine Optimization (SEO) is evolving rapidly into &lt;strong&gt;Generative Engine Optimization (GEO)&lt;/strong&gt;. To help developers and webmasters optimize their content for modern AI search engines, I built &lt;strong&gt;Gemini SEO&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What is Gemini SEO?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gemini SEO&lt;/strong&gt; is a high-performance, parallel multi-agent engine built with &lt;strong&gt;TypeScript&lt;/strong&gt; and powered by Google's &lt;strong&gt;Gemini API&lt;/strong&gt;. It automates deep technical SEO and GEO audits using specialized autonomous AI agents running concurrently.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;⚡ Parallel Multi-Agent Execution:&lt;/strong&gt; Runs multiple AI agents in parallel for fast, multi-dimensional analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 Generative Engine Optimization (GEO):&lt;/strong&gt; Prepares your content not just for traditional search engines, but for modern AI search platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🛡️ Built with TypeScript:&lt;/strong&gt; Fully typed, scalable, and maintainable codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🎯 Actionable Insights:&lt;/strong&gt; Generates structured reports and actionable optimization suggestions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;p&gt;You can easily set up and run the project locally:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
# Clone the repository
git clone [https://github.com/navidseyedain/gemini-seo.git](https://github.com/navidseyedain/gemini-seo.git)

# Navigate to directory
cd gemini-seo

# Install dependencies
npm install

Make sure to set your Gemini API key in your environment variables before running the engine.
🔗 Open Source &amp;amp; Contribution
The project is completely open-source under the MIT License. I would love to get feedback from the community!
GitHub Repository: navidseyedain/gemini-seo
⭐ If you find this project useful, please consider giving it a star on GitHub! It helps the project reach more developers.
Feel free to leave your thoughts, questions, or feature requests in the comments below!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>showdev</category>
      <category>ai</category>
      <category>typescript</category>
      <category>seo</category>
    </item>
  </channel>
</rss>
