diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html index 95ad5f1..b185773 100644 --- a/zebra-report/zebra-spaces.html +++ b/zebra-report/zebra-spaces.html @@ -1640,6 +1640,7 @@ const sfuStreamsByPubHex = new Map(); // pubHex -> MediaStream function attachSfuTrack(uuid, stream){ let a = remoteAudio.get(uuid); + const fresh = !a; if (!a){ /* lease from the pre-blessed audio pool so Firefox Android's * per-element autoplay grant carries over from the entry-button @@ -1650,12 +1651,26 @@ function attachSfuTrack(uuid, stream){ a = leaseAudioElement(); remoteAudio.set(uuid, a); applySinkTo(a); + /* one-shot breadcrumbs so we can see whether the new path lights + * up at all, vs. the silent-but-state=connected pattern. */ + a.addEventListener('playing', () => logLine('', 'rtc playing '+uuid.slice(0,4)+' ct='+a.currentTime.toFixed(2)), { once: true }); + a.addEventListener('pause', () => logLine('err','rtc paused '+uuid.slice(0,4)+' ct='+a.currentTime.toFixed(2))); + a.addEventListener('ended', () => logLine('err','rtc ended '+uuid.slice(0,4))); + a.addEventListener('stalled', () => logLine('err','rtc stalled '+uuid.slice(0,4))); + a.addEventListener('error', () => logLine('err','rtc error '+uuid.slice(0,4)+' code='+(a.error?a.error.code:'?'))); } a.srcObject = stream; + const tracks = stream && stream.getAudioTracks ? stream.getAudioTracks() : []; + const t0 = tracks[0]; + logLine('', 'sfu attach '+uuid.slice(0,4)+' fresh='+(fresh?1:0)+ + ' tracks='+tracks.length+ + (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+': '+e.message)); - } catch(_){} + 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); + } stopMeter(uuid); startMeter(uuid, stream); logLine('', 'sfu: receiving '+((members.get(uuid)||{}).handle || uuid)); } @@ -3355,6 +3370,88 @@ function stopAlivePings(){ clearInterval(aliveTimer); aliveTimer = null; } +/* Telemetry tick — fired every TELEMETRY_INTERVAL_MS while in a room. + * Dumps PC states + receiver RTP counters +