SG Announcer: Piper-TTS-utroper med forhåndslytt og kø

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kent 2026-10-06 03:18:13 +02:00
commit 1c3e17afa0
8 changed files with 971 additions and 0 deletions

45
AGENTS.md Normal file
View file

@ -0,0 +1,45 @@
# sg-announcer – utrop på høyttaleranlegget (Sauda Gathering)
Liten Flask-app: tekst inn i nettleseren → forhåndslytt → «Send ut på
anlegget» spiller lyden lokalt på **denne** maskinen med `pw-play`. TTS er
Piper (`piper-tts`, onnx, helt lokalt). Alt ligger i to filer:
`announcer.py` (server + kø) og `index.html` (sida).
Dokumentasjon for Kent: Athena-notatet
`30 Ressurser/Teknologi/Sauda Gathering - announcer.md`. Oppdater det, ikke
denne fila, når noe som er verdt å huske endres.
## Kjøring
Tjenesten er en systemd-brukerenhet: `~/.config/systemd/user/sg-announcer.service`
(enabled, port 8090). `systemctl --user restart sg-announcer` etter endringer
i koden. Manuelt: `uv run announcer.py --port 8090`.
Miljøvariabler (settes i enheten): `ANNOUNCER_PORT`, `ANNOUNCER_PIN` (tom =
ingen PIN), `ANNOUNCER_SINK` (pw-play `--target`; tom = standard utgang).
## Hvordan det henger sammen
- `/api/preview` syntetiserer og returnerer WAV til nettleseren. Ingen lyd på PC-en.
- `/api/announce` legger meldingen i én FIFO-kø; en bakgrunnstråd spiller én
om gangen med `pw-play`. `/api/stop` dreper gjeldende avspilling, `/api/clear`
tømmer køen.
- Knappen «Send ut» er låst til nøyaktig den teksten/stemmen/hastigheten som
sist ble forhåndslyttet. Det er med vilje: ingen skal sende noe de ikke har hørt.
- Ferdige WAV-er bufres i `cache/` etter innholdshash. Trygt å slette.
- Chimen («ding-dong») genereres i Python, ingen lydfil.
## Stemmer
`VOICES` i `announcer.py` er eneste sted en stemme legges til. Navnet er
Piper-ID-en (`<lang>-<navn>-<kvalitet>`); fila lastes ned fra
rhasspy/piper-voices ved første oppstart til `voices/` (gitignored, ~63 MB
per stemme). Norsk: `no_NO-talesyntese-medium` er den eneste norske Piper-stemmen.
## Feller
- **ufw**: appen kjører nativt, så Docker-smutthullet gjelder ikke. Porten må
åpnes eksplisitt for LAN-et (`sudo ufw allow from 10.20.70.0/23 to any port 8090 proto tcp`).
- `pkill -f announcer.py` fra et skall som selv har `announcer.py` i
kommandolinja dreper skallet. Bruk `systemctl --user`.
- Piper 1.8 bruker `SynthesisConfig(length_scale=…)`; lavere = raskere.