Files
christianandClaude Opus 5 c9eef0672c Church Translate, as it runs at the campuses
Live sermon translation into 100+ languages, running entirely on one Mac per
campus: audio in, voice detection, Whisper on the GPU, NLLB-200 in its own
process, and a built-in web server the congregation reads from on their
phones. No audio leaves the building.

This is the source only. What used to sit beside it — 14 GB of speech and
translation models, 8 GB of voice bundles, 6 GB of natural voices, the Electron
caches, and the app data holding the operator PIN and every service transcript
— is machine state and downloaded assets, and stays in the NAS backup where it
belongs. The vendored node, cloudflared and Windows ffmpeg binaries are out too
(533 MB, re-fetched for packaging); the browser-side runtime beside them is
kept, so a checkout still serves the congregation page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 15:41:21 -04:00

3.3 KiB

Stream Deck / Bitfocus Companion

One button starts and stops translation. That is the whole integration.


The button

In Companion:

  1. Connections → add Generic HTTP. No settings needed.
  2. Make a button. Add a press action: Generic HTTP → GET.
  3. Paste the toggle URL from the operator page (Stream Deck / Companion section — there is a Copy button):
http://127.0.0.1:3100/api/control/toggle?key=YOUR_TOKEN

Use 127.0.0.1 when Companion runs on the same Mac as the app, which is the normal case. If Companion is on a different machine, use that Mac's LAN address instead — the app shows it under What the congregation opens.

The token is per-campus. Copy it from the operator page → Stream Deck / Companion, which has a copy button for exactly this.

Set the button text to TRANSLATE. Done.

Separate start and stop URLs are on the operator page too if you'd rather have two buttons than one toggle.

The key is a password. Anyone who has it can start and stop translation for the whole congregation. Don't put it on a slide, and don't paste it into a group chat.


Making the button change colour

Worth doing — a volunteer should be able to tell at a glance whether it is running.

The server pushes its state into a Companion custom variable, so the button is always right the moment anything changes, including when translation was started from the operator page or stopped because the Mac engine quit.

First, switch Companion's HTTP API on. It ships disabled — checked on your Companion 5.0.4 and every API endpoint returns 404 until you enable it. In Companion: Settings → HTTP API → enable. (The button itself works without this; only the colour feedback needs it, because that is the server calling into Companion rather than Companion calling out.)

Then: Variables → Custom Variables → create one called translate_state.

On the operator page: set Companion address. When Companion runs on the same Mac as the app — the normal case — that is http://127.0.0.1:8000.

The variable will then hold one of:

Value Meaning Suggested colour
live Translating right now Red
ready Engine connected, standing by Green
offline The Mac engine is not running Dark grey / amber

Add feedbacks on the button: Internal → Custom variable value — one rule per value, each setting the background colour.

offline is the useful one. It tells the volunteer the Mac app is closed before the sermon starts, instead of after.


If you'd rather poll

There is also a plain-text endpoint that returns exactly one word:

http://127.0.0.1:3100/api/status.txt?key=YOUR_TOKEN

Returns live, ready, or offline. Use it with any control system that can fetch a string — it needs no JSON parsing.


Other control systems

Everything is plain HTTP GET, so anything that can fetch a URL can drive this: a browser bookmark, a shortcut on a phone, an AMX/Crestron panel, a curl in a script.

curl "http://127.0.0.1:3100/api/control/start?key=YOUR_TOKEN"
curl "http://127.0.0.1:3100/api/control/stop?key=YOUR_TOKEN"

Both return JSON describing the new state, including how many people are listening and in which languages.