{"slug": "build-a-real-time-voice-translation-app", "title": "Build a Real-Time Voice Translation App", "summary": "A developer published a walkthrough for building a real-time voice translation app that chains speech-to-text, machine translation, and text-to-speech services, using ElevenLabs for voice synthesis. The guide pairs a JavaScript MediaRecorder frontend with a Python FastAPI backend that streams 250ms audio chunks over WebSocket, targeting roughly two seconds of end-to-end latency.", "body_md": "**Getting Started with a Real‑Time Voice Translation App**\n\nBuilding a real‑time voice translation app feels like science‑fiction, but with today’s cloud APIs it’s a very achievable side‑project. In this article we’ll walk through the whole stack: capturing audio, transcribing it, translating the text, and finally turning the translated text back into speech. We’ll keep the example language‑agnostic (Python on the backend, JavaScript on the frontend) and we’ll lean on a few battle‑tested services. The star of the show is ElevenLabs for its high‑quality text‑to‑speech (TTS) and voice‑cloning capabilities. You can start experimenting right away with their free tier at [https://try.elevenlabs.io/kr07zfuqn1bp](https://try.elevenlabs.io/kr07zfuqn1bp).\n\nIf you’re building a language‑learning app, a travel chatbot, or a customer‑support tool, latency is everything. A 2‑second delay feels natural; a 5‑second lag is noticeable. That means we need:\n\nThe rest of this guide assumes you already have an API key for a STT provider (Google Cloud Speech‑to‑Text, Azure Speech, or Whisper on your own server) and a translation service (Google Translate, DeepL, or Microsoft Translator). We’ll plug in ElevenLabs for the TTS step.\n\n```\n+----------------+      +-------------------+      +-----------------+\n|  Browser (JS)  | <--->|  Node.js/Flask API| <--->|  ElevenLabs TTS |\n+----------------+      +-------------------+      +-----------------+\n        ^                        ^                          ^\n        |                        |                          |\n        |  WebSocket (audio)     |  REST (transcribe/translate)\n        |                        |                          |\n        |                        |                          |\n  Mic input  <---  STT API  <---  Translation API  <---  TTS Engine\n```\n\nBelow is a minimal JavaScript snippet that records mic input and streams it to a server using WebSocket. We’re using the `MediaRecorder` API for simplicity.\n\n``` js\nconst socket = new WebSocket('wss://your-server.com/stream');\nconst mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });\n\nmediaRecorder.ondataavailable = (e) => {\n  // Send each chunk as binary data\n  socket.send(e.data);\n};\n\nsocket.addEventListener('message', (event) => {\n  // event.data is the TTS audio blob from ElevenLabs\n  const audio = new Audio(URL.createObjectURL(event.data));\n  audio.play();\n});\n\nmediaRecorder.start(250); // send 250ms chunks\n```\n\n**What to watch for**\n\n`MediaRecorder`. For older browsers you may need a polyfill or a server‑side WebRTC solution.\nWe’ll use **Python + FastAPI** for the backend because of its async support and excellent typing. The core flow is:\n\n``` python\n# main.py\nfrom fastapi import FastAPI, WebSocket\nimport aiohttp\nimport asyncio\nimport json\n\napp = FastAPI()\n\n# Replace with your real keys\nSTT_ENDPOINT = \"https://api.speech-to-text.com/v1/recognize\"\nTRANSLATE_ENDPOINT = \"https://api.translate.com/v1/translate\"\nELEVENLABS_API = \"https://api.elevenlabs.io/v1/text-to-speech\"\n\nELEVENLABS_API_KEY = \"YOUR_ELEVENLABS_KEY\"\n\nasync def transcribe_audio(audio_bytes: bytes) -> str:\n    async with aiohttp.ClientSession() as session:\n        async with session.post(\n            STT_ENDPOINT,\n            headers={\"Authorization\": f\"Bearer {STT_ENDPOINT}\"},\n            data=audio_bytes,\n        ) as resp:\n            result = await resp.json()\n            return result[\"text\"]\n\nasync def translate_text(text: str, target_lang: str = \"es\") -> str:\n    async with aiohttp.ClientSession() as session:\n        payload = {\"q\": text, \"target\": target_lang}\n        async with session.post(\n            TRANSLATE_ENDPOINT,\n            json=payload,\n            headers={\"Authorization\": f\"Bearer {TRANSLATE_ENDPOINT}\"},\n        ) as resp:\n            result = await resp.json()\n            return result[\"translatedText\"]\n\nasync def synthesize_speech(text: str) -> bytes:\n    async with aiohttp.ClientSession() as session:\n        payload = {\n            \"text\": text,\n            \"voice_settings\": {\"pitch\": 0, \"speed\": 1}\n        }\n        async with session.post(\n            ELEVENLABS_API,\n            json=payload,\n            headers={\n                \"xi-api-key\": ELEVENLABS_API_KEY,\n                \"Content-Type\": \"application/json\",\n            },\n        ) as resp:\n            # ElevenLabs streams MP3\n            return await resp.content.read()\n\n@app.websocket(\"/stream\")\nasync def websocket_endpoint(websocket: WebSocket):\n    await websocket.accept()\n    buffer = bytearray()\n    while True:\n        data = await websocket.receive_bytes()\n        buffer.extend(data)\n\n        # Simple logic: every 3 seconds of audio we process\n        if len(buffer) > 300_000:  # roughly 3 s of 96 kHz audio\n            text = await transcribe_audio(buffer)\n            translated = await translate_text(text, target_lang=\"de\")\n            audio = await synthesize_speech(translated)\n            await websocket.send_bytes(audio)\n            buffer.clear()\n```\n\nElevenLabs offers:\n\n**Tip**: The free tier gives you a generous amount of usage per month. If you’re building a prototype, you’ll be fine. When you go live, just swap the API key in the `ELEVENLABS_API_KEY` variable.\n\n| Step | What to do | Notes | \n|---|---|---|\n| 1 | Deploy the FastAPI app to a platform that supports WebSockets (e.g., Fly.io, Render, Railway). | Make sure you set `CORS_ALLOW_ORIGIN` to your domain. | \n| 2 | Secure your API keys. Store them in environment variables or a secrets manager. | Don’t hard‑code them in the repo. | \n| 3 | Enable HTTPS on the front‑end. Browsers block microphone access on insecure origins. | Let’s Encrypt is free. | \n| 4 | Test latency. Use `chrome://inspect` or`websocket.org` to measure round‑trip time. | Aim for < 500 ms end‑to‑end. | \n| 5 | Optimize VAD. If you notice unnecessary STT calls, add a simple VAD library like `webrtcvad` . | Reduces costs and latency. | \n\n`target_lang` parameter.\nWith a handful of lines of code and a few paid services, you can turn a microphone into a real‑time, multilingual chatbot. The key is to keep the data path tight: mic → STT → translation → TTS → speaker. ElevenLabs makes the last hop the smoothest, delivering natural‑sounding voices that feel like a real person.\n\nReady to bring your voice translation idea to life? Sign up for ElevenLabs today and unlock high‑quality TTS and voice‑cloning for your app.\n\n**Try ElevenLabs now**: [https://try.elevenlabs.io/kr07zfuqn1bp](https://try.elevenlabs.io/kr07zfuqn1bp)\n\nHappy coding!", "url": "https://wpnews.pro/news/build-a-real-time-voice-translation-app", "canonical_source": "https://dev.to/voice_developer/build-a-real-time-voice-translation-app-3l55", "published_at": "2026-10-17 00:16:02+00:00", "updated_at": "2026-10-17 00:27:00.539391+00:00", "lang": "en", "topics": ["ai-tools", "natural-language-processing", "generative-ai", "developer-tools"], "entities": ["ElevenLabs", "FastAPI", "Google Cloud Speech-to-Text", "Azure Speech", "Whisper", "Google Translate", "DeepL", "Microsoft Translator"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/build-a-real-time-voice-translation-app", "markdown": "https://wpnews.pro/news/build-a-real-time-voice-translation-app.md", "text": "https://wpnews.pro/news/build-a-real-time-voice-translation-app.txt", "jsonld": "https://wpnews.pro/news/build-a-real-time-voice-translation-app.jsonld"}}