Docker faellt weg. Das Projekt hat keine npm-Abhaengigkeiten und Node fuehrt TypeScript direkt aus - der Container schrieb nur noch drei Programme fest, und dafuer braucht es keine Virtualisierung, sondern einen Ordner. Der Anlass war, dass ADR-0004 zwar `docker compose pull` versprach, es aber nie ein veroeffentlichtes Image gab. Wer installieren wollte, musste whisper.cpp aus dem Quelltext uebersetzen. Plattformschicht (packages/core/src/platform.ts): - Programme werden neben der Anwendung gesucht, nicht im PATH - Daten unter %LOCALAPPDATA%, damit Installation und Update ohne Administratorrechte auskommen - Schriften mitgeliefert: ohne fontsdir setzt libass wortlos eine Ersatzschrift ein - gemessen 720 statt 826 Pixel Zeilenbreite Windows-Eigenheiten, an echtem ffmpeg 8.1 durchprobiert: - Pfade im Filtergraphen brauchen alle drei Schritte (Vorwaertsschraegstriche, escapter Doppelpunkt, Anfuehrungszeichen); je zwei davon reichen nicht - `nice` gibt es nicht, ersetzt durch os.setPriority Auslieferung: - scripts/build-package.ts baut das Paket, laeuft auch unter Linux - install.ps1 ohne Administratorrechte, Autostart ueber den Aufgabenplaner - update legt neue Fassungen bereit; eingespielt wird beim naechsten Start, nie mitten im Stream - ZIP lesen und schreiben ohne Abhaengigkeiten (packages/core/src/zip.ts) Kein `irm ... | iex`-Einzeiler: git.zeasy.dev antwortete instanzweit mit einer Umleitung auf /user/login, und `iex` fuehrte die Anmeldeseite als PowerShell aus. Der Updater verfolgt Umleitungen jetzt nicht und hat keine erfundene Vorgabeadresse mehr. Ausserdem: backup.ps1 war an zwei Stellen dokumentiert, aber nie geschrieben. ADR-0007 ersetzt ADR-0004. 84 Tests, Typpruefung sauber. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhVSfMFdWnXKCv5JfLnArZ
328 lines
16 KiB
Markdown
328 lines
16 KiB
Markdown
# MVP-Paket: „Clip-Knopf"
|
||
|
||
**Ziel in einem Satz:** Nach jedem Stream liegen fertige 9:16-Videos mit
|
||
eingebrannten Untertiteln zur Auswahl bereit — Abdu klickt zwei davon an und
|
||
lädt sie hoch.
|
||
|
||
Begründung der Auswahl: [`06-hebel-analyse.md`](06-hebel-analyse.md).
|
||
Detailspezifikation: [`projects/clip-shorts.md`](projects/clip-shorts.md).
|
||
|
||
## Warum genau dieser Zuschnitt
|
||
|
||
Der spürbare Effekt entsteht nicht dadurch, dass ein Clip *entsteht* — das kann
|
||
Twitch selbst. Er entsteht dadurch, dass die Strecke von „das war lustig" bis
|
||
„fertiges Short liegt bereit" von 30 Minuten Handarbeit auf 0 Minuten fällt.
|
||
Genau diese Strecke ist der MVP. Alles, was nicht auf dieser Strecke liegt,
|
||
fliegt raus.
|
||
|
||
Das MVP ist bewusst **ein einziger Prozess in einem einzigen Container**. Die in
|
||
[`01-architecture.md`](01-architecture.md) beschriebene Aufteilung in Ingest,
|
||
Overlay-Server und Konsumenten kommt erst, wenn es einen zweiten Konsumenten
|
||
gibt. Vorher ist sie nur Ballast.
|
||
|
||
## Rahmenbedingungen (geklärt)
|
||
|
||
| Punkt | Stand |
|
||
|---|---|
|
||
| Zielmaschine | Abdus Stream-PC, dort wo OBS läuft — alles lokal |
|
||
| OBS-Layout | Facecam bündig oben links, 440×330 — **eingemessen**, siehe unten |
|
||
| GPU | keine NVIDIA-Karte → CPU-Encoding mit libx264 |
|
||
| Untertitel | whisper.cpp (Binary, kein Python) statt faster-whisper |
|
||
| Betrieb | Docker Compose, siehe [ADR-0004](decisions/ADR-0004-docker.md) |
|
||
|
||
## Fortschritt
|
||
|
||
| Scheibe | Stand |
|
||
|---|---|
|
||
| S0 Container + Toolchain | **fertig** — Image 258 MB, `check-env` ohne harte Fehler |
|
||
| Layout eingemessen | **fertig** — `config/layout.yaml`, vorgezogen aus S3 |
|
||
| S1 Einrichtung + Auth + DB + IRC-Ingest | **fertig** — 20 Tests grün, Daemon läuft |
|
||
| S2 OBS-Anbindung + Trigger | **Code fertig**, Abnahme braucht laufendes OBS |
|
||
| S3 9:16-Render | **fertig** — Durchlauf verifiziert |
|
||
| S4 Untertitel | **fertig** — an echtem Clip verifiziert, 53 Tests grün |
|
||
| S5 Onboarding + Sichtung | als Nächstes |
|
||
| S6 Erstchatter-Begrüßung | offen |
|
||
| OBS-Layout vorgegeben | **fertig** — [`obs-layout.md`](obs-layout.md) |
|
||
|
||
**S1 abgenommen am 2026-09-09.** Der Daemon läuft, hängt am Chat, die
|
||
Einrichtung ist unter `http://localhost:4792/setup` erreichbar.
|
||
|
||
Beim Bauen hat sich die Technikbasis vereinfacht: Node 24 bringt SQLite,
|
||
WebSocket, `fetch` und die Ausführung von TypeScript mit, deshalb hat das
|
||
Projekt **null Laufzeitabhängigkeiten und keinen Build-Schritt**. pnpm-Workspaces
|
||
und die Paketmanifeste sind entfallen. Siehe Nachtrag 2 in
|
||
[ADR-0001](decisions/ADR-0001-monorepo-typescript.md).
|
||
|
||
Nachgewiesen:
|
||
|
||
- 20 Tests grün (IRC-Parser, Spike-Detektor, Datenbankschicht)
|
||
- Chat verbindet sich **anonym**, solange keine Zugangsdaten hinterlegt sind —
|
||
damit lässt sich die Datenaufnahme prüfen, bevor die Twitch-Apps existieren
|
||
- Zugangsdaten überstehen die Runde durch die Einrichtungsseite, liegen
|
||
verschlüsselt mit Rechten `0600` im Volume, tauchen weder im HTML noch in der
|
||
Datenbank noch in einer Volltextsuche im Klartext auf
|
||
- Was noch aussteht: die Strecke IRC → Datenbank im Livebetrieb. Die Teile sind
|
||
einzeln getestet, die Verdrahtung wird beim ersten echten Stream sichtbar.
|
||
|
||
**S0 abgenommen am 2026-09-09.** Im Image: Node 22.23, ffmpeg 5.1.9 mit
|
||
libx264 und libass, whisper.cpp v1.7.4, Sprachmodell `ggml-small` geladen.
|
||
`check-env` prüft Werkzeuge, Volumes, Layout-Geometrie, OBS-Erreichbarkeit und
|
||
Zugangsdaten; die verbleibenden Warnungen (OBS nicht erreichbar, noch keine
|
||
Zugangsdaten hinterlegt) sind auf dieser Entwicklungsmaschine erwartbar.
|
||
|
||
`calibrate` wurde mit einem echten 1920×1080-Bild durchgespielt: 1080×1920
|
||
heraus, Ausschnitte an der richtigen Stelle. Damit ist der Filtergraph für S3
|
||
bereits verifiziert, bevor S3 anfängt.
|
||
|
||
Das Einmessen der Facecam war eigentlich Teil von S3, ließ sich aber aus dem
|
||
gelieferten Screenshot sofort erledigen. Dabei kamen zwei Dinge heraus, die das
|
||
geplante Layout verändert haben — **der Chat ist ins Streambild eingebrannt**
|
||
und **die Facecam ist 4:3, nicht 16:9**. Beides ist in
|
||
[`projects/clip-shorts.md`](projects/clip-shorts.md) dokumentiert und in
|
||
`config/layout.yaml` aufgelöst.
|
||
|
||
## Umfang
|
||
|
||
### Drin
|
||
|
||
- Trigger: `!clip` im Chat **und** OBS-Hotkey (über `ReplayBufferSaved`)
|
||
- Quelle: OBS-Replay-Buffer, parallel dazu ein Twitch-Clip für die teilbare URL
|
||
- Render: 1080×1920, Facecam oben, Gameplay unten, fester Crop aus Config
|
||
- Untertitel: whisper.cpp deutsch → SRT → ASS mit wortweisem Highlight → eingebrannt
|
||
- Ablage: `data/clips/<datum>/<clip-id>/` mit `final.mp4`, Transkript, Metadaten
|
||
- Sichtung: eine statische HTML-Seite mit Vorschau, Score und zwei Knöpfen
|
||
- Nebenbei: Chat, Zuschauerzahlen und Nutzer werden ab Tag 1 in die DB
|
||
geschrieben, auch wenn im MVP noch nichts damit passiert
|
||
|
||
### Bewusst draußen
|
||
|
||
| Nicht im MVP | Warum |
|
||
|---|---|
|
||
| EventSub | Für den Clip-Weg reicht IRC plus Helix-Polling. Spart einen ganzen Verbindungstyp mit Reconnect-Logik. |
|
||
| Event-Bus über WebSocket | Es gibt nur einen Prozess. Funktionsaufrufe genügen. |
|
||
| Dashboard mit Framework | Eine statische HTML-Seite reicht für zehn Videos. |
|
||
| Spike-Trigger scharf | Läuft mit und protokolliert, löst aber nichts aus — Schwelle wird erst an echten Daten kalibriert. |
|
||
| Automatischer Upload | Die Auswahl ist ohnehin manuell. Kein Gewinn, viel API-Aufwand. |
|
||
| Overlay, Punkte, Recap, Raid | Eigene Meilensteine. |
|
||
|
||
## Die sieben Scheiben
|
||
|
||
Jede Scheibe ist einzeln lauffähig und einzeln überprüfbar. Am Ende jeder
|
||
Scheibe gibt es etwas, das man anschauen kann.
|
||
|
||
### S0 — Container und Toolchain · ~1 Tag
|
||
|
||
`docker/Dockerfile` (Node 22, ffmpeg mit libx264 + libass, whisper.cpp),
|
||
Paketbau, Installer und Updater, Modell-Download bei der Einrichtung
|
||
in ein eigenes Volume, `scripts/check-env` als Selbsttest im Container.
|
||
|
||
**Fertig, wenn:** `abdulive check-env` meldet ffmpeg,
|
||
whisper.cpp, Modell und die Schreibrechte auf allen Volumes als OK.
|
||
|
||
### S1 — Einrichtung, Auth und Datenaufnahme · ~3 Tage
|
||
|
||
**Einrichtungs-Assistent** auf `http://localhost:4792/setup`: Client-ID und
|
||
-Secret werden dort eingegeben, nicht in eine Datei. Verschlüsselter
|
||
Secret-Speicher im Volume, OAuth-Flow mit Rücksprung auf denselben Port,
|
||
Token-Refresh. Siehe [ADR-0005](decisions/ADR-0005-zugangsdaten.md).
|
||
|
||
Dazu Helix-Client mit Rate-Limit-Bucket, DB-Migrationen für `streams`, `users`,
|
||
`user_streams`, `chat_messages`, `viewer_samples`, `clips`, ein IRC-Client, der
|
||
jede Nachricht schreibt, und Stream-Sessions über Helix-Polling im Minutentakt.
|
||
|
||
> Der Assistent war ursprünglich nicht eingeplant und kostet etwa einen Tag
|
||
> mehr. Dafür entfällt der `.env`-Schritt aus der Inbetriebnahme komplett.
|
||
|
||
**Fertig, wenn:** Nach einem echten Stream stehen alle Nachrichten in
|
||
`chat_messages` und eine korrekte Zeile in `streams`.
|
||
|
||
> Diese Scheibe ist der Teil ohne sichtbaren Effekt — und trotzdem der, den man
|
||
> nicht verschieben darf. Was hier nicht mitgeschrieben wird, ist für immer weg.
|
||
|
||
### S2 — OBS-Anbindung und Trigger · ~1 Tag
|
||
|
||
obs-websocket v5 über `host.docker.internal:4455`, Reconnect-Schleife.
|
||
`SaveReplayBuffer` auslösen, auf `ReplayBufferSaved` warten, Dateipfad vom
|
||
Windows-Pfad auf den Container-Mount abbilden. Trigger: `!clip` im Chat
|
||
(Cooldown 60 s global, 300 s pro Nutzer, nur Follower) und der OBS-Hotkey.
|
||
Parallel `POST /helix/clips`, Ergebnis-ID in `clips` nachtragen.
|
||
Bestätigung im Chat, genau eine pro Auslösung.
|
||
|
||
**Fertig, wenn:** `!clip` im laufenden Stream erzeugt binnen 5 s eine
|
||
`raw.mp4` im Ablageordner und eine Chat-Rückmeldung.
|
||
|
||
**Stand 2026-09-09:** Code steht und ist getestet, soweit es ohne OBS geht —
|
||
obs-websocket-Client mit Anmeldung und Wiederverbindung, Pfadübersetzung
|
||
Windows → Container, Abklingzeiten, Twitch-Clip parallel, Übernahme der Rohdatei
|
||
mit Warten auf fertigen Schreibvorgang. Der OBS-Hotkey wird ohne unseren Umweg
|
||
erkannt und als vollwertiger Auslöser behandelt.
|
||
|
||
Die **Abnahme steht aus**: Auf dieser Entwicklungsmaschine läuft kein OBS. Was
|
||
geprüft ist: Anmeldeverfahren (gegen eine unabhängige Zweitimplementierung),
|
||
Pfadübersetzung in allen vier Fällen, Warten auf die fertige Datei. Was
|
||
ungeprüft bleibt: das tatsächliche Gespräch mit einem laufenden OBS.
|
||
|
||
### S3 — 9:16-Render · ~1,5 Tage
|
||
|
||
`calibrate`-Kommando: zieht einen Frame aus einer Replay-Datei, schreibt ihn
|
||
als PNG raus, nimmt die vier Crop-Werte entgegen und legt sie in
|
||
`config/layout.yaml` ab. Render-Schritt mit dem Filtergraph aus
|
||
[`projects/clip-shorts.md`](projects/clip-shorts.md), Kopie der Rohdatei ins
|
||
Arbeitsvolume vor der Verarbeitung.
|
||
|
||
**Fertig, wenn:** Aus einer Replay-Datei entsteht eine `vertical.mp4` mit
|
||
korrekt sitzender Facecam oben und Gameplay unten.
|
||
|
||
**S3 abgenommen am 2026-09-09.** Verifiziert an einer künstlichen Aufnahme, die
|
||
eine OBS-Aufzeichnung nachbildet: 1920×1080, 70 s, drei getrennte Tonspuren
|
||
(Mischung, Mikrofon, Spiel). Ergebnis 1080×1920, 45 s, Naht bei y = 512 an der
|
||
richtigen Stelle, Rechenzeit 27,9 s bei `nice 15` — also gut zwei Drittel der
|
||
Echtzeit auf einer CPU ohne Grafikbeschleunigung.
|
||
|
||
Dabei aufgefallen und korrigiert: S2 hat die Rohdatei in den Windows-Bind-Mount
|
||
kopiert und dort verarbeitet — genau das, was [ADR-0004](decisions/ADR-0004-docker.md)
|
||
Punkt 2 verbietet. Jetzt liegt die Rohdatei im Arbeits-Volume, und auf die
|
||
Windows-Seite kommt nur das fertige, kleine Ergebnis.
|
||
|
||
Neu dazu: `abdulive render <datei>` rendert eine Rohdatei
|
||
von Hand — gedacht zum Nachrendern, wenn sich das Layout ändert.
|
||
|
||
### S4 — Untertitel · ~1,5 Tage
|
||
|
||
**Nur die Mikrofonspur** extrahieren (OBS nimmt getrennt auf: Mikro Spur 2,
|
||
Spielton Spur 3, Mischung Spur 1) als 16 kHz Mono WAV, whisper.cpp mit
|
||
`ggml-small` und `--language de`, Ausgabe als SRT mit Wort-Zeitstempeln,
|
||
Umwandlung in ASS mit wortweisem Highlight, Stil aus
|
||
`config/subtitle-style.ass`, Einbrennen. Sicherheitsabstand nach unten
|
||
mindestens 320 px. Ins Video kommt weiterhin die Mischung von Spur 1.
|
||
|
||
**Fertig, wenn:** `final.mp4` hat lesbare, zeitlich passende deutsche
|
||
Untertitel, und der Text wird auf dem Handy von der TikTok-Oberfläche nicht
|
||
verdeckt.
|
||
|
||
**S4 abgenommen am 2026-09-09**, geprüft an einem echten 30-Sekunden-Clip mit
|
||
deutscher Sprache. 41 Wörter in 37 s Rechenzeit auf der CPU, Transkript
|
||
inhaltlich korrekt, Untertitel sitzen zeitlich und sind lesbar.
|
||
|
||
Drei Fehler kamen erst am echten Material heraus:
|
||
|
||
- **Ein-Wort-Zeilen.** Bei zögerndem Sprechen zerfiel der Text in Zeilen mit
|
||
einem einzigen Wort („Dank" / „es," / „Savina,"). Die Obergrenze von 2,2 s je
|
||
Zeile war zu eng; jetzt 3,2 s plus ein Nachverdichten, das allein stehende
|
||
Wörter an den Nachbarn hängt. 17 Zeilen wurden zu 10.
|
||
- **Überlappende Zeilen.** Der Nachlauf von 0,25 s ragte in die nächste Zeile.
|
||
ASS stapelt gleichzeitig sichtbare Zeilen übereinander — das sieht kaputt
|
||
aus. Das Ende wird jetzt am Beginn der Folgezeile abgeschnitten.
|
||
- **Zeitformat.** Bei 59,999 s rundeten die Hundertstel auf 100 und der Übertrag
|
||
lief nicht in die Minuten: `0:00:60.00` statt `0:01:00.00`. Gefunden durch
|
||
einen Test, nicht durch Zusehen.
|
||
|
||
**Befund fürs Streamsetup:** Im Quellmaterial lagen bereits zwei Textebenen
|
||
(Spieluntertitel und ein Live-Caption-Overlay mit Wort-Markierung). Beide sind
|
||
fest eingebrannt. Behandelt in [`obs-layout.md`](obs-layout.md).
|
||
|
||
### S5 — Oberfläche: Onboarding und Sichtung · ~2 Tage
|
||
|
||
**Erststart-Assistent.** Die heutige Einrichtungsseite ist ein Formularblock —
|
||
das reicht für mich, nicht für Abdu. Der Assistent führt durch sechs Schritte
|
||
und **prüft jeden davon live**, statt zu behaupten, es sei erledigt:
|
||
|
||
| Schritt | Wird geprüft |
|
||
|---|---|
|
||
| 1. Kanal bestätigen | Kanal existiert (Helix) |
|
||
| 2. Twitch-Apps anlegen | Redirect-URI zum Kopieren, Anleitung |
|
||
| 3. Verbinden | Token gültig, Scopes vollständig |
|
||
| 4. OBS | erreichbar, Wiedergabepuffer aktiv, Hotkey belegt |
|
||
| 5. Facecam einmessen | Vorschau direkt in der Seite |
|
||
| 6. Fertig | „So löst du einen Clip aus" |
|
||
|
||
**Warum diese Scheibe hinten liegt:** Die Prüfungen sind nur so viel wert, wie
|
||
es zu prüfen gibt. Ein OBS-Schritt, der behauptet „alles gut", ohne den
|
||
Wiedergabepuffer wirklich abzufragen, ist schlimmer als kein Schritt. Deshalb
|
||
**erweitert jede Scheibe ab S2 den Assistenten um ihren eigenen Schritt**, und
|
||
S5 macht daraus einen zusammenhängenden Ablauf mit Texten, Reihenfolge und der
|
||
Startseite danach.
|
||
|
||
Danach wird aus der Einrichtungsseite eine Einstellungsseite, und die Startseite
|
||
zeigt den laufenden Stream und die anstehenden Entscheidungen — nicht eine Liste
|
||
von Werkzeugen (siehe [ADR-0006](decisions/ADR-0006-ein-dach.md)).
|
||
|
||
**Sichtung.** Auf derselben Oberfläche eine Seite mit allen Kandidaten des
|
||
letzten Streams: Videovorschau, Punktzahl, Auslöser, der Chat-Ausschnitt aus dem
|
||
Clip-Fenster, Transkript, und die Knöpfe *Übernehmen* / *Verwerfen*. Übernommene
|
||
Clips wandern nach `data/clips/_upload/`.
|
||
|
||
**Fertig, wenn:** Ein Fremder kommt von „nichts eingerichtet" bis zum ersten
|
||
eigenen Clip, ohne die Dokumentation zu lesen. Und: nach einem Stream lässt sich
|
||
in unter zwei Minuten entscheiden, welche Clips hochgeladen werden.
|
||
|
||
### S6 — Erstchatter-Begrüßung · ~0,5 Tage · optional
|
||
|
||
Der IRC-Client aus S1 liegt ohnehin da, das `first-msg`-Tag ebenso. Eine
|
||
Begrüßung für Erstchatter, eine für Rückkehrer nach mehr als 21 Tagen, mit
|
||
Cooldown und Obergrenze pro Stream. Details in
|
||
[`projects/community-memory.md`](projects/community-memory.md).
|
||
|
||
Diese Scheibe steht am Ende, weil sie unabhängig ist und notfalls entfällt.
|
||
Sie kostet fast nichts und ist das Einzige im MVP, das die Zuschauer direkt
|
||
merken — deshalb ist sie trotzdem drin.
|
||
|
||
## Zeitplan
|
||
|
||
| Woche | Scheiben | Ergebnis |
|
||
|---|---|---|
|
||
| 1 | ~~S0~~, S1 | Einrichtung im Browser, schreibt jeden Stream mit |
|
||
| 2 | S2, S3 | Knopfdruck erzeugt ein fertiges 9:16-Video |
|
||
| 3 | S4, S5, S6 | Untertitel, Sichtungsseite, Begrüßung |
|
||
|
||
Rund zehn Arbeitstage (S0 erledigt, S1 durch den Einrichtungs-Assistenten einen
|
||
Tag teurer). Realistisch drei Kalenderwochen, wenn nebenher noch etwas
|
||
anderes läuft.
|
||
|
||
## Definition of Done für das gesamte MVP
|
||
|
||
Ein echter Stream, ohne Eingriff von außen:
|
||
|
||
1. Container läuft von Streambeginn bis -ende durch, auch über einen
|
||
Twitch-Reconnect hinweg.
|
||
2. Fünfmal ausgelöst (dreimal `!clip`, zweimal Hotkey) ergibt fünf
|
||
`final.mp4` mit sitzendem Crop und brauchbaren Untertiteln.
|
||
3. Kein Auslöser bleibt unbestätigt, kein Clip geht verloren.
|
||
4. Die Sichtungsseite zeigt alle fünf, sortiert nach Score.
|
||
5. Das Encoding kostet den Stream keine sichtbaren Frames (Kontrolle über
|
||
die OBS-Statistik: keine übersprungenen Frames wegen Encoder-Überlast).
|
||
6. Chat und Zuschauerzahlen des Streams sind vollständig in der DB.
|
||
|
||
## Risiken
|
||
|
||
| Risiko | Wahrscheinlichkeit | Gegenmaßnahme |
|
||
|---|---|---|
|
||
| Encoding kostet Frames im Stream | mittel | `-preset veryfast`, CPU-Limit im Compose-File, Schalter `renderWhileLive: false` — dann läuft alles nach Streamende |
|
||
| whisper.cpp versteht Spielgeräusche statt Sprache | ~~mittel~~ **gelöst** | OBS nimmt getrennte Spuren auf; transkribiert wird nur das Mikrofon (Spur 2). |
|
||
| Twitch ändert die Ableitung der Clip-MP4-URL | niedrig | Betrifft nur den Zweitweg; die Rohdatei kommt aus OBS. Gekapselt in einer Datei. |
|
||
| Replay-Buffer-Pfad-Abbildung Windows ↔ Container | mittel | In S2 als Erstes lösen, mit einem Testlauf vor allem anderen |
|
||
| ~~Docker Desktop belastet den Stream-PC~~ | — | **eingetreten und geloest**: seit [ADR-0007](decisions/ADR-0007-native-windows.md) laeuft alles nativ, die WSL2-VM und ihre 1-2 GB entfallen |
|
||
|
||
## Was Abdu vorher tun muss
|
||
|
||
1. `install.ps1` ausfuehren (kein Docker, keine Administratorrechte)
|
||
2. Zwei Twitch-Apps anlegen, Redirect-URI `http://localhost:4792/callback`
|
||
(siehe [`05-setup.md`](05-setup.md)). Client-ID und Secret **nicht**
|
||
irgendwo eintragen — die kommen in den Einrichtungs-Assistenten.
|
||
3. In OBS: obs-websocket aktivieren (Port 4455, Passwort), Wiedergabepuffer auf
|
||
90 Sekunden, Hotkey auf „Wiedergabepuffer speichern" legen
|
||
4. ~~Screenshot der laufenden Szene schicken~~ — **erledigt**, Crop ist
|
||
eingemessen und steht in `config/layout.yaml`
|
||
5. ~~Getrennte Audiospuren klären~~ — **erledigt**, OBS nimmt getrennt auf;
|
||
Whisper bekommt nur die Mikrofonspur
|
||
6. In GTA die spieleigenen Untertitel ausschalten (werden vom Ausschnitt rechts
|
||
abgeschnitten, und die eigenen liegen ohnehin darüber)
|
||
|
||
## Danach
|
||
|
||
Wenn das MVP steht, ist der teuerste Teil erledigt: Auth, DB, Chat-Anbindung
|
||
und Container laufen. Die nächsten Meilensteine aus
|
||
[`04-roadmap.md`](04-roadmap.md) setzen darauf auf und werden dadurch
|
||
erheblich billiger — das Analytics-Dashboard wertet dann bereits mehrere Wochen
|
||
echter Daten aus, statt bei null anzufangen.
|