Files
abdulive/apps/overlay-server/README.md
T
ZeasyAlexandClaude Opus 5 bc2c8f6cbe Overlay: fuenf Browser-Sources fuer OBS
Einblendungen, Chat, Statusleiste, Effekte, Pausenbild. Kein Build, kein
Framework - OBS laedt die Dateien direkt, und jede Zwischenstufe waere ein
Ding, das mitten im Stream kaputtgehen kann.

Server-Sent Events statt WebSocket, entgegen der Skizze in chat-control.md:
Node bringt einen WebSocket-*Client* mit, aber keinen Server, `EventSource`
verbindet sich von allein neu, und die Richtung stimmt - das Overlay hoert
nur zu. Gegen die tote Browser-Source nach einem Neustart stehen drei Dinge:
der eingebaute Reconnect, ein Herzschlag als echtes Ereignis (ein
SSE-Kommentar haelt die Verbindung offen, ist im Browser aber unsichtbar),
und ein Zustands-Schnappschuss beim Verbinden.

Abos, Raids, Bits und Loeschungen kommen ueber IRC-USERNOTICE und CLEARCHAT
herein; das wurde bisher weggeworfen. Follows fehlen weiter, die gibt es nur
ueber EventSub.

GIFs im Chat: Twitch schickt dafuer einen Tag `gifs`, den wir nicht kannten.

  gifs=0-22|Pnd7qLFuGCOntZcNKB|https://media0.giphy.com/media/.../giphy.gif
  PRIVMSG #abdulive_ :[Idk GIF by Respective]

Der Nachrichtentext ist nur ein Platzhalter, der Bereich markiert ihn.
Ausgewertet wird er jetzt; ohne das stand woertlich "[Idk GIF by Respective]"
im Bild. Gefunden wurde der Tag durch einen Rohmitschnitt - in 3094
Nachrichten aus acht grossen Kanaelen war kein einziges GIF, weil die Adresse
eben nicht im Text steht.

Zwei Fehler, die beim Durchklicken im Browser aufgefallen sind:

- Die Aufraeumfunktion im Chat zaehlte Zeilen, die erst nach der
  Ausblend-Animation aus dem DOM verschwinden, und lief in eine
  Endlosschleife. In OBS waere die Quelle beim vierzehnten Chatbeitrag
  eingefroren.
- Der Bereichsparser der GIFs war zu nachsichtig: `-1-4` zerfaellt beim
  Trennen in ['', '1', '4'], und `Number('')` ist 0 - der Bereich saehe
  gueltig aus und wuerde den falschen Textteil ersetzen.

Auf der Uebersichtsseite steht fuer jede Einblendung, jede Chat-Variante und
jeden Effekt ein Knopf. Ohne den liesse sich eine Raid-Einblendung nur
pruefen, indem man auf einen echten Raid wartet. Was einen Zustand setzt, ist
waehrend eines Streams gesperrt; "Stand zuruecksetzen" ausdruecklich nicht,
sonst kaeme man aus einem erfundenen Zustand nicht mehr heraus.

build-package.ts nimmt jetzt auch html/css/js mit - sonst liefert das Paket
404 statt Overlay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 00:13:28 +02:00

51 lines
2.3 KiB
Markdown

# @abdulive/overlay-server
Der einzige Server, der von außen erreichbar ist. Liefert die Seiten aus
[`overlay-web`](../overlay-web/README.md) 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`](../../docs/projects/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](../../docs/decisions/ADR-0008-geteilter-betrieb.md).
- **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.