Files
abdulive/apps/overlay-web
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
..

@abdulive/overlay-web

Die Browser-Sources für OBS. Fünf Seiten, alle mit durchsichtigem Hintergrund, alle an demselben Ereignisstrom.

Kein Build, kein Framework, keine Abhängigkeit: OBS lädt die Dateien direkt, und jede Zwischenstufe wäre ein Ding, das mitten im Stream kaputtgehen kann. Gemeinsam sind nur theme.css (Farben, Schrift, Kontur) und client.js (Verbindung, Escaping, Emotes).

Die Seiten

Adresse Größe Was sie zeigt
/alerts 1920×1080 Abos, Raids, Bits, Erstchatter. Eine nach der anderen, nie übereinander.
/chat 460×900 Chatnachrichten mit Emotes, Abzeichen, Farben.
/status 1920×160 Titel, Kategorie, Zuschauer, Laufzeit.
/effects 1920×1080 Emote-Regen bei Chat-Spitzen, Konfetti bei Abos und Raids.
/starting 1920×1080 Pausenbild als eigene Szene. Deckend, nicht durchsichtig.

Die fertigen Adressen mit Schlüssel stehen auf der Übersichtsseite (/).

In OBS

Je Seite eine Browser-Source anlegen, Adresse eintragen, Breite und Höhe setzen. Zwei Häkchen sind wichtig:

  • "Quelle beim Unsichtbarwerden deaktivieren" aus. Sonst verpasst das Overlay alles, was passiert, während eine andere Szene im Bild ist, und baut sich bei jedem Szenenwechsel neu auf.
  • "Browser beim Szenenwechsel aktualisieren" aus. Eine laufende Einblendung würde sonst mitten im Wechsel abgeschnitten.

Einstellungen über die Adresse

Es gibt keine Konfigurationsdatei. Was einstellbar ist, hängt hinten an der URL - so lässt es sich in OBS ändern, ohne den Dienst anzufassen.

Seite Parameter Vorgabe
alle probe=1 dunkler Hintergrund zum Ansehen im Browser
/alerts sekunden 7 - wie lange eine Einblendung steht
/alerts erstchatter=0 Erstchatter nicht einblenden
/chat max 14 - so viele Zeilen gleichzeitig
/chat sekunden 120 - danach verblasst eine Zeile (0 = nie)
/chat befehle=1 auch !-Befehle zeigen
/status kanal abdulive_
/effects max 260 - Obergrenze für Teilchen
/starting text, unter "Gleich geht es los", leer

Zum Ausprobieren

Auf der Übersichtsseite (/) steht unter Ausprobieren für jede Einblendung, jede Chat-Variante und jeden Effekt ein Knopf. Er löst ein erfundenes Ereignis aus, das nur an die Browser-Sources geht - nichts davon landet in der Datenbank, auf Discord oder bei Twitch.

Am besten die zu prüfende Seite über „ansehen" in einem zweiten Fenster offen haben. Dabei hilft ?probe=1: das legt einen dunklen Grund unter die sonst durchsichtige Seite.

Zwei Dinge sind gesperrt, solange ein Stream läuft: „Stream läuft" und die Vorführung. Beide setzen einen Zustand, der in der Statusleiste stehen bliebe, bis die nächste Twitch-Abfrage ihn geraderückt. „Stand zurücksetzen" ist absichtlich nie gesperrt - das ist der Weg aus einem erfundenen Zustand wieder heraus.

Dieselben Ereignisse im Dauerbetrieb, auch ohne laufenden Dienst:

abdulive overlay --demo

Erfundener Chat, alle neun Sekunden eine Einblendung, ab und zu eine Chat-Spitze. Ohne das ließe sich eine Raid-Einblendung nur prüfen, indem man auf einen echten Raid wartet.

Was fehlt

  • Follows. Kommen nicht über IRC, dafür braucht es EventSub. Bis dahin bleibt das Overlay bei Follows stumm; Abos, Raids und Bits kommen an.
  • BTTV- und 7TV-Emotes. Die hängen an einer zweiten API. Twitchs eigene Emotes werden angezeigt.
  • Töne. Es liegen keine Audiodateien im Repo, und ein Overlay, das ungefragt Krach macht, ist schlimmer als eines, das still ist.

Vorlesen (/tts)

Eigene Browser-Source, 600×200, mit Ton. In OBS darf „Audio über OBS steuern" nicht ausgeschaltet sein, sonst hört der Stream nichts.

Gesprochen wird über speechSynthesis, die im Browser eingebaute Sprachausgabe. Kein Cloud-Dienst, keine Kosten, kein Zuschauertext, der das Haus verlässt. Ob OBS' Browser-Quelle das kann, ist offen — CEF wird teils ohne Sprachausgabe gebaut. Die Seite prüft das beim Start und blendet einen roten Hinweis ein, wenn sie nicht sprechen kann; im Stream soll das auffallen und nicht stillschweigend fehlen.

Einstellungen: ?sprache=de-DE, ?tempo=1, ?laut=1.

Vorgelesen wird nur, was auf der Übersichtsseite freigegeben wurde. Nach einem Neuverbinden wird nichts nachgeholt — eine Nachricht von vor zehn Minuten vorzulesen ist schlimmer, als sie zu verpassen.