Files
abdulive/apps/overlay-server
ZeasyAlexandClaude Opus 5.5 63ea40d5a8 Vorlesen: Piper im Hub statt Sprachausgabe im Browser
In OBS' Browser-Quelle kam `speechSynthesis` amerikanisch heraus: der
eingebaute Browser sah keine deutsche Stimme, und die Seite nahm die erste
beliebige. Welche Stimmen es gibt, haengt am Rechner, der streamt.

Jetzt spricht der Hub mit Piper (lokal im LXC, 200 Zeichen in 0,7 s). Die
WAV liegt kurz im Speicher, `/tts` holt sie unter /tts/audio/<id> mit dem
Overlay-Schluessel und spielt sie ueber <audio> ab - das laeuft sicher ueber
OBS' Tonspur. Der Browser springt nur noch mit einer deutschen Stimme ein,
sonst wird nur angezeigt. Stimme und Sprecher stehen in rewards.tts.

Dazu:

- `abdulive rewards:anlegen`: Belohnung ueber die API anlegen. Nur die App,
  die sie angelegt hat, darf Einloesungen abschliessen oder erstatten.
- Einloesungen werden nach der Aktion als FULFILLED markiert, statt in
  Twitchs Warteschlange liegen zu bleiben.
- Wortfilter normalisiert vorher: Leetspeak, Punkte dazwischen, gezogene
  Buchstaben, Akzente. Kurze Eintraege nur am Wortanfang.
- Der Testknopf "Vorlesen" geht durch Piper und prueft so die echte Stimme.
- scripts/install-piper.sh richtet Piper und Stimme im LXC ein.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:58:36 +02:00
..

@abdulive/overlay-server

Der einzige Server, der von außen erreichbar ist. Liefert die Seiten aus overlay-web aus, hält den Ereignisstrom dorthin offen und bringt Einrichtung und OAuth-Rückruf unter dieselbe Adresse.

/              Übersicht mit den Adressen für OBS      Passwort
/setup         Einrichtung: Twitch-Apps, Tokens        Passwort
/callback      OAuth-Rückruf von Twitch                offen, `state` schützt
/alerts …      die Browser-Sources                     Schlüssel in der URL
/events        der Ereignisstrom dahinter              Schlüssel in der URL

Server-Sent Events statt WebSocket

chat-control.md skizziert einen WS-Kanal. Es sind SSE geworden, aus drei Gründen:

  1. Node bringt einen WebSocket-Client mit, aber keinen Server. Den müsste man selbst schreiben, inklusive Handshake und Rahmenformat - in einem Projekt ohne Abhängigkeiten heißt das: selbst pflegen.
  2. EventSource verbindet sich von allein neu. Die tote Browser-Source nach einem Neustart ist der häufigste Fehler bei solchen Overlays, und hier löst ihn der Browser.
  3. Die Richtung stimmt. Das Overlay hört nur zu; es sendet nie.

Drei Dinge halten die Verbindung ehrlich:

  • Herzschlag alle 15 s, als echtes Ereignis und nicht als SSE-Kommentar - ein Kommentar hält die Verbindung offen, ist im Browser aber unsichtbar.
  • Wachhund im Client: 45 s ohne Nachricht heißt neu verbinden. OBS hält eine tote Verbindung erstaunlich lange für lebendig.
  • Schnappschuss beim Verbinden: der letzte Stream-Zustand und die letzten Chatnachrichten, damit die Quelle nach dem Neuverbinden nicht leer im Bild steht.

Zugang

Siehe ADR-0008.

  • Passwort für alles, was ein Mensch bedient. Setzen mit abdulive web:passwort, nie über das Netz - ein Dienst, bei dem man das Passwort über die offene Weboberfläche setzen kann, hat kein Passwort.
  • Schlüssel in der Adresse für die Browser-Sources. Eine Browser-Source kann kein Formular ausfüllen. Der Schlüssel darf nur lesen und lässt sich auf der Übersichtsseite neu würfeln.

Ohne publicUrl bindet der Server weiter auf 127.0.0.1 und verhält sich wie vorher.