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>
This commit is contained in:
2026-04-06 03:46:13 -04:00
parent 180e95f74d
commit 0dff4eeee3
4 changed files with 158 additions and 86 deletions
+36 -28
View File
@@ -8,7 +8,7 @@ Configures NPM to:
**Stream** (L4 UDP proxy).
Replace `<PC-LAN-IP>` with the LAN IP of the Windows gaming PC
(e.g., `192.168.50.10`).
(e.g., `192.168.50.254`).
## 1. DNS
@@ -22,7 +22,7 @@ Make sure your router forwards these to NPM (not to the PC directly):
| Proto | External port | Internal target |
|-------|--------------|-------------------|
| TCP | 443 | NPM host, 443 |
| UDP | 48189 | NPM host, 48189 |
| UDP | 48189 | NPM host, 48189 |
(TCP 443 is probably already forwarded for your other services; UDP 48189 is
the new one for this app.)
@@ -38,20 +38,15 @@ In NPM, **Hosts -> Proxy Hosts -> Add Proxy Host**.
| Domain Names | `stream.hetherman.cloud` |
| Scheme | `http` |
| Forward Hostname | `<PC-LAN-IP>` |
| Forward Port | `48080` |
| Forward Port | `48080` |
| Cache Assets | off |
| Block Common Exploits | on |
| Websockets Support | **on** (WebRTC signaling works without this, but it costs nothing) |
| Websockets Support | **on** |
**Custom locations tab:** add three entries so WHEP, HLS, and the MediaMTX
API are reverse-proxied to the right MediaMTX ports (and inherit the same
forward-auth gating).
| Location | Scheme | Forward Hostname | Forward Port |
|----------|--------|------------------|--------------|
| `/whep` | `http` | `<PC-LAN-IP>` | `48889` |
| `/hls` | `http` | `<PC-LAN-IP>` | `48888` |
| `/v3` | `http` | `<PC-LAN-IP>` | `19997` |
**Custom Locations tab:** leave this **empty**. Do not add any custom location
entries here. The `/whep/`, `/hls/`, and `/v3/` locations are defined in the
Advanced tab config below with trailing-slash path stripping. Adding them in
the GUI creates duplicate nginx location blocks that cause routing failures.
**SSL tab:**
@@ -61,8 +56,12 @@ forward-auth gating).
- HSTS Enabled: optional
**Advanced tab:** paste the entire contents of
[`config/npm-advanced.conf`](../config/npm-advanced.conf). This installs the
Authentik forward-auth subrequest and the sign-in redirect.
[`config/npm-advanced.conf`](../config/npm-advanced.conf). This installs:
- Authentik forward-auth subrequest on all requests
- `/whep/` -> MediaMTX WHEP port 48889 (prefix stripped)
- `/hls/` -> MediaMTX HLS port 48888 (prefix stripped)
- `/v3/` -> MediaMTX API port 19997 (prefix stripped, auth bypassed)
- `/outpost.goauthentik.io` -> Authentik internal outpost
Save the proxy host. Wait for the Let's Encrypt certificate to be issued.
@@ -72,9 +71,9 @@ In NPM, **Hosts -> Streams -> Add Stream**.
| Field | Value |
|-------------------|---------------|
| Incoming Port | `48189` |
| Incoming Port | `48189` |
| Forward Host | `<PC-LAN-IP>` |
| Forward Port | `48189` |
| Forward Port | `48189` |
| TCP | **off** |
| UDP | **on** |
@@ -88,14 +87,23 @@ on the gaming PC. This is the path WebRTC media takes after ICE negotiation.
`auth.hetherman.cloud` to log in. Log in as a `stream-viewers` member -
you should land back at the stream page (video container + "Stream
offline" overlay, assuming you haven't started OBS yet).
2. **Certificate:** the padlock icon should show the Let's Encrypt cert you
requested.
3. **/whep, /hls, /v3:** once you start streaming in OBS, open DevTools on
the stream page and confirm requests to `/whep/game/whep`,
`/hls/game/index.m3u8`, and `/v3/paths/get/game` all return 200 (and not
401/302).
4. **UDP stream:** with OBS streaming, tail the NPM container logs - you
should see entries from the stream module for UDP connections on 48189.
Alternatively, from the NPM host run
`tcpdump -n -i any udp port 48189` and confirm packets flow while a
viewer is connected.
2. **Certificate:** the padlock icon should show the Let's Encrypt cert.
3. **With OBS streaming**, open DevTools on the stream page and confirm:
- `POST /whep/game-opus/whep` returns 201
- `GET /hls/game-opus/index.m3u8` returns 200
- `GET /status` returns 200 with `"ready": true`
4. **UDP stream:** with OBS streaming and a viewer connected, run
`tcpdump -n -i any udp port 48189` on the NPM host and confirm packets flow.
## Troubleshooting
- **500 or auth loop on stream.hetherman.cloud:** check the outpost `proxy_pass`
in the Advanced config uses the internal Authentik address
(`http://192.168.50.224:30140`) not the public HTTPS URL. Using the public
URL causes SSL SNI issues when NPM tries to proxy to itself.
- **WHEP returns 400:** the Custom Locations tab in the NPM GUI has `/whep`,
`/hls`, or `/v3` entries. Remove them - these must only be in the Advanced
tab config so the trailing-slash path stripping works correctly.
- **WHEP returns 401 / browser shows a Basic Auth dialog:** MediaMTX is
challenging the viewer directly. Check `authInternalUsers` in `mediamtx.yml`
has a rule allowing `read` from any IP (empty `ips: []`).