diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html
index 18ecd80..3b4b3b3 100644
--- a/zebra-report/zebra-spaces.html
+++ b/zebra-report/zebra-spaces.html
@@ -1667,14 +1667,16 @@ function attachSfuTrack(uuid, stream){
(t0 ? ' tr0={en='+t0.enabled+' mu='+t0.muted+' rs='+t0.readyState+'}' : ''));
try {
const p = a.play();
- if (p && p.catch) p.catch(e => {
- logLine('err','rtc autoplay '+uuid.slice(0,4)+': '+e.message);
- flagAudioBlocked('rtc autoplay '+uuid.slice(0,4));
- });
+ if (p && p.catch) p.catch(e => logLine('err','rtc autoplay '+uuid.slice(0,4)+': '+e.message));
} catch(e){
logLine('err','rtc play threw '+uuid.slice(0,4)+': '+e.message);
- flagAudioBlocked('rtc play threw '+uuid.slice(0,4));
}
+ /* If play() returns a resolved promise but the element stays paused
+ * at ct=0 (Firefox Android srcObject-swap kills the pre-blessed
+ * engagement silently), the telemetry tick's wedge-recovery will
+ * detect that within 5s and lease a fresh pool element. No user-
+ * visible notice — fox: tap-anywhere from 6c9d1b8 was rejected for
+ * adding noise, automatic silent recovery is the right shape. */
stopMeter(uuid); startMeter(uuid, stream);
logLine('', 'sfu: receiving '+((members.get(uuid)||{}).handle || uuid));
}
@@ -3424,12 +3426,17 @@ async function dumpTelemetry(){
} catch(e){ parts.push('stats.err=' + e.message); }
}
/* every