3.8 KiB
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.
Ny maskin (Debian/Ubuntu/Mint): git clone https://git.1x1.no/kent/sg-announcer.git
og ./install.sh gjør alt (apt, uv, Python 3.13, stemmer, enhet, ufw). Finnes
NetBird (wt0) skrur det på ufw med deny incoming og åpner 22 og porten kun
på wt0. Kan
kjøres på nytt. Avspilling bruker pw-play når PipeWire kjører, ellers
paplay (player_cmd()), så Mint 21 med PulseAudio virker også.
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/previewsyntetiserer og returnerer WAV til nettleseren. Ingen lyd på PC-en./api/announcelegger meldingen i én FIFO-kø; en bakgrunnstråd spiller én om gangen medpw-play./api/stopdreper gjeldende avspilling,/api/cleartø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. - Jingler: de innebygde (
BUILTIN_CHIMES) genereres i Python med_tone/_mix/_overlay, ingen lydfiler. Egne filer ichimes/(wav/mp3/ogg/flac) dukker opp i menyen somfile:<stem>; ffmpeg kutter til 6 s, normaliserer til -18 LUFS og fader ut. Mappa leses ved hver forespørsel, så nye filer vises uten restart. Toppnivå på de innebygde ligger mellom -4 og -10 dBFS, talen går til 0 dBFS, så jinglen skal aldri være høyere enn stemmen.
Stemmer og motorer
VOICES_LIST i announcer.py er eneste sted en stemme legges til. To motorer:
- edge (
_edge): Microsofts nevrale stemmer viaedge-tts-pakken. Gratis, ingen nøkkel, men krever internett og er en uoffisiell bruk av Edge sin «les høyt»-tjeneste – kan slutte å virke uten varsel. Norsk: barenb-NO-FinnNeuralognb-NO-PernilleNeural.*MultilingualNeural-stemmene kan lese norsk med engelsk aksent. Liste:uv run edge-tts --list-voices. Leverer MP3 24 kHz; dekodes med ffmpeg til PCM iedge_pcm(). - piper (
_piper): lokalt, robotaktig, reserve når nettet er nede. Modellen lastes ned ved oppstart tilvoices/(gitignored). Norsk finnes bare somtalesyntese-mediumognvcc-medium(ti talere,speaker-indeks). Full liste:https://huggingface.co/rhasspy/piper-voices/resolve/main/voices.json.
Vil Kent ha enda bedre lyd: ElevenLabs (nøkkel, best norsk) eller OpenAI
gpt-4o-mini-tts er neste trinn; legg til som ny motor i synthesize().
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.pyfra et skall som selv harannouncer.pyi kommandolinja dreper skallet. Bruksystemctl --user.- Piper 1.8 bruker
SynthesisConfig(length_scale=…); lavere = raskere. - Forhåndslytt svarer 502 med feilmelding hvis edge-tts feiler (ingen nett).
Køen markerer meldingen som
failed. Bytt til en lokal reserve-stemme.