bin/mtx-on-ready.sh (runOnReady inside the mediamtx container) posts the is-live notice and, for sources whose audio is not Opus, runs ffmpeg: video copy, audio -> Opus, published over MediaMTX's loopback RTSP to <user>/<Title>.webrtc (record: no). dumpd accepts .webrtc publishes only from 127.0.0.1. The portal hides mirror paths, plays the mirror over WHEP (HLS stays on the source), holds an AAC source for 15 s while its mirror comes up, and corrects the viewer count. Verified headless with a mocked path list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
37 lines
2.2 KiB
Bash
Executable File
37 lines
2.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# MediaMTX runOnReady hook (runs INSIDE the mediamtx container; busybox sh + wget + ffmpeg from the -ffmpeg image).
|
|
# Env from MediaMTX: MTX_PATH (user/Title). From compose: LIVE_WEBHOOK_URL, LIVE_HOST.
|
|
# 1. optional Discord "is live" notice
|
|
# 2. WebRTC audio mirror: browsers cannot receive AAC over WebRTC (MediaMTX forwards Opus/G711/G722/LPCM only), and
|
|
# OBS sends AAC. For every stream whose audio is not already Opus, copy the video and transcode the audio to Opus
|
|
# into the sibling path "<user>/<Title>.webrtc". The live portal plays that path over WebRTC; recordings, HLS and
|
|
# the Discord notice stay on the original. Mirrors are published from 127.0.0.1 inside this container only, which
|
|
# is the only publisher dumpd accepts for ".webrtc" paths. Audio-only transcode: a few % of one core per stream.
|
|
# MediaMTX kills this process when the source path goes away.
|
|
case "$MTX_PATH" in *.webrtc) exit 0 ;; esac
|
|
u="${MTX_PATH%%/*}"; t="${MTX_PATH#*/}"
|
|
if [ -n "$LIVE_WEBHOOK_URL" ]; then
|
|
wget -q -O /dev/null --header="Content-Type: application/json" \
|
|
--post-data="{\"content\":\"🔴 **$u** is live: $t — https://$LIVE_HOST/\"}" "$LIVE_WEBHOOK_URL" 2>/dev/null &
|
|
fi
|
|
# which audio does the source carry? (API on loopback; "Opus" needs no mirror, no audio needs no mirror)
|
|
tracks=""
|
|
for i in 1 2 3 4 5; do
|
|
tracks=$(wget -q -O - "http://127.0.0.1:9997/v3/paths/get/$MTX_PATH" 2>/dev/null) && [ -n "$tracks" ] && break
|
|
sleep 1
|
|
done
|
|
case "$tracks" in
|
|
*Opus*) exit 0 ;;
|
|
*"MPEG-4 Audio"*|*"MPEG-1 Audio"*|*G711*|*G722*|*LPCM*|*AC-3*) ;;
|
|
*) exit 0 ;; # no (recognised) audio: nothing to mirror
|
|
esac
|
|
echo "mirror: $MTX_PATH -> $MTX_PATH.webrtc (audio -> Opus)"
|
|
n=0
|
|
while [ $n -lt 10 ]; do # retry: the source may not be readable for the first second
|
|
ffmpeg -nostdin -hide_banner -loglevel warning -fflags nobuffer -flags low_delay \
|
|
-rtsp_transport tcp -i "rtsp://127.0.0.1:8554/$MTX_PATH" \
|
|
-map 0:v:0 -map 0:a:0 -c:v copy -c:a libopus -b:a 128k -ar 48000 -ac 2 -application lowdelay -frame_duration 20 \
|
|
-f rtsp -rtsp_transport tcp "rtsp://127.0.0.1:8554/$MTX_PATH.webrtc"
|
|
n=$((n+1)); sleep 2
|
|
done
|