- Remove mpvController.ts and hlsTrimmer.ts entirely - Rewrite PlaybackService: streamlink --stream-url → HLS-URL → IPC event playback:hls-url - Add VideoPlayer.tsx (hls.js <video> wrapper, forwardRef with seek/seekTo/pause/play/stop/getCurrentTime) - Integrate VideoPlayer into ChannelScreen with direct videoRef calls (no IPC roundtrip for seek/pause) - Add global AppShell playback overlay for direct stream start (A-button in Browse/Category/StreamList) - Propagate onStartLive callback through BrowseScreen, CategoryScreen, StreamListScreen - Add CORS bypass for Twitch CDN (webRequest.onBeforeSendHeaders) and autoplay-policy switch - Update CSP: add media-src 'self' blob: for hls.js MediaSource API - Open chapter panel without stopping playback (pause + resume instead of stop/restart) - Drop IPC channels: seek, seekTo, resume, togglePause, getCurrentPosition, onTimeUpdate - Add IPC channel: playback:hls-url event with HlsUrlPayload
12 KiB
Twitch4SteamDeck
Ad-free Twitch client for the Steam Deck with Big-Screen UI, full gamepad control, and VOD playback with resume.
Features
- Live Streams — Ad-free playback via Streamlink + hls.js (HTML5 video, no external player)
- VOD Playback — Watch recordings with automatic resume at last position
- VOD Chapters — Browse and jump to chapters within VODs
- Direct Stream Start — Press A on any stream card in Browse/Top Streams/Category to start immediately without leaving the browse view
- Gamepad Control — Full control via Steam Deck controller or Xbox gamepad, including Gaming Mode (reads
/dev/input/js*directly, bypasses Chromium sandbox limitations) - Big-Screen UI — 10-foot interface optimized for TV/deck; fills the screen on Steam Deck and on external TVs when docked (React + Electron)
- Twitch Login — Device Code Flow with QR code (no browser required)
- Following — Live status and overview of followed streamers
- Category Browser — Browse Twitch categories and top streams
- Language-Filtered Streams — Top streams filtered by German/English
- Account Screen — User profile, app version, logout
- VOD History — Local SQLite database with playback history and progress
- Hardware Decoding — GPU-accelerated video via Chromium's built-in VA-API on Steam Deck
- Quit Dialog — Confirm quit via Xbox/Start button
Architecture
Electron (Main Process)
├── Auth -- Twitch Device Code Flow + token management (Electron safeStorage)
├── Helix Client -- Twitch API (followed channels, streams, VODs, categories, chapters via GQL)
├── Playback -- Streamlink --stream-url → HLS URL → IPC event to renderer
├── Gamepad -- Linux joystick API (/dev/input/js*)
└── History -- SQLite (better-sqlite3) for VOD history + resume
Electron (Renderer)
├── React UI -- Screens: Login, Following, Browse, Category, Channel,
│ StreamList (DE/EN), Settings, Account
├── VideoPlayer -- hls.js <video> wrapper (forwardRef, imperative handle)
└── AppShell -- Global playback overlay for direct stream start
Installation (Steam Deck)
flatpak install --user twitch4steamdeck.flatpak
flatpak run tv.twitch4steamdeck.App
Finished Flatpak bundles include everything (incl. Streamlink and Twitch integration) — no further setup required.
Build yourself (developers)
Prerequisites
- Node.js >= 20
- npm
- Windows: Streamlink installed at
%LOCALAPPDATA%\Programs\Streamlink\bin\streamlink.exe - For Flatpak build: WSL2 (Ubuntu) with
flatpak,flatpak-builder,librsvg2-bin
Setup
-
Clone the repository:
git clone https://github.com/<user>/twitch4steamdeck.git cd twitch4steamdeck -
Register your own Twitch app at https://dev.twitch.tv/console/apps:
- OAuth Redirect URLs:
http://localhost - Client Type: Public
- OAuth Redirect URLs:
-
Create
.env:cp .env.example .envEnter the Client ID from step 2 into
.env:MAIN_VITE_TWITCH_CLIENT_ID=your_client_id_hereThe Client ID is embedded into the app at build time. End users installing a finished Flatpak do not need to register their own Twitch app.
-
Install dependencies:
npm install
Development
npm run dev
Starts Electron with Hot-Reload (electron-vite). Open DevTools with Ctrl+Shift+I.
Build
Desktop (AppImage)
npm run package
Creates a Linux AppImage under dist/.
Flatpak (Steam Deck)
The Flatpak build must run in WSL2 on the Linux filesystem (not under /mnt/):
# Copy project to Linux filesystem
cp -rp /mnt/c/Projekte/twitch4steamdeck ~/twitch4steamdeck
cd ~/twitch4steamdeck
# Run full build (incl. streamlink, Electron)
bash flatpak/build-flatpak.sh
The script handles automatically:
- Install Flatpak runtimes (freedesktop SDK 24.08, Electron2 BaseApp)
- npm install + rebuild native modules (better-sqlite3 for Linux x64)
- electron-vite build
- Generate Streamlink Python deps
- Run flatpak-builder
- Create Flatpak bundle and transfer via SCP to Steam Deck
Gamepad Layout
| Button | Context | Function |
|---|---|---|
| A | Browse / Top Streams / Category | Start stream directly (full-screen overlay) |
| X | Browse / Top Streams / Category | Open channel page |
| A | Following | Open channel page |
| A | Channel page | Play live stream / confirm |
| A | During playback | Pause / Resume |
| B | During playback | Stop |
| ← / → (D-Pad) | During playback | Seek ±30s |
| LT / RT | During playback (VOD) | Seek ±5min |
| LB / RB | During playback (VOD) | Previous / next chapter |
| B | Navigation | Back |
| D-Pad / Left Stick | Navigation | Navigate |
| LB / RB | Navigation | Switch tabs |
| Xbox / Start | Navigation | Quit dialog |
Security
- Twitch tokens are stored encrypted in the OS keystore (Electron
safeStorage) and never end up in the build or repository - Client ID is a public identifier (Public App) and not a secret
.env,out/,dist/anduserData/are excluded in.gitignore
Tech Stack
| Component | Technology |
|---|---|
| Framework | Electron 33 + electron-vite |
| UI | React 18 + TypeScript |
| Video | hls.js 1.6 (HTML5 <video> in Renderer) |
| Stream URL | Streamlink 8.2.1 (Windows dev) / 6.11.0 (Flatpak) via --stream-url |
| Database | better-sqlite3 |
| Gamepad | Linux joystick API (/dev/input/js*) |
| Packaging | Flatpak / electron-builder (AppImage) |
| HW Decoding | Chromium VA-API (automatic on Steam Deck) |
License
Twitch4SteamDeck
Werbefreier Twitch-Client fuer das Steam Deck mit Big-Screen-UI, voller Gamepad-Steuerung und VOD-Wiedergabe mit Resume.
Features
- Live-Streams — Werbefreie Wiedergabe ueber Streamlink + hls.js (HTML5-Video, kein externer Player)
- VOD-Wiedergabe — Aufnahmen ansehen mit automatischem Resume an der letzten Position
- VOD-Kapitel — Kapitel in VODs durchsuchen und direkt anspringen
- Direkter Stream-Start — A-Button auf einer Stream-Karte in Durchsuchen/Top-Streams/Kategorie startet den Stream sofort als Vollbild-Overlay, ohne die Browse-Ansicht zu verlassen
- Gamepad-Steuerung — Volle Bedienung per Steam Deck Controller oder Xbox-Gamepad, auch im Gaming Mode (liest
/dev/input/js*direkt, umgeht Chromium-Sandbox-Limitierungen) - Big-Screen-UI — 10-Foot-Interface optimiert fuer TV/Deck; bildschirmfuellend auf dem Steam Deck und auf externen TVs im Docking-Betrieb (React + Electron)
- Twitch-Login — Device Code Flow mit QR-Code (kein Browser noetig)
- Gefolgte Kanaele — Live-Status und Uebersicht der gefolgten Streamer
- Kategorie-Browser — Twitch-Kategorien und Top-Streams durchsuchen
- Sprachgefilterte Streams — Top-Streams gefiltert nach Deutsch/Englisch
- Account-Ansicht — Nutzerprofil, App-Version, Abmelden
- VOD-Verlauf — Lokale SQLite-Datenbank mit Wiedergabe-Historie und Fortschritt
- Hardware-Decoding — GPU-beschleunigte Videowiedergabe ueber Chromiums eingebaute VA-API auf dem Steam Deck
- Quit-Dialog — Beenden per Xbox/Start-Button bestaetigen
Architektur
Electron (Main Process)
├── Auth -- Twitch Device Code Flow + Token-Verwaltung (Electron safeStorage)
├── Helix Client -- Twitch API (gefolgte Kanaele, Streams, VODs, Kategorien, Kapitel via GQL)
├── Playback -- Streamlink --stream-url → HLS-URL → IPC-Event an Renderer
├── Gamepad -- Linux joystick API (/dev/input/js*)
└── History -- SQLite (better-sqlite3) fuer VOD-Verlauf + Resume
Electron (Renderer)
├── React UI -- Screens: Login, Following, Browse, Category, Channel,
│ StreamList (DE/EN), Settings, Account
├── VideoPlayer -- hls.js <video> Wrapper (forwardRef, imperative handle)
└── AppShell -- Globaler Playback-Overlay fuer Direkt-Stream-Start
Installation (Steam Deck)
flatpak install --user twitch4steamdeck.flatpak
flatpak run tv.twitch4steamdeck.App
Fertige Flatpak-Bundles enthalten alles (inkl. Streamlink und Twitch-Anbindung) -- keine weitere Einrichtung noetig.
Selbst bauen (Entwickler)
Voraussetzungen
- Node.js >= 20
- npm
- Windows: Streamlink unter
%LOCALAPPDATA%\Programs\Streamlink\bin\streamlink.exe - Fuer Flatpak-Build: WSL2 (Ubuntu) mit
flatpak,flatpak-builder,librsvg2-bin
Einrichtung
-
Repository klonen:
git clone https://github.com/<user>/twitch4steamdeck.git cd twitch4steamdeck -
Eigene Twitch-App registrieren auf https://dev.twitch.tv/console/apps:
- OAuth Redirect URLs:
http://localhost - Client Type: Public
- OAuth Redirect URLs:
-
.envanlegen:cp .env.example .envDie Client-ID aus Schritt 2 in
.enveintragen:MAIN_VITE_TWITCH_CLIENT_ID=deine_client_id_hierDie Client-ID wird beim Build in die App eingebettet. Endnutzer, die ein fertiges Flatpak installieren, brauchen keine eigene Twitch-App zu registrieren.
-
Abhaengigkeiten installieren:
npm install
Entwicklung
npm run dev
Startet Electron mit Hot-Reload (electron-vite). DevTools oeffnen mit Ctrl+Shift+I.
Build
Desktop (AppImage)
npm run package
Erzeugt ein Linux-AppImage unter dist/.
Flatpak (Steam Deck)
Der Flatpak-Build muss in WSL2 auf dem Linux-Dateisystem ausgefuehrt werden (nicht unter /mnt/):
# Projekt auf Linux-Dateisystem kopieren
cp -rp /mnt/c/Projekte/twitch4steamdeck ~/twitch4steamdeck
cd ~/twitch4steamdeck
# Kompletten Build ausfuehren (inkl. Streamlink, Electron)
bash flatpak/build-flatpak.sh
Das Script erledigt automatisch:
- Flatpak-Runtimes installieren (freedesktop SDK 24.08, Electron2 BaseApp)
- npm install + native Module rebuilden (better-sqlite3 fuer Linux x64)
- electron-vite Build
- Streamlink Python-Deps generieren
- flatpak-builder ausfuehren
- Flatpak-Bundle erstellen und per SCP aufs Steam Deck uebertragen
Gamepad-Belegung
| Taste | Kontext | Funktion |
|---|---|---|
| A | Durchsuchen / Top-Streams / Kategorie | Stream direkt starten (Vollbild-Overlay) |
| X | Durchsuchen / Top-Streams / Kategorie | Kanalseite oeffnen |
| A | Du folgst | Kanalseite oeffnen |
| A | Kanalseite | Live-Stream starten / Bestaetigen |
| A | Waehrend Wiedergabe | Pause / Fortsetzen |
| B | Waehrend Wiedergabe | Stop |
| ← / → (D-Pad) | Waehrend Wiedergabe | ±30s springen |
| LT / RT | Waehrend Wiedergabe (VOD) | ±5min springen |
| LB / RB | Waehrend Wiedergabe (VOD) | Vorheriges / naechstes Kapitel |
| B | Navigation | Zurueck |
| D-Pad / Left Stick | Navigation | Navigieren |
| LB / RB | Navigation | Tab wechseln |
| Xbox / Start | Navigation | Quit-Dialog |
Sicherheit
- Twitch-Tokens werden verschluesselt im OS-Keystore gespeichert (Electron
safeStorage) und landen weder im Build noch im Repository - Client-ID ist eine oeffentliche Kennung (Public App) und kein Geheimnis
.env,out/,dist/unduserData/sind in.gitignoreausgeschlossen
Tech-Stack
| Komponente | Technologie |
|---|---|
| Framework | Electron 33 + electron-vite |
| UI | React 18 + TypeScript |
| Video | hls.js 1.6 (HTML5 <video> im Renderer) |
| Stream-URL | Streamlink 8.2.1 (Windows-Dev) / 6.11.0 (Flatpak) via --stream-url |
| Datenbank | better-sqlite3 |
| Gamepad | Linux joystick API (/dev/input/js*) |
| Packaging | Flatpak / electron-builder (AppImage) |
| HW-Decoding | Chromium VA-API (automatisch auf Steam Deck) |