Files
bhetherman 0dff4eeee3 Update all docs to reflect current working configuration
- README: update architecture diagram for RTMP+FFmpeg pipeline, add FFmpeg
  install step, fix path descriptions
- obs-setup: switch from WHIP to RTMP output, add FFmpeg prerequisite, fix
  script log messages (MediaMTX starts on load not streaming start), add
  Python setup note, update troubleshooting for game-opus path and audio
- npm-setup: remove Custom Locations GUI instructions (must be empty - all
  locations defined in Advanced tab only), update verify steps to game-opus
  paths, add troubleshooting for WHEP 400/401 causes
- authentik-setup: add section 6 covering both manual account creation and
  self-service enrollment via invite link; clarify User Write stage group
  field is what triggers auto-add (not the invitation form)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 03:46:13 -04:00

85 lines
4.1 KiB
Markdown

# game-stream-app
Low-latency browser-based game streaming to a small group of friends, gated by
Authentik authentication.
- **Streamer:** Windows PC with an NVIDIA GPU running OBS Studio.
- **Viewers:** up to ~6 friends, any modern browser, no client install.
- **Auth:** Authentik forward auth at the Nginx Proxy Manager (NPM) edge.
- **Transport:** WebRTC (WHEP) for low latency, with LL-HLS fallback.
- **Latency target:** ~200 ms over WebRTC, ~1-2 s over LL-HLS fallback.
## How it works
```
OBS Studio (NVENC H.264, RTMP out)
-> MediaMTX (localhost, RTMP ingest)
-> FFmpeg (AAC -> Opus transcode, internal RTSP)
-> game-opus path (H.264 + Opus)
-> WHEP / HLS for viewers
-> Frontend HTTP server (localhost:48080)
-> NPM (TLS, Authentik forward auth, reverse proxy)
-> Friend's browser
```
OBS outputs RTMP to MediaMTX on localhost. MediaMTX spawns FFmpeg via
`runOnReady` to transcode audio from AAC to Opus (required for WebRTC) and
re-publish to the `game-opus` path. Viewers connect to `game-opus` via WHEP
(WebRTC) or HLS.
Everything on the gaming PC (MediaMTX, HTTP server, Windows Firewall rule for
the WebRTC UDP port) is spawned and torn down by an OBS Python script -
`obs-script/game_stream.py`. You just click **Start Streaming** in OBS and the
whole pipeline comes up; click **Stop Streaming** and it all goes away.
## Repository layout
| Path | Purpose |
|-------------------------------|-------------------------------------------------------------|
| `config/mediamtx.yml` | MediaMTX configuration (RTMP in, WHEP/HLS out, FFmpeg transcode) |
| `config/npm-advanced.conf` | Authentik forward-auth snippet for the NPM Advanced tab |
| `obs-script/game_stream.py` | OBS script: lifecycle, HTTP server, firewall toggle |
| `frontend/index.html` | Viewer page |
| `frontend/js/player.js` | WHEP client with HLS fallback |
| `frontend/js/app.js` | Status polling and DOM glue |
| `frontend/css/style.css` | Dark theme |
| `scripts/install.ps1` | Downloads MediaMTX, creates the Windows Firewall rule |
| `docs/authentik-setup.md` | Authentik proxy provider, group, and invite configuration |
| `docs/npm-setup.md` | NPM proxy host + stream (UDP) configuration |
| `docs/obs-setup.md` | OBS encoder + RTMP output settings |
## Setup at a glance
1. **Clone** this repo onto the Windows gaming PC.
2. **Install FFmpeg:** `winget install Gyan.FFmpeg` in an elevated PowerShell,
then open a new terminal to verify: `ffmpeg -version`.
3. **Install MediaMTX and the firewall rule:** open an elevated PowerShell in
the repo root and run `.\scripts\install.ps1`.
4. **Configure Authentik** - see `docs/authentik-setup.md`.
5. **Configure NPM** - see `docs/npm-setup.md`.
6. **Configure OBS** - see `docs/obs-setup.md`, then add
`obs-script/game_stream.py` via Tools -> Scripts.
7. **Click Start Streaming in OBS.** Friends can now open
`https://stream.hetherman.cloud`, log in with Authentik, and watch.
## Security posture
- TLS terminates at NPM with Let's Encrypt.
- Every request is gated by Authentik forward auth before it reaches the
frontend, WHEP signaling, or HLS.
- MediaMTX only accepts publishers from `127.0.0.1` - nobody on the public
internet can hijack the stream.
- The UDP port used for WebRTC media is opened on the Windows Firewall only
while streaming is active (toggled by the OBS script). Even though NPM and
the router still forward the port, the OS silently drops packets between
streams, so there is no exposed listener.
- WebRTC media is DTLS-encrypted SRTP. An attacker who hits the UDP port
without an Authentik-authenticated WHEP session cannot decrypt or inject
media.
- Removing a friend from the Authentik `stream-viewers` group revokes their
access on the next auth_request subrequest (within seconds).
## License
MIT