# @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`](public/theme.css) (Farben, Schrift, Kontur) und [`client.js`](public/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. | | `/sounds` | 400×120 | Spielt die Sounds vom Pult. Unsichtbar, **mit Ton**. | 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 bei Einblendungen.** Es liegen keine Audiodateien im Repo, und ein Overlay, das ungefragt Krach macht, ist schlimmer als eines, das still ist. Sounds gibt es nur auf Knopfdruck, über das Pult. ## Das Pult (`/pult`) Keine Browser-Source, sondern eine App fürs Handy: wie ein Stream Deck, nur ohne Hardware. Mit Passwort, wie die Übersicht. Im Browser des Handys „Zum Startbildschirm hinzufügen“ (iPhone) bzw. „App installieren“ (Android), dann startet es ohne Adressleiste. `manifest.webmanifest` und `sw.js` machen das möglich; der Service Worker hält nur die Hülle vor und beantwortet nie einen Knopfdruck aus dem Speicher. | Reiter | Was | |---|---| | Sounds | Tasten fürs Soundboard. „+ Sound“ lädt MP3, WAV, OGG, WebM oder M4A vom Handy hoch (bis 8 MB). „Bearbeiten“: Name, Emoji, Farbe, Lautstärke, Reihenfolge, Löschen, am Handy anhören. „Stopp“ bricht alle Sounds ab. | | Szenen | OBS-Szenen umschalten, Clip aus dem Wiedergabepuffer speichern, Toneingänge stumm schalten. Braucht den Stream-PC (siehe unten). | | Stream | Liegestütze zählen, Vorlesen freigeben, „Sofort still“. | | Test | Dieselben Testknöpfe wie auf der Übersicht. | Die Sonne oben rechts hält den Bildschirm an (Wake Lock), solange das Pult offen ist. **Sounds** liegen auf dem Hub neben der Datenbank (`/sounds/`), nicht im Repo und nicht unter `/opt/abdulive` - sie überleben jedes Ausrollen. Der Dateityp wird an den ersten Bytes erkannt; was kein Ton ist, wird abgelehnt. Gespielt wird in OBS über die Browser-Source `/sounds`, „Audio über OBS steuern“ an. Ist sie nicht verbunden, sagt das Pult es in Gelb. Höchstens vier Sounds gleichzeitig (`?max=`), `?laut=` dämpft alle. **Szenen** gehen über den Stream-PC, weil der Hub OBS nicht erreicht. Der PC wählt sich mit eigenem Schlüssel beim Hub ein (`apps/ingest/src/fern.ts` und `apps/overlay-server/src/fern.ts`). In OBS muss nur obs-websocket an sein - dasselbe, was `!clip` braucht. Einzurichten ist nichts. Beim ersten Start würfelt `ingest` einen Schlüssel und meldet sich bei `fern.url` (Vorgabe `https://abdu.dimension47.de`, `FERN_URL=` schaltet ab). Im Pult unter Szenen steht dann „Stream-PC … möchte sich verbinden“ mit **Freigeben**. Ein Tipp, nach ein paar Sekunden ist er da. „Stream-PC trennen“ unten im Reiter würfelt den Schlüssel neu; danach muss er neu freigegeben werden. `abdulive fern:verbinden ` bleibt als Weg von Hand (Befehl auf der Übersicht). Jeder Knopf wartet auf die Antwort von OBS und sagt ehrlich, wenn es nicht ging. **Die Sound-Quelle legt der PC selbst an.** Nach dem Verbinden schickt der Hub die Adresse von `/sounds` mit Schlüssel, und `ingest` legt in OBS an: - die Szene `abdulive Ton` mit der Browser-Source `abdulive Sounds` darin („Audio über OBS steuern“ an, beim Unsichtbarwerden nicht abschalten); - in **jeder** Szene ein Verweis auf `abdulive Ton`. OBS gibt Ton nur aus Quellen der gerade gezeigten Szene aus; so gibt es die Quelle einmal, sie läuft beim Szenenwechsel durch und ist überall zu hören. Neue Szenen bekommen den Verweis sofort, ein neuer Overlay-Schlüssel wird in die Quelle nachgetragen. Die Ton-Szene taucht im Pult nicht als Szene auf, die Quelle aber unter Ton - damit lässt sich das Soundboard stumm schalten. Wer den Verweis aus einer Szene löscht, bekommt ihn beim nächsten Start zurück. Die App-Symbole zeichnet `node scripts/make-icons.ts`. ## 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 im Hub mit Piper, nicht im Browser. Die eingebaute Sprachausgabe von OBS' Browser-Quelle sah keine deutsche Stimme und las amerikanisch; welche Stimmen es gibt, hängt am Rechner, der streamt. Piper läuft lokal im LXC, kostet nichts, und kein Zuschauertext verlässt das Haus. Die Seite holt sich die fertige WAV unter `/tts/audio/` und spielt sie über ein `