WebRTC audio mirror: AAC cannot cross WebRTC, so transcode audio to Opus into <path>.webrtc
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>
This commit is contained in:
@@ -6,6 +6,7 @@ import { audio, effectiveMuted } from './useAudio.js'
|
||||
// WebRTC (WHEP) first, HLS fallback. Mute/volume come from the shared audio store.
|
||||
export default function Player({ params, api }) {
|
||||
const { id, user, title } = params
|
||||
const whep = params.whep || id // Opus audio mirror path when the source audio is AAC
|
||||
const videoRef = useRef(null)
|
||||
const [status, setStatus] = useState('connecting…')
|
||||
const [viewers, setViewers] = useState(params.viewers ?? 0)
|
||||
@@ -78,7 +79,7 @@ export default function Player({ params, api }) {
|
||||
const offer = await pc.createOffer()
|
||||
await pc.setLocalDescription(offer)
|
||||
await new Promise(res => { if (pc.iceGatheringState === 'complete') return res(); const t = setTimeout(res, 1500); pc.onicegatheringstatechange = () => { if (pc.iceGatheringState === 'complete') { clearTimeout(t); res() } } })
|
||||
const r = await fetch(whepUrl(id), { method: 'POST', headers: { 'Content-Type': 'application/sdp' }, body: pc.localDescription.sdp, credentials: 'same-origin' })
|
||||
const r = await fetch(whepUrl(whep), { method: 'POST', headers: { 'Content-Type': 'application/sdp' }, body: pc.localDescription.sdp, credentials: 'same-origin' })
|
||||
if (!r.ok) throw new Error('whep ' + r.status)
|
||||
await pc.setRemoteDescription({ type: 'answer', sdp: await r.text() })
|
||||
setStatus('webrtc')
|
||||
@@ -90,7 +91,7 @@ export default function Player({ params, api }) {
|
||||
}
|
||||
startWhep()
|
||||
return () => { cancelled = true; try { pc?.close() } catch {}; try { hls?.destroy() } catch {}; v.srcObject = null; v.removeAttribute('src') }
|
||||
}, [id])
|
||||
}, [id, whep])
|
||||
|
||||
const icon = muted ? '🔇' : volume === 0 ? '🔈' : volume < 0.5 ? '🔉' : '🔊'
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user