Files
ZeasyAlexandClaude Opus 5 d09e2b945a Struktur, Doku und S0-Toolchain fuer das abdulive-Toolkit
Monorepo-Geruest fuer neun Streamer-Tools plus den Ingest-Daemon, der
unter sechs davon liegt. Enthaelt:

- docs/: Ueberblick, Architektur, Twitch-Integration, Datenmodell,
  Roadmap, Setup, Hebel-Analyse und den MVP-Plan "Clip-Knopf"
- docs/projects/: je eine Spezifikation pro Tool
- docs/decisions/: vier ADRs (TS-Monorepo, SQLite, EventSub/IRC, Docker)
- docker/: Image mit ffmpeg und whisper.cpp, abhaengigkeitsfreier
  Entrypoint mit check-env, fetch-model und calibrate
- config/layout.yaml: aus einem VOD-Screenshot eingemessener
  Facecam-Ausschnitt (440x330 oben links, Chat-Overlay ab x=1270)

Noch kein Anwendungscode - Scheibe S0 aus docs/07-mvp-plan.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VTGjd92LsDDWF3frd9FTB
2026-09-09 08:56:09 +02:00

2.7 KiB

Ingest-Daemon (apps/ingest)

Kein eigenes "Tool" im Sinne der Wunschliste, sondern das Fundament, auf dem sechs der neun Tools stehen. Wird zuerst gebaut.

Aufgabe

Ein Prozess, der dauerhaft läuft und alle Datenquellen in einen einheitlichen Event-Strom übersetzt: schreibt in SQLite, publiziert auf dem Bus.

Quellen

Quelle Verbindung liefert
Twitch IRC wss://irc-ws.chat.twitch.tv:443 Chat-Nachrichten mit Tags
Twitch EventSub wss://eventsub.wss.twitch.tv/ws Follows, Subs, Raids, Kategorie, Online/Offline
Twitch Helix REST, Polling 60 s Viewerzahl, Chatter-Liste (5 min)
obs-websocket ws://127.0.0.1:4455 Szenenwechsel, Replay-Buffer-Events

Was der Ingest selbst berechnet

Stream-Sessions. stream.online legt eine streams-Zeile an, stream.offline schließt sie. Wenn der Daemon mitten im Stream startet, wird die laufende Session über GET /helix/streams rekonstruiert. Kurze Unterbrechungen (< 5 min) werden als dieselbe Session behandelt — sonst zerfallen Streams bei jedem Verbindungsabbruch in Fragmente.

Chat-Spikes. Gleitendes Fenster über die Nachrichtenrate:

rate(t)     = Nachrichten in den letzten 15 s
baseline(t) = Median von rate über die letzten 10 min
spike       = rate >= max(baseline * 3, baseline + 4)
              && Zeit seit letztem Spike > 60 s

Zusätzlich gewichtet: Lach-Emotes (KEKW, LUL, OMEGALUL, Kanal-Emotes), Ausrufe (?!, Großbuchstaben-Anteil), das Wort clip. Ergebnis ist ein chat.spike-Event mit score. Wer darauf reagiert, entscheidet der Konsument.

Bei 10 Zuschauern ist die Baseline klein und die Statistik dünn. Der Detektor ist deshalb bewusst konservativ und protokolliert alle Kandidaten mit Score, auch die unter der Schwelle — so lässt sich die Schwelle nachträglich am echten Material kalibrieren, statt sie zu raten.

Anwesenheit. Aus GET /helix/chat/chatters (alle 5 min) plus jeder Nachricht wird user_streams fortgeschrieben: Ersterscheinung, letzte Aktivität, Minuten. Daraus fällt streams_present für jeden User ab.

Schnittstellen nach außen

  • WS ws://127.0.0.1:4790 — Broadcast aller Events als JSON-Zeilen. Ein Client kann beim Connect {"since":"<iso-ts>"} senden und bekommt die verpassten Events aus der DB nachgeliefert.
  • HTTP GET /health — Status aller vier Verbindungen, für das Dashboard.

Abnahmekriterien

  • Läuft 7 Tage ohne Neustart durch, inklusive Twitch-Reconnects.
  • Nach einem erzwungenen Prozess-Kill mitten im Stream: Neustart rekonstruiert die laufende Session, keine doppelten streams-Zeilen, keine doppelten Events.
  • Jede Chat-Nachricht eines Test-Streams ist in chat_messages (Abgleich gegen ein parallel mitgeschriebenes Log).