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>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# Letting people off-site watch
|
||||
|
||||
**Optional.** Everything works on the building's WiFi without any of this. Read
|
||||
on only if you want people on cell data, or watching from home, to follow along.
|
||||
|
||||
Because each campus runs its own copy, this is a per-campus decision — you can
|
||||
publish one campus and not another.
|
||||
|
||||
---
|
||||
|
||||
## The easy way: Cloudflare Tunnel
|
||||
|
||||
Free, needs no port forwarding, no firewall changes, no certificate, and no
|
||||
static IP. It runs on the same Mac as the app.
|
||||
|
||||
1. **Install cloudflared**
|
||||
|
||||
```bash
|
||||
brew install cloudflared
|
||||
```
|
||||
|
||||
No Homebrew on that Mac? Download the `cloudflared-darwin-arm64.tgz` binary
|
||||
from Cloudflare's releases page and drop it in `/usr/local/bin`.
|
||||
|
||||
2. **Log in and create the tunnel**
|
||||
|
||||
```bash
|
||||
cloudflared tunnel login
|
||||
cloudflared tunnel create translate-main
|
||||
```
|
||||
|
||||
3. **Point a hostname at the app**
|
||||
|
||||
```bash
|
||||
cloudflared tunnel route dns translate-main translate.watersmedia.org
|
||||
```
|
||||
|
||||
4. **Run it**
|
||||
|
||||
```bash
|
||||
cloudflared tunnel run --url http://127.0.0.1:3100 translate-main
|
||||
```
|
||||
|
||||
To keep it running after a reboot, `sudo cloudflared service install`.
|
||||
|
||||
5. **Tell the app its public name**
|
||||
|
||||
Operator page → **Public address** → `https://translate.watersmedia.org` →
|
||||
Save. That is what the QR code encodes, so it must be the public name or the
|
||||
code only works for people already on your WiFi.
|
||||
|
||||
WebSockets pass through Cloudflare tunnels with nothing extra to configure,
|
||||
which is the main reason this is the lower-risk option.
|
||||
|
||||
For a second campus, repeat with its own name — `translate-north`,
|
||||
`north.translate.watersmedia.org`.
|
||||
|
||||
---
|
||||
|
||||
## The other way: your existing nginx proxy
|
||||
|
||||
You already run a reverse proxy at `10.1.1.4` fronting `check.watersmedia.org`,
|
||||
with split-horizon DNS. It can front this too, though it means the traffic goes
|
||||
through the NAS network to reach the booth Mac.
|
||||
|
||||
Add a DNS record for `translate.watersmedia.org` — public to your WAN address,
|
||||
internal to `10.1.1.4` — and a server block. Copy the one that already serves
|
||||
the checklist app, change the name, and point it at the **booth Mac**, not the
|
||||
NAS:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name translate.watersmedia.org;
|
||||
|
||||
ssl_certificate /path/to/fullchain.pem;
|
||||
ssl_certificate_key /path/to/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.6.3.222:3100; # the booth Mac
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
|
||||
# ---- required: captions ride a WebSocket ----
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# A sermon is long and mostly silent between sentences. Without this the
|
||||
# proxy closes the caption socket after 60s of quiet and every phone in
|
||||
# the room reconnects at once.
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This has one real drawback the tunnel does not: the booth Mac needs a fixed
|
||||
address on the network, or the proxy breaks the next time DHCP moves it.
|
||||
|
||||
---
|
||||
|
||||
## Checking it worked
|
||||
|
||||
```bash
|
||||
curl -s https://translate.watersmedia.org/healthz
|
||||
```
|
||||
|
||||
Should return `{"ok":true,…}`. Then open the page on a phone **with WiFi turned
|
||||
off** — that is the real test. If the page loads but captions never appear, the
|
||||
WebSocket headers are missing.
|
||||
Reference in New Issue
Block a user