Paket bauen und veroeffentlichen / paket (push) Successful in 42s
- ingest wuerfelt beim ersten Start einen Schluessel und meldet sich beim Hub; der antwortet 202, bis im Pult jemand auf Freigeben tippt - nach dem Verbinden schickt der Hub die Adresse von /sounds, ingest legt Szene "abdulive Ton" mit der Browser-Source an und haengt sie in jede Szene - fern:verbinden bleibt als Weg von Hand Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
171 lines
8.2 KiB
Markdown
171 lines
8.2 KiB
Markdown
# @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 (`<db>/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 <adresse> <schlüssel>` 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/<id>` und spielt sie
|
||
über ein `<audio>` ab, das sicher über OBS' Tonspur läuft.
|
||
|
||
Kann der Hub nicht sprechen, springt `speechSynthesis` ein, aber nur mit
|
||
einer deutschen Stimme. Gibt es keine, wird die Nachricht nur angezeigt,
|
||
mit rotem Hinweis.
|
||
|
||
Stimme und Sprecher: `rewards.tts.stimme` und `rewards.tts.sprecher` in der
|
||
Konfiguration, eingerichtet mit `scripts/install-piper.sh`.
|
||
|
||
Einstellungen: `?laut=1` (0 bis 1). Besser im OBS-Mixer regeln.
|
||
`?sprache=de-DE` und `?tempo=1` gelten nur für den Notnagel im Browser.
|
||
|
||
Mit `freigabe: true` wird nur vorgelesen, 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.
|