From 0f70d621483aaf83e6b9bd1cfde6c41e94dfe5c0 Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Wed, 3 Jun 2026 22:12:59 -0400 Subject: [PATCH] zebra-report: pre-bless audio-element pool on entry click Mirror of zebra-report 44e05b2. --- zebra-report/zebra-spaces.html | 76 ++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html index e955888..f2325e6 100644 --- a/zebra-report/zebra-spaces.html +++ b/zebra-report/zebra-spaces.html @@ -1627,17 +1627,17 @@ const sfuStreamsByPubHex = new Map(); // pubHex -> MediaStream function attachSfuTrack(uuid, stream){ let a = remoteAudio.get(uuid); if (!a){ - a = document.createElement('audio'); a.autoplay = true; - a.playsInline = true; - document.body.appendChild(a); remoteAudio.set(uuid, a); + /* lease from the pre-blessed audio pool so Firefox Android's + * per-element autoplay grant carries over from the entry-button + * gesture. attachSfuTrack runs after several async hops (WS join, + * SFU subscribe negotiation, ontrack) so the click activation + * window has expired by now — only a pre-played pool element + * still has the engagement bit set. */ + a = leaseAudioElement(); + remoteAudio.set(uuid, a); applySinkTo(a); } a.srcObject = stream; - /* programmatic play in case autoplay policy needs the nudge after a track - * swap — caller already had a user gesture (entered the space). On Firefox - * Android the play() promise will reject if the gesture grace has aged - * out; the listener's play button re-runs play() inside its own gesture - * to recover. */ try { const p = a.play(); if (p && p.catch) p.catch(e => logLine('err','rtc autoplay '+uuid+': '+e.message)); @@ -4743,23 +4743,65 @@ const SILENCE_WAV = 'data:audio/wav;base64,UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAA * after a successful first prime. Mobile browsers can suspend the * audio session on tab background / leave; the next entry click needs * a fresh play() to re-bless audio for the new session. */ +/* Pool of audio elements pre-blessed for autoplay by the user gesture + * (entry button click). Firefox Android grants media autoplay + * permission PER ELEMENT, not per document — so attachSfuTrack creating + * a fresh