Files
obs-game-stream-plugin/docs/npm-setup.md
T
bhetherman 180e95f74d Fix audio, routing, auth, and stream lifecycle
- Switch OBS output to RTMP; add FFmpeg AAC->Opus transcoding via MediaMTX
  runOnReady so WebRTC can carry audio (WebRTC requires Opus, not AAC)
- Enable RTSP on localhost so FFmpeg reads game path without publisher conflict;
  viewers connect to game-opus path (H264+Opus)
- Fix WHEP/HLS path prefix stripping in NPM advanced config; move all custom
  locations (/whep, /hls, /v3) out of NPM GUI and into advanced conf so
  trailing-slash proxy_pass correctly strips prefixes before hitting MediaMTX
- Fix MediaMTX API port 49997->19997 (49997 was in Windows ephemeral range)
- Add /status proxy endpoint to OBS HTTP server so frontend can poll stream
  readiness without hitting /v3/ through NPM where auth_request blocked it
- Fix authInternalUsers: split publish (localhost only) from read (any IP)
  so WHEP viewers are not challenged with Basic Auth by MediaMTX
- Remove muted attribute from video element; show unmute/play button on
  autoplay block so viewers get audio after one click
- Fix webrtcAdditionalHosts to include LAN IP 192.168.50.254
- Fix hlsAllowOrigin->hlsAllowOrigins deprecation warning
- Move MediaMTX/HTTP server startup to script_load (not streaming started)
  so MediaMTX is ready before OBS attempts RTMP connection
- Log MediaMTX output to bin/mediamtx.log for easier debugging

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

3.8 KiB

Nginx Proxy Manager setup

Configures NPM to:

  1. Serve https://stream.hetherman.cloud with TLS + Authentik forward auth, reverse-proxying HTTP traffic to the Windows gaming PC.
  2. Forward public UDP 48189 (WebRTC media) to the gaming PC via an NPM Stream (L4 UDP proxy).

Replace <PC-LAN-IP> with the LAN IP of the Windows gaming PC (e.g., 192.168.50.10).

1. DNS

Create an A / CNAME record for stream.hetherman.cloud pointing to the same DDNS hostname / public IP your other NPM-hosted services use.

2. Router port forwarding

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

(TCP 443 is probably already forwarded for your other services; UDP 48189 is the new one for this app.)

3. NPM Proxy Host (HTTP)

In NPM, Hosts -> Proxy Hosts -> Add Proxy Host.

Details tab:

Field Value
Domain Names stream.hetherman.cloud
Scheme http
Forward Hostname <PC-LAN-IP>
Forward Port 48080
Cache Assets off
Block Common Exploits on
Websockets Support on (WebRTC signaling works without this, but it costs nothing)

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

SSL tab:

  • SSL Certificate: Request a new SSL Certificate with Let's Encrypt
  • Force SSL: on
  • HTTP/2 Support: on
  • HSTS Enabled: optional

Advanced tab: paste the entire contents of config/npm-advanced.conf. This installs the Authentik forward-auth subrequest and the sign-in redirect.

Save the proxy host. Wait for the Let's Encrypt certificate to be issued.

4. NPM Stream (UDP L4 proxy)

In NPM, Hosts -> Streams -> Add Stream.

Field Value
Incoming Port 48189
Forward Host <PC-LAN-IP>
Forward Port 48189
TCP off
UDP on

Save. NPM (nginx stream module) now forwards public UDP 48189 to MediaMTX on the gaming PC. This is the path WebRTC media takes after ICE negotiation.

5. Verify

  1. HTTP + auth: from an incognito browser on a different network, visit https://stream.hetherman.cloud. You should be redirected to 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.