DEV Community

Cover image for Babel Ears: A macOS Speech Translator Born From Conference Prep
Yuuki Yamashita
Yuuki Yamashita

Posted on

Babel Ears: A macOS Speech Translator Born From Conference Prep

I'm speaking at AWS Community Day Singapore on August 22nd. Great excuse to visit Singapore, but it also means I'll be sitting through a full day of talks in a room where I'm not always the strongest English listener. So a few weeks ago I built myself a tool to help with that, and it slowly grew into something bigger than I expected.

Where it started

I wanted something that would sit next to me during sessions, listen to the speaker, and show me a Japanese translation in near real time. Ideally without sending my recordings anywhere.

I found minorun365/live-translator-macos, a macOS app that does exactly this using Apple's on-device Speech and Translation frameworks. Fixed English-to-Japanese pair, clean SwiftUI interface, nothing leaves the Mac. It was a good starting point, so I used it as a reference and started extending it for what I actually needed.

What it turned into

Once I started poking at it, one addition led to another. A few weeks later the thing I'm using now, which I ended up naming Babel Ears, looks like this:

  • Any language pair, chosen at runtime. Not just English↔Japanese — whatever Apple's Speech and Translation frameworks support on your Mac, picked from two independent dropdowns.
  • A transcript-only mode. Pick the same language for listening and translation, and it skips translation entirely and just shows you the raw transcript. Turns out that's handy for taking notes during Japanese meetings too.
  • An online option. Everything still runs on-device by default. But there's a toggle to switch translation and summarization to Amazon Bedrock — Claude Haiku 4.5 for translation, Claude Opus 4.5 for the rolling 5-minute summary — for when I want a second opinion or better handling of a tricky language pair. Only the transcribed text goes to AWS, never the audio.
  • Copy and export. Each panel has a copy button, and the whole session can be downloaded as TXT or PDF.
  • A UI I actually enjoy looking at. I rebuilt the interface a few times — first a dark glass look, then a lighter one — before landing on a white, slightly playful design that doesn't feel like a stock macOS utility.

Here's roughly how it's wired together:

Speech recognition always runs on-device through Apple's SpeechAnalyzer/SpeechTranscriber. Translation and summarization are the only steps that can optionally go online.

Three things that didn't work the first time

Command Line Tools weren't enough. I started building on a Mac with only Xcode Command Line Tools installed, and the build failed with a cryptic error about SwiftUIMacros not being found. Turns out SwiftUI's macros (@State and friends) need the full Xcode.app, not just the CLT — the macro plugin isn't shipped with CLT alone. Installing Xcode fixed it immediately.

aws login credentials weren't where I expected. For the Bedrock option, I wrote a small SigV4 signer so the app wouldn't need the full AWS SDK. My first version read credentials from ~/.aws/credentials, which worked fine from my terminal but failed every time from the app with "credentials not found." It turned out aws login (the newer browser-based sign-in flow) caches its session somewhere else entirely. Running aws configure export-credentials resolves credentials correctly regardless of which provider issued them, so I shelled out to that instead.

Bedrock kept rejecting my signature. Even after fixing credentials, every Bedrock call came back with a 403 and "the request signature we calculated does not match the signature you provided." AWS's error response conveniently includes the canonical string it expected, and comparing it to mine showed the difference: my model ID had %3A in it (from URL-encoding the colon in us.anthropic.claude-haiku-4-5-20251001-v1:0), but the canonical request needed that % encoded again, as %253A. Most AWS services expect the canonical URI to be double-encoded — S3 is the well-known exception, and I'd assumed the same exception applied elsewhere. It doesn't.

Thanks

None of this happens without minorun365's live-translator-macos as a starting point — the core idea of doing everything with Apple's on-device Speech and Translation frameworks, keeping recordings local, came straight from that project. I starred it, and if you're looking for a clean single-language-pair translator without all the extra knobs I added, it's a great choice on its own.

Closing

The app is still just for me right now, but it's already doing its job: I've used it to follow a couple of English tech talks in the weeks since, and I'm bringing my laptop to Singapore in a few weeks to see how it holds up in a real conference room. If you want to see the code, the on-device/AWS switch, or the SigV4 signer, it's on GitHub.

Thanks for reading.

Top comments (0)