mirror of
https://github.com/Andre-Bzk/twitch4steamdeck.git
synced 2026-11-15 15:43:08 +01:00
Phase 5 abgeschlossen
- SQLite-Setup: `src/main/store/db.ts` (better-sqlite3, Migration) - Lokaler VOD-Verlauf (Resume) - mpv `time-pos`-Observer schreibt alle ~5s in DB - Auto-Resume: beim VOD-Start Position aus DB lesen → `--start=<s>` -Resume-Indikator auf VOD-Karte - Completed-Indikator (dunkles Overlay + Checkmark)
This commit is contained in:
+52
-107
@@ -1,145 +1,90 @@
|
||||
# Twitch4SteamDeck — Fortschritts-Snapshot
|
||||
|
||||
> Stand: **Ende 2026-04-07 (Session 2)**. Diese Datei dient als Übergabe zwischen Sessions.
|
||||
> Stand: **2026-04-08 (Session 3)**. Diese Datei dient als Übergabe zwischen Sessions.
|
||||
> **Lies zuerst:** diese Datei + `todo.md` + `plan.md`.
|
||||
> Architekturplan-Quelle: `C:\Users\andre\.claude\plans\smooth-shimmying-parasol.md` (im Repo gespiegelt).
|
||||
>
|
||||
> **Aktueller Stand:** Phase 0–2 abgeschlossen & verifiziert. Phase 3 Code-complete, noch NICHT verifiziert (mpv PATH-Problem beim ersten Start).
|
||||
|
||||
**Aktueller Stand:** Phase 0–5 abgeschlossen & verifiziert. Als nächstes: Phase 6 (Flatpak-Packaging).
|
||||
|
||||
---
|
||||
|
||||
## Bereits abgeschlossen
|
||||
|
||||
### ✅ Phase 0 — Projekt-Skelett
|
||||
Siehe vorherige Sessions.
|
||||
|
||||
### ✅ Phase 1 — Twitch OAuth Device Code Flow
|
||||
Siehe vorherige Sessions. End-to-End verifiziert 2026-04-07.
|
||||
|
||||
### ✅ Phase 2 — Twitch Helix-Client + Sidebar-Layout
|
||||
Siehe vorherige Sessions. End-to-End verifiziert 2026-04-07.
|
||||
Alle drei End-to-End verifiziert 2026-04-07.
|
||||
|
||||
---
|
||||
|
||||
### 🔄 Phase 3 — Streamlink + mpv (Live-Wiedergabe) — Code complete, nicht verifiziert
|
||||
### ✅ Phase 3 — Streamlink + mpv (Live-Wiedergabe)
|
||||
|
||||
#### Neu erstellte Dateien (Session 2, 2026-04-07):
|
||||
Verifiziert 2026-04-08.
|
||||
|
||||
**Main-Prozess:**
|
||||
- `src/main/playback/types.ts` — `PlaybackEvent`, `Quality`
|
||||
- `src/main/playback/streamlink.ts` — `spawnStreamlink()` mit `resolveStreamlinkBin()` (sucht
|
||||
`.exe` in `%LOCALAPPDATA%\Programs\Streamlink\bin\` usw., Fallback `streamlink`)
|
||||
- `src/main/playback/mpvController.ts` — `getMpvIpcPath()`, `MpvController` (Named Pipe Win32
|
||||
/ Unix Socket), connect mit Retry, `quit()`, `disconnect()`
|
||||
- `src/main/playback/playbackService.ts` — orchestriert streamlink + mpv, `startLive()`, `stop()`,
|
||||
`stopAll()`, emittiert `'playback-event'`
|
||||
- `src/main/ipc/handlers.ts` — erweitert um `playback:start-live`, `playback:stop`,
|
||||
`playback:event` (main→renderer); `registerIpcHandlers` nimmt jetzt `PlaybackService` als 3. Arg
|
||||
- `src/main/index.ts` — instanziiert `PlaybackService`, registriert
|
||||
`app.on('before-quit', () => playback.stopAll())`
|
||||
|
||||
**Preload + Typen:**
|
||||
- `src/preload/index.ts` — `window.t4sd.playback.{startLive, stop, onEvent}` hinzugefügt
|
||||
- `src/renderer/src/types/t4sd.d.ts` — `PlaybackEvent`-Typ + `playback`-API hinzugefügt
|
||||
|
||||
**Renderer:**
|
||||
- `src/renderer/src/screens/ChannelScreen.tsx` — Detail-Screen: Thumbnail/Avatar/Name/Titel/Spiel/
|
||||
Viewer, Button „▶ Live ansehen", Zustandsanzeige (idle/starting/playing/error),
|
||||
Escape/B → Stop oder Zurück
|
||||
- `src/renderer/src/screens/AppShell.tsx` — `selectedChannel`-State, Routing zu `ChannelScreen`,
|
||||
`onSelectChannel` an `FollowingScreen` weitergegeben
|
||||
- `src/renderer/src/screens/FollowingScreen.tsx` — `onSelectChannel`-Prop verkabelt,
|
||||
`onSelect` der Karte ruft jetzt `onSelectChannel(ch)` auf (nicht mehr nur `console.log`)
|
||||
- `src/renderer/src/styles/global.css` — `.channel-screen` + alle Unter-Klassen ergänzt
|
||||
|
||||
#### Architektur-Entscheidungen in Phase 3:
|
||||
- **Variante 2:** streamlink spawnt mpv selbst via `--player mpv --player-args "..."`.
|
||||
Node steuert nur den streamlink-Prozess direkt.
|
||||
- **mpv IPC** via Named Pipe (Win32) oder Unix Socket (Linux), verbunden nach `spawn` im Hintergrund
|
||||
(nicht blockierend, nicht kritisch für MVP). Wird für `quit()` beim Stop genutzt.
|
||||
- **`resolveStreamlinkBin()`** sucht die `.exe` unter bekannten Windows-Installationspfaden,
|
||||
#### Architektur-Entscheidungen:
|
||||
- `--twitch-api-header` wird **nicht** übergeben — Twitch lehnt den Device-Code-Token für
|
||||
streamlinks interne GQL-API ab. Öffentliche Streams funktionieren ohne Auth-Header.
|
||||
- `resolveMpvBin()` löst den mpv-Pfad explizit auf (`C:\Program Files\MPV Player\mpv.exe`),
|
||||
da Electron den User-PATH nicht vollständig erbt.
|
||||
- `--twitch-disable-ads` ist von streamlink deaktiviert worden (deprecated) — kein Ad-Bypass
|
||||
im Moment. Post-MVP-Problem.
|
||||
|
||||
---
|
||||
|
||||
## Offener Punkt beim Start morgen — mpv PATH-Problem
|
||||
### ✅ Phase 4 — VOD-Browsing + -Wiedergabe
|
||||
|
||||
### Was passiert ist:
|
||||
Streamlink startet (ENOENT behoben via `resolveStreamlinkBin()`), aber streamlink
|
||||
kann mpv nicht finden, weil **mpv nicht im PATH ist, den streamlink von Electron erbt**.
|
||||
Verifiziert 2026-04-08.
|
||||
|
||||
Fehlerbild: `[streamlink] exit code 1`, kein mpv-Fenster.
|
||||
|
||||
### Wahrscheinlichste Lösung (zuerst probieren):
|
||||
**VS Code (und damit das Electron-Dev-Fenster) neu starten.** Nach dem `setx PATH ...`
|
||||
für mpv muss VS Code neu gestartet werden, damit es den neuen PATH erbt.
|
||||
|
||||
```
|
||||
1. VS Code schließen
|
||||
2. VS Code neu öffnen
|
||||
3. npm run dev
|
||||
4. Kanal auswählen → "Live ansehen"
|
||||
```
|
||||
|
||||
### Falls das nicht reicht — Fallback:
|
||||
mpv-Pfad ebenfalls resolven wie streamlink. In `streamlink.ts` eine `resolveMpvBin()`-Funktion
|
||||
ergänzen und den vollen Pfad an `--player` übergeben:
|
||||
|
||||
```typescript
|
||||
// In streamlink.ts hinzufügen:
|
||||
function resolveMpvBin(): string {
|
||||
if (process.platform === 'win32') {
|
||||
const candidates = [
|
||||
join(process.env.LOCALAPPDATA ?? '', 'Programs', 'mpv', 'mpv.exe'),
|
||||
// shinchiro winget installiert nach: %LOCALAPPDATA%\Microsoft\WinGet\Packages\...
|
||||
// Dort nach mpv.exe suchen wenn oben nicht gefunden
|
||||
]
|
||||
for (const p of candidates) {
|
||||
if (existsSync(p)) return p
|
||||
}
|
||||
}
|
||||
return 'mpv'
|
||||
}
|
||||
```
|
||||
|
||||
Dann in `spawnStreamlink()`:
|
||||
```typescript
|
||||
'--player', resolveMpvBin(), // statt '--player', 'mpv'
|
||||
```
|
||||
|
||||
**Wichtig:** `where mpv` in der Shell ausführen um den exakten Pfad zu kennen, bevor
|
||||
du `resolveMpvBin()` implementierst.
|
||||
|
||||
### Falls auch das nicht reicht:
|
||||
streamlink selbst via `--player-args` testen ohne `--input-ipc-server` (vereinfachter Test),
|
||||
um zu isolieren ob das Problem mpv-start oder IPC-Argument ist.
|
||||
#### Architektur-Entscheidungen:
|
||||
- **VODs:** streamlink `--stream-url` liefert HLS-URL → mpv wird **direkt** mit der URL
|
||||
gespawnt (nicht via `--player`-Flag). Grund: Piped-Streams sind nicht seekable.
|
||||
Direktes mpv-Spawnen ermöglicht Seeking + funktionierendes IPC.
|
||||
- **Live-Streams:** weiterhin via `--player mpv --player-args "--fullscreen"`. Kein IPC
|
||||
nötig (kein Seeking, kein Position-Tracking bei Live).
|
||||
- VOD-Shelf im `ChannelScreen` (untere Hälfte, horizontal, oberer Hero-Bereich fix).
|
||||
Navigation: ↓ → Shelf, ←/→ zwischen VODs, ↑ → zurück, Enter → abspielen.
|
||||
|
||||
---
|
||||
|
||||
## Verifikations-Checkliste Phase 3 (noch offen)
|
||||
### ✅ Phase 5 — Lokaler VOD-Verlauf (Resume)
|
||||
|
||||
- [ ] 5 min Live-Stream ohne Werbe-Unterbrechung auf Windows (Dev-Setup)
|
||||
- [ ] Beim Stop: mpv-Fenster schließt sich sauber, streamlink-Prozess terminiert
|
||||
- [ ] Keine Zombie-Prozesse im Task-Manager nach Stop
|
||||
- [ ] Logout/Login und erneutes Starten funktioniert ohne App-Neustart
|
||||
Verifiziert 2026-04-08.
|
||||
|
||||
#### Neue Dateien:
|
||||
- `src/main/store/db.ts` — SQLite via better-sqlite3, WAL-Modus, Migration
|
||||
- `src/main/store/historyRepo.ts` — `upsertVod`, `updatePosition`, `markCompleted`,
|
||||
`getPosition`, `getProgressMap`
|
||||
|
||||
#### Architektur-Entscheidungen:
|
||||
- mpv IPC funktioniert jetzt zuverlässig (da mpv direkt gespawnt wird).
|
||||
`MpvController.observeTimePos()` parst eingehende JSON-Lines, Throttling auf 5s.
|
||||
- Resume-Position wird beim `startVod()`-Aufruf automatisch aus DB gelesen.
|
||||
- Auto-Complete bei >95% Fortschritt.
|
||||
- `„Continue Watching"-Reihe` wurde bewusst weggelassen (vom User nicht gewünscht).
|
||||
- VOD-Karte zeigt: Fortschrittsbalken (lila), `0:16 von 6:22`, `Vor X Min.`,
|
||||
Completed-Overlay mit Kreis-Checkmark.
|
||||
|
||||
---
|
||||
|
||||
## Erste Anweisung morgen an Claude (copy-paste)
|
||||
## Nächster Schritt: Phase 6 — Flatpak-Packaging
|
||||
|
||||
> „Lies CLAUDE_PROGRESS.md, todo.md und plan.md. Phase 3 ist code-complete. Das mpv
|
||||
> PATH-Problem war der letzte offene Punkt — ich habe VS Code neugestartet (oder den
|
||||
> Fallback umgesetzt). Sag mir ob der Stream jetzt läuft."
|
||||
Ziel: App läuft auf dem Steam Deck als Flatpak.
|
||||
|
||||
Wichtige offene Punkte:
|
||||
- mpv + streamlink müssen als Flatpak-Module gebündelt werden
|
||||
- `--hwdec=vaapi` für Linux (Steam Deck) statt `auto` (Windows)
|
||||
- IPC-Pfad: Unix Socket `/tmp/twitch4sd-mpv.sock` (bereits implementiert für non-win32)
|
||||
- better-sqlite3 muss für Linux/ARM64 (Steam Deck) cross-compiliert werden
|
||||
- Flatpak-Manifest: `flatpak/tv.twitch4steamdeck.App.yml`
|
||||
|
||||
---
|
||||
|
||||
## Technische Baseline (Sanity-Check)
|
||||
## Technische Baseline
|
||||
|
||||
- Electron 33, electron-vite, TypeScript 5.5, React 18
|
||||
- streamlink 8.2.1 installiert unter `%LOCALAPPDATA%\Programs\Streamlink\bin\streamlink.exe`
|
||||
- mpv v0.41.0 installiert, via `setx` zum PATH hinzugefügt (VS Code-Neustart nötig!)
|
||||
- IPC-Pattern: `ipcMain.handle` → `ipcRenderer.invoke` → `contextBridge` → `window.t4sd.*`
|
||||
- Main→Renderer Events via `webContents.send` + `ipcRenderer.on`
|
||||
- better-sqlite3 12.x (native, rebuilt für Electron via `@electron/rebuild`)
|
||||
- streamlink 8.x unter `%LOCALAPPDATA%\Programs\Streamlink\bin\streamlink.exe`
|
||||
- mpv v0.41.0 unter `C:\Program Files\MPV Player\mpv.exe`
|
||||
- Dev-Host: **Windows**. Target: **Steam Deck (Linux / Flatpak)**
|
||||
|
||||
### Wichtiges Projekt-Memo
|
||||
- Bei **allen Architekturänderungen** `plan.md` updaten.
|
||||
|
||||
Reference in New Issue
Block a user