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

6.8 KiB

OBS setup

Configures OBS Studio on the Windows gaming PC to capture the game, encode with NVENC H.264, and publish via RTMP to the local MediaMTX instance that the OBS script spawns.

Prerequisites:

  • OBS Studio 30.0 or newer.
  • FFmpeg installed and on PATH: winget install Gyan.FFmpeg (admin PowerShell). MediaMTX uses FFmpeg to transcode audio AAC->Opus for WebRTC compatibility.
  • You already ran .\scripts\install.ps1 in an elevated PowerShell, so bin\mediamtx.exe exists and the GameStream-UDP-48189 firewall rule is registered (in the disabled state).
  • Run OBS as Administrator so the script can toggle the Windows Firewall rule with netsh.

1. Load the OBS script

  1. OBS -> Tools -> Scripts -> Python Settings tab - point it at your Python 3.11 installation (e.g. C:\Users\<you>\AppData\Local\Programs\Python\Python311). If OBS shows no properties after loading the script, this is the cause.

  2. OBS -> Tools -> Scripts -> +

  3. Select obs-script/game_stream.py from this repo.

  4. In the properties panel on the right, set:

    Setting Value
    MediaMTX binary <repo>\bin\mediamtx.exe
    MediaMTX config <repo>\config\mediamtx.yml
    Frontend directory <repo>\frontend
    Frontend HTTP port 48080 (default)
    Firewall rule name GameStream-UDP-48189 (must match the rule created by install.ps1)
    Public URL https://stream.hetherman.cloud
    MediaMTX API URL http://127.0.0.1:19997
  5. Check the Script Log at the bottom - you should see:

    • [game_stream] MediaMTX started (pid=...)
    • [game_stream] Frontend HTTP server listening on 0.0.0.0:48080
    • [game_stream] game_stream.py loaded

    MediaMTX and the HTTP server start immediately on script load (not on streaming started), so they are ready before OBS attempts RTMP.

2. OBS output settings

Settings -> Output, set Output Mode to Advanced.

Streaming tab

Setting Value
Audio Encoder FFmpeg AAC (only option; MediaMTX+FFmpeg transcodes to Opus for WebRTC)
Video Encoder NVIDIA NVENC H.264

Use H.264 for maximum browser compatibility (all browsers). HEVC works in Safari and recent Chrome but not Firefox.

Encoder settings (H.264):

Setting Value
Rate Control CBR
Bitrate 8000-16000 Kbps
Keyframe Interval 2 s
Preset P5 (Quality)
Tuning Ultra Low Latency
Multipass Two Passes (Quarter Resolution)
Profile high
Look-ahead off
Max B-frames 0 (required for low-latency WebRTC)

Audio tab

Setting Value
Audio Bitrate 128 Kbps
Sample Rate 48 kHz

3. OBS stream settings

Settings -> Stream

Setting Value
Service Custom
Server rtmp://127.0.0.1/game

Note: Use RTMP (not WHIP). WHIP uses WebRTC which requires ICE/UDP negotiation between OBS and MediaMTX - this fails over localhost due to NAT hairpin issues. RTMP is plain TCP and works reliably on localhost.

Save.

4. First stream

  1. Click Start Streaming.
  2. Check the OBS Script Log - you should see:
    • [game_stream] Firewall rule 'GameStream-UDP-48189' ENABLED
    • [game_stream] OBS streaming started -> viewers can watch at: https://stream.hetherman.cloud
  3. After 2-3 seconds, MediaMTX spawns FFmpeg to transcode the audio. The game-opus path becomes ready. The stream page will show LIVE.
  4. Open https://stream.hetherman.cloud from another device, log in with Authentik, and verify video and audio play. Click the "Click to play" or "Click to unmute" button in the status bar if audio is muted.

5. Stopping

Click Stop Streaming in OBS. The script will:

  • Disable the firewall rule (GameStream-UDP-48189 -> disabled)

When OBS exits, the script also:

  • Stops the MediaMTX subprocess (and with it, the FFmpeg transcoder)
  • Stops the frontend HTTP server

Verify the firewall state from PowerShell:

Get-NetFirewallRule -DisplayName "GameStream-UDP-48189" | Select-Object Enabled

Should report False while not streaming, True while streaming.

Troubleshooting

  • No properties panel after loading script: OBS is using the Microsoft Store Python stub. Install real Python 3.11 via winget install Python.Python.3.11 and point OBS Python Settings to the install directory.
  • "MediaMTX binary not found" in the script log: the path in the script properties panel is wrong. Re-select it with the file picker.
  • OBS cannot connect / streaming fails immediately: MediaMTX did not start. Check the script log for errors. Most commonly a port conflict on 1935, 48889, or 48189 (another process is already using them). Also check bin\mediamtx.log.
  • Stream page shows "Connecting..." but never goes LIVE: FFmpeg failed to start the game-opus transcoder. Check bin\mediamtx.log for FFmpeg errors. Verify ffmpeg -version works in a new PowerShell (not the same session as before installing FFmpeg).
  • Viewers see "Stream offline" even after you click Start Streaming:
    • Check that the MediaMTX API returns ready: true for the transcoded path: curl http://localhost:19997/v3/paths/get/game-opus
    • Check OBS's own streaming indicator - if it's red, OBS is not connected. Verify the RTMP server URL is rtmp://127.0.0.1/game.
  • Viewers connect but playback freezes after a few seconds: the UDP port path is broken. Verify the firewall rule is enabled (Get-NetFirewallRule), the router port-forward for UDP 48189 goes to NPM, and the NPM Stream entry points at <PC-LAN-IP>:48189.
  • No audio: the "Click to play" or "Click to unmute" button appears in the status bar when the browser blocks autoplay. Click it once. If audio is still absent, check bin\mediamtx.log to confirm FFmpeg started successfully and the game-opus path shows both H264 and Opus tracks.