zebra-report: defer WebRTC mute until DJ stream actually plays

Mirror of zebra-report ebcd257.
This commit is contained in:
russell@unturf.com 2026-06-03 19:30:58 -04:00
parent ed93bb8fca
commit 5163613d1e
No known key found for this signature in database

View file

@ -3998,9 +3998,10 @@ function streamUrlFor(pubHex){
return SFU_BASE + '/stream?room=' + encodeURIComponent(roomID) + '&pub=' + pubHex;
}
function startStream(uuid, pubHex){
/* mute the WebRTC mic for this uuid so they don't double-play */
const w = remoteAudio.get(uuid);
if (w) try { w.muted = true; } catch(_){}
/* DON'T mute the WebRTC audio yet — if the fresh <audio>'s autoplay
* is blocked (common on mobile after the entry gesture's grace has
* passed) we'd be left with zero audio. Mute only after 'playing'
* fires so the WebRTC path stays as the live fallback. */
let a = streamAudio.get(uuid);
if (!a){
a = document.createElement('audio');
@ -4011,8 +4012,31 @@ function startStream(uuid, pubHex){
}
a.muted = false;
a.src = streamUrlFor(pubHex);
try { const p = a.play(); if (p && p.catch) p.catch(()=>{}); } catch(_){}
logLine('', 'stream on for '+pubHex.slice(0,12)+' — DJ mode (~2s delay, glitch-free)');
/* mute WebRTC the moment the HTTP stream actually plays a frame,
* not before. Removed on stop / error so WebRTC takes over again. */
const muteWebRtcOnPlay = () => {
const w = remoteAudio.get(uuid);
if (w) try { w.muted = true; } catch(_){}
};
const unmuteWebRtcOnFail = (why) => {
const w = remoteAudio.get(uuid);
if (w) try { w.muted = false; } catch(_){}
logLine('err', 'stream for '+pubHex.slice(0,12)+' '+why+' — staying on live WebRTC');
};
a.addEventListener('playing', muteWebRtcOnPlay, { once: true });
a.addEventListener('error', () => unmuteWebRtcOnFail('error'), { once: true });
a.addEventListener('stalled', () => unmuteWebRtcOnFail('stalled'));
try {
const p = a.play();
if (p && p.then){
p.then(() => logLine('', 'stream on for '+pubHex.slice(0,12)+' — DJ mode (~2s delay, glitch-free)'))
.catch(e => unmuteWebRtcOnFail('autoplay blocked: '+e.message));
} else {
logLine('', 'stream on for '+pubHex.slice(0,12)+' — DJ mode (~2s delay, glitch-free)');
}
} catch(e){
unmuteWebRtcOnFail('play threw: '+e.message);
}
}
function stopStream(uuid){
const a = streamAudio.get(uuid);
@ -4659,8 +4683,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-03</span><br>
md5 <span class="stamp-md5">cebb664d38a0843a3a440fa74fdf2253</span><br>
sha256 <span class="stamp-sha">67ba8ee7c7047d4f7c3a9aca5a398357ef6c24b7d57fd5ca04e3d5f6227f20a7</span><br>
md5 <span class="stamp-md5">3c056398b2b24a618e1ee01a18f9c091</span><br>
sha256 <span class="stamp-sha">f981c4df0ab237ba9dc02cb0dbca728f13a8c06dacf4bf95f0dac17408f7ad57</span><br>
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
</footer>