Skip to main content

Real-time speech-to-speech translation for any meeting app โ€” your voice, every language.

Project description

๐ŸŽ™๏ธ meetdub

Speak any language with your own voice โ€” in any meeting.

Real-time speech-to-speech translation that lives between your mic and Teams/Zoom/Meet.

CI PyPI Python License: MIT GitHub stars

English ยท ๆ—ฅๆœฌ่ชž

built on OpenAI's gpt-realtime-translate ยท runs locally ยท BYO API key ยท MIT


๐Ÿ“น Demo GIF goes here โ€” docs/demo.gif (Teams call with live JAโ†’EN translation in the meetdub TUI)

Why meetdub?

meetdub Microsoft Teams
Live Translation
Krisp / Noise tools Heygen
(avatar dubbing)
Works in any app โœ… โŒ Teams only โœ… โŒ
Your own voice โœ… โŒ Synth voice / text captions N/A โœ…
Bring your own key โœ… โŒ โŒ โŒ
Open source โœ… โŒ โŒ โŒ
Cost ~$2/hr Per-seat license Subscription Subscription
Self-hostable โœ… โŒ โŒ โŒ

Quick start

curl -fsSL https://raw.githubusercontent.com/Yarta-AI/meetdub/main/install.sh | bash

meetdub auth openai          # paste your sk-โ€ฆ (hidden input)
meetdub setup                # one-time wizard: language + devices + passthrough
meetdub run                  # โ–ถ start translating

In Teams / Zoom / Meet, set microphone โ†’ BlackHole 2ch. That's it.

Day-to-day after that is just meetdub run, or meetdub run --to en to switch target language for one session.

How it works

                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    24kHz PCM16    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   you speak โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚     mic       โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ gpt-realtime-translateโ”‚
       โ”‚             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                                                            โ”‚
       โ”‚                                                            โ”‚ translated audio
       โ”‚                                                            โ”‚ (your voice, target language)
       โ”‚                                                            โ–ผ
       โ”‚                                                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚                                                  โ”‚   BlackHole 2ch   โ”‚ โ”€โ”€โ–ถ Teams hears it
       โ”‚                                                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                                                            โ”‚
       โ”‚                                                            โ–ผ (--monitor)
       โ”‚                                                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€ live bilingual captions in your terminal  โ”‚   your headphones โ”‚
                                                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  • Capture โ€” sounddevice reads 24 kHz mono PCM16 in 20 ms frames.
  • VAD โ€” RMS energy gate skips silence so you only pay for speech. No native deps.
  • Translate โ€” WebSocket to wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate (or your Azure deployment).
  • Play โ€” translated audio writes straight to BlackHole 2ch. Teams reads BlackHole as its microphone.
  • TUI โ€” rich.Live renders bilingual source / target captions plus a running cost meter.
  • Hotkeys โ€” pynput listens for F2โ€“F12 (language hot-swap), Space (push-to-translate), Esc (quit).

Features

  • ๐ŸŽญ Voice preservation โ€” gpt-realtime-translate keeps your tone, pitch, and cadence. People hear you, just in another language.
  • ๐Ÿช„ Universal โ€” Teams ยท Zoom ยท Google Meet ยท Slack huddles ยท Discord ยท OBS ยท QuickTime ยท FaceTime. If it picks a mic, meetdub works.
  • โšก One-command install + setup wizard โ€” install.sh handles BlackHole / pipx / brew; meetdub setup writes the rest. After that, you just run meetdub run.
  • ๐ŸŒ 11 output languages โ€” English, ๆ—ฅๆœฌ่ชž, Espaรฑol, Franรงais, Deutsch, ไธญๆ–‡, ํ•œ๊ตญ์–ด, Portuguรชs, Italiano, เคนเคฟเคจเฅเคฆเฅ€, ะ ัƒััะบะธะน. Plus Indonesian and Vietnamese.
  • โŒจ๏ธ Hot-swap mid-call โ€” tap F2โ€“F12 to change target language without restarting.
  • ๐ŸŽš๏ธ Live passthrough mix โ€” + / - / 0 adjusts how loud your original voice rides under the translation. Cookbook-recommended for mixed-language meetings (avoids silence when the other side speaks your target language).
  • ๐Ÿ”‡ Push-to-translate โ€” hold Space (with --ptt) so meetdub only listens while you're speaking. Perfect for multilingual calls where you want to hear the other side untranslated.
  • ๐Ÿ’ธ Live cost meter โ€” your TUI shows actual API spend so you never get a surprise invoice.
  • ๐Ÿ“ Bilingual transcripts โ€” every session auto-saves a Markdown transcript to ~/.meetdub/transcripts/.
  • ๐Ÿ” Local secrets โ€” credentials in ~/.meetdub/secrets.env (chmod 600), never in shell rc.
  • โ˜๏ธ Two backends โ€” OpenAI direct or Azure OpenAI (api-key or Microsoft Entra ID).
  • ๐Ÿ MIT, no telemetry โ€” single Python package, no servers we control, no analytics.

Install

Requirements: macOS, an OPENAI_API_KEY (or Azure OpenAI deployment).

One-liner

curl -fsSL https://raw.githubusercontent.com/Yarta-AI/meetdub/main/install.sh | bash

The installer runs through 5 visible steps:

  1. Homebrew โ€” installs if missing
  2. pipx โ€” brew install pipx && pipx ensurepath
  3. BlackHole 2ch โ€” brew install --cask blackhole-2ch (sudo for system extension)
  4. meetdub โ€” pipx install meetdub
  5. Audio setup โ€” walks you through creating a Multi-Output Device so you can hear yourself while Teams hears the translation

Audit before running

git clone https://github.com/Yarta-AI/meetdub && cd meetdub
less install.sh
./install.sh

Or use the Python bootstrap: python3 scripts/bootstrap.py.

After install

If you see meetdub: command not found, your shell hasn't picked up ~/.local/bin yet:

exec zsh   # or: source ~/.zshrc

Configure credentials

Credentials live in ~/.meetdub/secrets.env (chmod 600) โ€” never in your shell rc.

OpenAI

meetdub auth openai                # interactive, hides input
meetdub auth openai --key sk-โ€ฆ     # non-interactive

Azure OpenAI

Three auth modes are supported:

# 1. API key
meetdub auth azure
  # prompts: endpoint, deployment, key

meetdub auth azure --endpoint my-resource.openai.azure.com \
                   --deployment my-realtime-translate \
                   --key โ€ฆ

# 2. Static Microsoft Entra Bearer token
meetdub auth azure --aad-token "$(az account get-access-token --resource https://cognitiveservices.azure.com --query accessToken -o tsv)"

# 3. Interactive browser login (no `az` CLI needed)
meetdub auth login
  # opens your browser, signs you into Azure, caches the token for auto-refresh

Use case for auth login: when your Azure OpenAI resource is configured for Microsoft Entra ID only (api-key disabled). It's the smoothest path and survives token expiry automatically.

Inspect / clear

meetdub auth show                  # masked summary
meetdub auth clear --openai        # remove specific backend
meetdub auth clear --azure
meetdub auth clear --all
meetdub auth path                  # print file path

Precedence: shell env vars > ~/.meetdub/secrets.env. So OPENAI_API_KEY=other-key meetdub run โ€ฆ still overrides cleanly for one-off testing.

Run

After meetdub setup, the everyday command is just:

meetdub run

One-off overrides:

meetdub run --to en                  # switch target language for this session
meetdub run --ptt                    # push-to-translate mode (hold Space)
meetdub run --passthrough            # mix original mic in at 15% (adjust with +/-)
meetdub run --azure                  # use Azure backend

If you skip meetdub setup, sane defaults apply:

  • Output โ†’ BlackHole 2ch (the virtual mic Teams/Zoom will pick up)
  • Input โ†’ auto-selects MacBook / Built-in mic when one is available (AirPods mic pickup is unreliable for translation)
  • Monitor โ†’ none (you won't hear the translation yourself โ€” pass --monitor "AirPods" to fix)

In Teams / Zoom / Meet:

  • Microphone: BlackHole 2ch
  • Speaker: your real headphones (so you hear the other party)
  • Noise suppression: โš  Low or Off โ€” Teams' default "auto" filters out synthesized voices.

Hotkeys

Key Action
F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 EN ยท JA ยท ES ยท FR ยท DE ยท ZH ยท KO ยท PT ยท IT ยท HI ยท RU
+ / - passthrough volume ยฑ5%
0 mute passthrough
Space (hold, with --ptt) push-to-translate
Esc quit

Two paths handle these keys:

  1. Global (works while Teams is focused) โ€” pynput listener. Needs macOS Input Monitoring + Accessibility permission for your terminal app.
  2. TTY fallback (works only when meetdub's terminal is focused, but needs no permissions) โ€” direct /dev/tty read in cbreak mode.

โš  macOS reserves the F-key row for media controls by default. Either hold fn while pressing F2, or enable System Settings โ†’ Keyboard โ†’ Use F1, F2, etc. keys as standard function keys.

CLI reference

meetdub install                      Install BlackHole + audio walkthrough
meetdub setup                        Interactive wizard (language, devices, passthrough)
meetdub run [options]                Start translating
meetdub auth openai | azure | login  Save credentials
meetdub auth show | clear | path     Manage credentials
meetdub doctor                       Verify environment
meetdub devices                      List audio devices
meetdub languages                    Supported output languages
meetdub config                       Print current config
meetdub keys-test                    Verify keyboard permission (Input Monitoring)
meetdub mic-test                     Verify microphone permission + level
meetdub --version

meetdub run options

Option Default Notes
--to / -t from config Target language code (en, ja, es, fr, de, zh, ko, pt, it, hi, ru, id, vi)
--input auto-detect MacBook mic, else system default Substring match on input device name
--output BlackHole 2ch Substring match on output device name
--monitor none (from config if set) Also play translation here so you hear yourself
--ptt off Translate only while Space is held
--passthrough off Mix original mic at 15% into BlackHole (adjust with +/- in TUI)
--passthrough-gain โ€” Set explicit linear gain 0.0โ€“1.0 (overrides --passthrough)
--no-vad off Always send audio (more accurate, more cost)
--no-transcript off Skip the Markdown transcript
--azure off Use Azure backend
--azure-endpoint from auth my-resource.openai.azure.com
--azure-deployment from auth Deployment name
--azure-api-version GA Set for preview API (deprecated 2026-04-30)
--azure-path /openai/v1/realtime/translations Override if your region 404s
--latency-ms 0 (device minimum) Output buffer in milliseconds. Bump to 30โ€“100 if you hear stutter; 0 is closest to real-time.
--debug off Verbose log to ~/.meetdub/debug.log

Troubleshooting

Run meetdub doctor first โ€” it checks Homebrew, BlackHole, secrets, and Azure config.

Symptom Cause / fix
meetdub: command not found Run exec zsh to refresh PATH after pipx install.
meetdub doctor shows BlackHole as โœ— even after brew install Run sudo killall coreaudiod to make CoreAudio re-scan plugins.
No audio captured โ€” mic-test shows < -100 dBFS macOS Microphone permission missing. Settings โ†’ Privacy & Security โ†’ Microphone โ†’ enable your terminal. Cmd+Q the terminal, then reopen.
F-keys / Esc / Space do nothing โ€” keys-test receives nothing macOS Input Monitoring permission missing. Settings โ†’ Privacy & Security โ†’ Input Monitoring and Accessibility โ†’ enable your terminal. Cmd+Q, reopen.
Translation runs but Teams stays silent Set Teams microphone to BlackHole 2ch. Also: noise suppression โ†’ Low or Off.
Teams sounds robotic / chopped Teams' noise suppression is filtering meetdub's output. Set it to Off.
Endpoint configured for Microsoft Entra ID authentication, key is not needed Your Azure resource disabled api-key auth. Run meetdub auth login for browser login.
Audio is choppy / "ใทใคใทใค" Bump the output buffer: meetdub run --latency-ms 50 (or 100). Bluetooth monitors like AirPods compound the issue โ€” try a wired output for comparison.
Persistent transcription errors mid-call Speak in complete sentences (3+ seconds). Very short utterances or whispers fail to transcribe. Try --no-vad.

Roadmap

  • Demo GIF in this README
  • Homebrew tap (brew install Yarta-AI/meetdub/meetdub)
  • Linux support (PulseAudio / PipeWire null-sink)
  • Windows support (VB-CABLE)
  • Two-way mode โ€” pipe the other side's audio through translation back to your headphones
  • Glossary plugin hooks โ€” rewrite jargon / product names before TTS
  • Local-model backend โ€” whisper.cpp + open TTS for offline / privacy mode
  • macOS Keychain storage backend as alternative to secrets.env
  • Web version using the WebRTC /realtime/translations/calls endpoint (reaches mobile browsers)

๐Ÿ›‘ Not planned: native iOS / Android apps that inject into other apps' microphones. The platform sandbox forbids virtual audio drivers, so meetdub's BlackHole-style approach won't translate. The Web version above is the practical path for mobile users.

Contributing

PRs welcome โ€” please open an issue first for anything bigger than a typo. See CONTRIBUTING.md.

Acknowledgements

License

MIT โ€” do whatever you want, just don't blame us.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meetdub-0.1.0.tar.gz (51.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meetdub-0.1.0-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

File details

Details for the file meetdub-0.1.0.tar.gz.

File metadata

  • Download URL: meetdub-0.1.0.tar.gz
  • Upload date:
  • Size: 51.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meetdub-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bf02e9eb60c2a3e46ab50dd4eb49463a32bb43f6036bda481428bd2ad94c100e
MD5 5b24351321c76201f828d7225b57d6b3
BLAKE2b-256 04a875ced3bd79f602d1c5e3f09ab3c10edac9e68bbf3f0c368e7184a5f60d60

See more details on using hashes here.

Provenance

The following attestation bundles were made for meetdub-0.1.0.tar.gz:

Publisher: release.yml on Yarta-AI/meetdub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file meetdub-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: meetdub-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meetdub-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fe6ed65961ab5075255c924703b39c8e90b994b25e5b1366ef289d8ffc30fca5
MD5 187a0e9d72c5308b5b6f92c0f58e7cc4
BLAKE2b-256 0b194e3fb388bbc3e61325ffe6de79d7f3ae53a233680cc93fba3d4952af2ef9

See more details on using hashes here.

Provenance

The following attestation bundles were made for meetdub-0.1.0-py3-none-any.whl:

Publisher: release.yml on Yarta-AI/meetdub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page