0dff4eeee3
- 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>
85 lines
4.1 KiB
Markdown
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
|