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>
@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.