Real-time audio translation for Google Meet using Gemini Live Translate API.
Your microphone always forwards to a virtual audio device (BlackHole). When translation is active, the translated audio is mixed in. By default only translation goes to Meet; with --mix, participants hear your original voice plus the translation. Use it from the command line or the macOS menu bar app.
- macOS
- Python 3.11+
- BlackHole virtual audio driver
- Google API key with Gemini access
brew install blackhole-2chRestart your Mac after installing.
pip3 install -r requirements.txtGet a key at Google AI Studio.
Create a .env file:
GEMINI_API_KEY=your-key-here
python3 livetranslate.pyStarts forwarding mic to BlackHole and translates immediately.
python3 menubar.pyShows "LT" in your macOS menu bar. Mic forwarding starts automatically. Use the menu to start/stop translation, change languages, pick a voice, and select output device.
| Flag | Description |
|---|---|
--from LANG |
Source language code (default: es) |
--to LANG |
Target language code (default: en) |
--mix |
Send both your voice and translation to BlackHole (default: translation only) |
--voice NAME |
Voice for translation (default: Zephyr) |
--monitor |
Play translated audio on your headphones so you can hear it |
--list-devices |
List available audio devices and exit |
# Spanish to English (default, translation only to Meet)
python3 livetranslate.py
# English to Spanish
python3 livetranslate.py --from en --to es
# Mix mode: participants hear your voice + translation
python3 livetranslate.py --mix
# Hear the translation yourself
python3 livetranslate.py --monitor
# Use a different voice
python3 livetranslate.py --voice Charon
# Combine options
python3 livetranslate.py --from es --to fr --mix --monitor --voice Aoede| Code | Language |
|---|---|
es |
Spanish |
en |
English |
fr |
French |
de |
German |
pt |
Portuguese |
it |
Italian |
ja |
Japanese |
ko |
Korean |
zh |
Chinese |
ru |
Russian |
ar |
Arabic |
Zephyr (default), Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus, Perseus
- Run
python3 menubar.py(orlivetranslate.py) - Open Google Meet
- Go to Settings → Audio
- Set Microphone to BlackHole 2ch
- Keep your regular speakers/headphones as the output device
By default, participants hear only the translation. With --mix, they hear your original voice plus the translation.
┌─────────────────────────┐
│ Gemini Live Translate │
│ (es → en) │
└────────┬────────────────┘
│ translated audio (24kHz)
▼ resampled to 48kHz
Microphone ──→ sounddevice callback ──→ BlackHole 2ch ──→ Google Meet
(48kHz) (single stream) (48kHz)
│
└──→ Headphones (--monitor, 24kHz native)
- A single
sounddevice.Streamhandles both mic input and BlackHole output at 48kHz (BlackHole's native rate) - The callback mixes mic audio and translation audio into a single buffer — no dual-stream conflicts
- Mic audio is downsampled to 16kHz and sent to Gemini Live Translate API asynchronously
- Translated audio (24kHz) is upsampled to 48kHz and fed into the translation buffer
- The callback consumes the translation buffer each cycle, mixing or substituting as configured
- With
--monitor, translated audio plays on your headphones at native 24kHz quality
- Start/Stop Translation — toggle translation without interrupting mic forwarding
- From / To — change source and target language
- Voice — select from 9 available voices
- Mix — toggle between translation-only or voice+translation output
- Output Device — choose where monitor audio plays (headphones, speakers, etc.)
- Monitor — hear the translation in your headphones
- Refresh Devices — rescan audio devices if you plug/unplug something
- Use headphones when using
--monitorto avoid feedback loops - Mic → BlackHole is always active regardless of translation state
- Uses the dedicated
gemini-3.5-live-translate-previewmodel optimized for real-time translation - Audio runs at 48kHz (BlackHole native) to avoid CoreAudio sample rate conversion artifacts
- Uses
sounddevicewith a single callback stream — no dual-stream conflicts on virtual devices
