zebra-spaces: start remote screen tiles muted + add unmute button — fixes mobile autoplay

Mobile browsers refuse to autoplay a <video> carrying an unmuted audio
track without a user gesture; the whole element stays paused, so the
video pixels never render either. The phone listener saw a black tile
even with a healthy track flowing.

Start the remote tile muted so it autoplays everywhere; expose an
'unmute audio' button in the meta bar that toggles. The button click
counts as the gesture, so audio kicks in on demand. Local preview never
offers unmute (would feed back into the publisher's own mic).
This commit is contained in:
Russell Ballestrini 2026-06-01 20:02:03 -04:00
parent d9852e661e
commit 2fd2ac3546
No known key found for this signature in database
5 changed files with 36 additions and 19 deletions

View file

@ -1652,9 +1652,9 @@ logLine('sys', 'chat content lives in encrypted SRTP audio. no IP packets carry
})();
</script>
<footer style="max-width:820px;margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-01</span><br>
md5 <span class="stamp-md5">f1d9169e022a422b9b2f1fa166b1da3d</span><br>
sha256 <span class="stamp-sha">e8af1dceb904c649a681670056c1c664c352f0e0102ffdf202d007dbb50e0182</span><br>
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-02</span><br>
md5 <span class="stamp-md5">74f0583d5b47b420665b7bb923cfbd1b</span><br>
sha256 <span class="stamp-sha">5e06ebed815d304d9d3d4a9df270d00e0fba6a636e0c814f39346a13715b86bd</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 it against these hashes; point it 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>

View file

@ -440,9 +440,9 @@ handle /zebra-spaces-sfu* { reverse_proxy localhost:8092 { flush_interval -1
</p>
<footer style="max-width:820px;margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-01</span><br>
md5 <span class="stamp-md5">2d8b20ca6a7d4caceac7402f434d6bb0</span><br>
sha256 <span class="stamp-sha">70abdd694c78aa485d01d76fdd5e577dadce901c5aef7876ce74dadc597ece11</span><br>
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-02</span><br>
md5 <span class="stamp-md5">35cea88368ac2591fb7a075c215e242d</span><br>
sha256 <span class="stamp-sha">9989466be3b352d495cb9dcf5b11ea721f1f24d68db90678d0570635ec191c10</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 it against these hashes; point it at your own servers with ?signal= and ?turncred=</span>
</footer>

View file

@ -274,9 +274,9 @@
</p>
<footer style="max-width:820px;margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-01</span><br>
md5 <span class="stamp-md5">d7b8cf7bb3d0de305227d877211e1c68</span><br>
sha256 <span class="stamp-sha">a173bbc0c29dfd8bd11c94f66e561ba31b9c1fc7534ce2032659cd0a5e43d147</span><br>
<span style="color:#777">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-02</span><br>
md5 <span class="stamp-md5">866696ff17414e6a79b9118d5cec1242</span><br>
sha256 <span class="stamp-sha">a99c9cda25bfaaa2691f62ce7c97d1ea4cd8bb36f39271db675af147598f1638</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 it against these hashes; point it 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>

View file

@ -659,9 +659,9 @@ else wirePuppet();
</section>
<footer style="max-width:560px;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-01</span><br>
md5 <span class="stamp-md5">913f10bc546c13c1216bf7605a1b5afe</span><br>
sha256 <span class="stamp-sha">90b1c453c194824f79b77a72d5d52343baa79053894da6d2cf094c40ee4e9d48</span><br>
<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-02</span><br>
md5 <span class="stamp-md5">71881c48a78ce9205fad6fc2921e316a</span><br>
sha256 <span class="stamp-sha">bdc65afcb98c2e38dfd40e4b0cd1a2b8f26af740bced1f376deb99cd6b9ec912</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 it against these hashes; point it 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>

View file

@ -623,14 +623,31 @@ function renderScreenTile(pubHex, stream, opts){
if (!entry){
const tile = document.createElement('div'); tile.className = 'screen-tile';
const video = document.createElement('video');
/* local preview must be muted — playing back our own captured audio
* would feed back through the mic */
video.autoplay = true; video.playsInline = true; video.muted = local;
/* mobile autoplay policy refuses an unmuted <video> with audio without
* a user gesture — the whole element stays paused, no pixels render.
* Start muted on remote tiles too; an explicit unmute button below
* lets the user opt into audio with a click (counts as the gesture). */
video.autoplay = true; video.playsInline = true; video.muted = true;
const meta = document.createElement('div'); meta.className = 'screen-meta';
const who = document.createElement('span'); who.textContent = 'screen: '+label;
const ctl = document.createElement('span');
/* local preview never offers unmute — playing our own captured audio
* back would feed straight into our mic */
if (!local){
const unmute = document.createElement('button'); unmute.className = 'small';
unmute.textContent = 'unmute audio';
unmute.onclick = () => {
const turnOn = video.muted;
video.muted = !turnOn;
unmute.textContent = video.muted ? 'unmute audio' : 'mute audio';
try { video.play().catch(()=>{}); } catch(_){}
};
ctl.appendChild(unmute);
}
const pop = document.createElement('button'); pop.className = 'small';
pop.textContent = 'fullscreen'; pop.onclick = () => video.requestFullscreen && video.requestFullscreen().catch(()=>{});
meta.appendChild(who); meta.appendChild(pop);
ctl.appendChild(pop);
meta.appendChild(who); meta.appendChild(ctl);
tile.appendChild(video); tile.appendChild(meta);
$('screens').appendChild(tile);
entry = { tile, video, label };
@ -1581,9 +1598,9 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
</script>
<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-01</span><br>
md5 <span class="stamp-md5">3b4349329d1441a1ded19fb38dee687b</span><br>
sha256 <span class="stamp-sha">0e6bf4dceb9230fb54fa401f532b65a8c624dcd6a04adb73eab5455e8fdeafa2</span><br>
<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-02</span><br>
md5 <span class="stamp-md5">9f18287a705bb3427c7dd969f4dbd6e9</span><br>
sha256 <span class="stamp-sha">43e630fa94aa51360da0e051ea8381f9255dc80cb8f016a210565c6035663a8c</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>