zebra-spaces: bump playoutDelayHint to 400ms — Wi-Fi peak jitter eats 200ms buffer
Listener reported clean network (43ms RTT, 0% loss) but 53ms smoothed jitter, which on Wi-Fi typically peaks at 150-250ms inter-arrival. A 200ms playout buffer overflows on those peaks; 400ms absorbs them. Tradeoff: extra ~quarter-second of latency. For music broadcast that is invisible; for conversation it remains well below noticeable turn-taking thresholds. Applied to both SFU subscribe (mic audio path) and mesh peer audio.
This commit is contained in:
parent
383ed9af1e
commit
872d3a4df1
1 changed files with 11 additions and 9 deletions
|
|
@ -973,10 +973,12 @@ async function sfuSubscribe(){
|
|||
logLine('', 'sfu: unknown kind '+kind+' from '+shortHex(pubHex));
|
||||
return;
|
||||
}
|
||||
/* mic audio — set a small jitter-buffer hint so brief network jitter
|
||||
* doesn't cause audible drops. 100ms is enough to absorb typical
|
||||
* Wi-Fi micro-bursts without making conversation feel laggy. */
|
||||
try { ev.receiver.playoutDelayHint = 0.2; } catch(_){}
|
||||
/* mic audio — 400ms jitter-buffer target. Mobile/Wi-Fi peak inter-
|
||||
* arrival is 3-5x the smoothed jitter reported by getStats, so a
|
||||
* smoothed 50ms means 150-250ms peaks. 400ms absorbs that and feels
|
||||
* fine for music broadcasts; conversation gains ~quarter-second of
|
||||
* delay which is well below noticeable. */
|
||||
try { ev.receiver.playoutDelayHint = 0.4; } catch(_){}
|
||||
const pubHex = sid;
|
||||
/* cache stream by publisher pubkey so it survives the member's session
|
||||
* uuid changing across leave/rejoin — see flushSfuStreams */
|
||||
|
|
@ -1572,9 +1574,9 @@ async function connectToPeer(uuid, weOffer){
|
|||
let a = remoteAudio.get(uuid);
|
||||
if (!a){ a = document.createElement('audio'); a.autoplay = true; document.body.appendChild(a); remoteAudio.set(uuid, a); }
|
||||
a.srcObject = ev.streams[0] || new MediaStream([ev.track]);
|
||||
/* 100ms jitter buffer absorbs typical Wi-Fi micro-bursts without
|
||||
* adding perceptible conversation lag */
|
||||
try { ev.receiver.playoutDelayHint = 0.2; } catch(_){}
|
||||
/* 400ms jitter buffer — Wi-Fi peak inter-arrival is multiples of
|
||||
* the smoothed jitter, so a generous buffer absorbs the bursts */
|
||||
try { ev.receiver.playoutDelayHint = 0.4; } catch(_){}
|
||||
stopMeter(uuid); startMeter(uuid, a.srcObject);
|
||||
};
|
||||
pc.onicecandidate = (ev) => { /* using waitForIceGathering pattern, candidates ignored */ };
|
||||
|
|
@ -2071,8 +2073,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> · built <span class="stamp-date">2026-06-02</span><br>
|
||||
md5 <span class="stamp-md5">b3dc62bb089cc56ac842287fa3ce2c7b</span><br>
|
||||
sha256 <span class="stamp-sha">e164446240db3632db870b3f35efaf8dd5b8cbdb10b56177746bec9ba4c9fd36</span><br>
|
||||
md5 <span class="stamp-md5">b968332fc24066fa99f88860638ec179</span><br>
|
||||
sha256 <span class="stamp-sha">ba484cf6851555630d7fd6c5525d6fda834793f5e146582b8f48dff91300dac6</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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue