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>
100 lines
3.3 KiB
Markdown
100 lines
3.3 KiB
Markdown
# 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.
|
|
|
|
```bash
|
|
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.
|