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>
51 lines
2.3 KiB
Markdown
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.
|