Live portal: React + dockview multi-stream viewer behind Authentik; MediaMTX HLS/WebRTC/API re-enabled; is-live Discord hook

live/: every active stream opens as a dockable window (WHEP, HLS fallback), audio follows the
focused window, per-window mute/volume, pinning. Caddy live.HOST block with forward-auth proxies
/api /webrtc /hls to MediaMTX on loopback and serves /srv/live. WebRTC media on 8189 (firewall).
configure.py asks the live hostname and an optional Discord webhook; MediaMTX -ffmpeg image runs
the runOnReady hook. deployLive.sh builds and ships dist/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-30 23:01:11 -05:00
parent 3d42271ae2
commit 463d9b2385
22 changed files with 2398 additions and 28 deletions

View File

@@ -2,12 +2,23 @@
logLevel: info
rtsp: no
webrtc: no
hls: no
api: no
metrics: no
pprof: no
# live portal (served to the browser only via Caddy + Authentik on live.HOST; these ports are published on 127.0.0.1)
api: yes
apiAddress: :9997
hls: yes
hlsAddress: :8888
hlsVariant: lowLatency
hlsAlwaysRemux: no
webrtc: yes
webrtcAddress: :8889
webrtcLocalUDPAddress: :8189
webrtcLocalTCPAddress: :8189
webrtcIPsFromInterfaces: no
# webrtcAdditionalHosts is set via env MTX_WEBRTCADDITIONALHOSTS (= the public hostname) in docker-compose.yml
rtmp: yes
rtmpAddress: :1935
@@ -20,6 +31,11 @@ srtAddress: :8890
# SRT: srt://HOST:8890?streamid=publish:techy/Title:techy:CHANGEME
authMethod: internal
authInternalUsers:
- user: any
permissions:
- action: read
- action: playback
- action: api
- user: techy
pass: CHANGEME_TECHY
permissions:
@@ -39,6 +55,13 @@ pathDefaults:
recordPartDuration: 1s
recordSegmentDuration: 12h # one file per stream unless it runs >12h
recordDeleteAfter: 0s # never auto-delete; the archive job handles it
# optional Discord "is live" notice (LIVE_WEBHOOK_URL set in .env). busybox wget in the -ffmpeg image.
runOnReady: >
sh -c '[ -n "$LIVE_WEBHOOK_URL" ] || exit 0;
u="${MTX_PATH%%/*}"; t="${MTX_PATH#*/}";
wget -q -O /dev/null --header="Content-Type: application/json"
--post-data="{\"content\":\"🔴 **$u** is live: $t — https://$LIVE_HOST/\"}" "$LIVE_WEBHOOK_URL"'
runOnReadyRestart: no
paths:
# any name under a streamer's prefix; inherits pathDefaults