zebra-report: deploy — 120s window for screen/game, 15s stays for camera
This commit is contained in:
parent
27a5319d81
commit
80a38e14c1
1 changed files with 32 additions and 16 deletions
|
|
@ -1601,21 +1601,37 @@ function flushSfuStreams(){
|
|||
* subscriber's pc and renegotiates. Browsers don't reliably fire
|
||||
* 'ended' on remote tracks under this path (Chromium half-fires,
|
||||
* Firefox stays silent). They DO fire 'mute' when RTP stops arriving.
|
||||
* Watch both: a sustained mute for >MUTE_WINDOW ms = the publisher is
|
||||
* Watch both: a sustained mute for >windowMs = the publisher is
|
||||
* (probably) gone and we remove the tile. If 'unmute' fires within
|
||||
* the window — transient network blip, NACK retransmission gap, brief
|
||||
* CPU pressure on publisher, mobile network handoff — we cancel the
|
||||
* removal.
|
||||
* CPU pressure on publisher, mobile network handoff, OR (for screen
|
||||
* shares) a long stretch of static content where the encoder simply
|
||||
* isn't producing RTP — we cancel the removal.
|
||||
*
|
||||
* Window depends on the kind of content (caller passes via windowMs):
|
||||
* - 15s for cameras: face/motion content keeps RTP flowing
|
||||
* continuously, so a 15s gap is meaningful. Generous enough to
|
||||
* weather Wi-Fi stalls and mobile network handoffs.
|
||||
* - 120s for screen / gameshare: STATIC content (a still desktop, a
|
||||
* paused video, a code editor with no caret motion) doesn't push
|
||||
* new RTP for long stretches. The encoder genuinely stops emitting
|
||||
* packets, the receiver's track goes muted, and the 15s window
|
||||
* would falsely reap a live tile. 120s lets a static screen
|
||||
* survive comfortably; a real unshare still resolves through the
|
||||
* 'ended' path within a frame.
|
||||
*
|
||||
* Window history:
|
||||
* - 3s: too aggressive — transient blips killed live tiles, the
|
||||
* 'host shares screen, other speaker loses it' regression.
|
||||
* - 15s: enough to weather Wi-Fi stalls and mobile network handoffs
|
||||
* without leaving frozen tiles around for ages. A genuine unshare
|
||||
* still removes the tile within 15s. */
|
||||
* - 3s (all kinds): killed live tiles on any transient mute.
|
||||
* - 15s (all kinds): cameras ok, but static screens vanished after
|
||||
* 15s of no motion.
|
||||
* - 15s camera / 120s screen+game (current). */
|
||||
const VIDEO_REMOVE_MUTE_WINDOW_MS = 15000;
|
||||
function watchVideoTrackForRemoval(track, removeFn){
|
||||
const VIDEO_REMOVE_MUTE_WINDOW_SCREEN_MS = 120000;
|
||||
function watchVideoTrackForRemoval(track, removeFn, windowMs){
|
||||
if (!track) return;
|
||||
if (typeof windowMs !== 'number' || !isFinite(windowMs) || windowMs <= 0){
|
||||
windowMs = VIDEO_REMOVE_MUTE_WINDOW_MS;
|
||||
}
|
||||
let timer = null, removed = false, hasFlowed = false;
|
||||
const remove = () => {
|
||||
if (removed) return;
|
||||
|
|
@ -1641,10 +1657,10 @@ function watchVideoTrackForRemoval(track, removeFn){
|
|||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
if (!removed && track.muted){
|
||||
logLine('', 'video track muted >'+(VIDEO_REMOVE_MUTE_WINDOW_MS/1000)+'s — removing tile');
|
||||
logLine('', 'video track muted >'+(windowMs/1000)+'s — removing tile');
|
||||
remove();
|
||||
}
|
||||
}, VIDEO_REMOVE_MUTE_WINDOW_MS);
|
||||
}, windowMs);
|
||||
};
|
||||
track.addEventListener('ended', remove);
|
||||
track.addEventListener('mute', onMute);
|
||||
|
|
@ -2427,14 +2443,14 @@ async function sfuSubscribe(){
|
|||
const s = ev.streams[0];
|
||||
screenStreams.set(pubHex, s);
|
||||
renderScreenTile(pubHex, s);
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (screenStreams.get(pubHex) === s) removeScreenTile(pubHex); });
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (screenStreams.get(pubHex) === s) removeScreenTile(pubHex); }, VIDEO_REMOVE_MUTE_WINDOW_SCREEN_MS);
|
||||
return;
|
||||
}
|
||||
if (kind === 'camera'){
|
||||
const s = ev.streams[0];
|
||||
cameraStreams.set(pubHex, s);
|
||||
renderCameraTile(pubHex, s);
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (cameraStreams.get(pubHex) === s) removeCameraTile(pubHex); });
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (cameraStreams.get(pubHex) === s) removeCameraTile(pubHex); }, VIDEO_REMOVE_MUTE_WINDOW_MS);
|
||||
return;
|
||||
}
|
||||
if (kind === 'game'){
|
||||
|
|
@ -2444,7 +2460,7 @@ async function sfuSubscribe(){
|
|||
const s = ev.streams[0];
|
||||
gameStreams.set(pubHex, s);
|
||||
renderVideoTile('gameshare', pubHex, s);
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (gameStreams.get(pubHex) === s) removeVideoTile('gameshare', pubHex); });
|
||||
watchVideoTrackForRemoval(ev.track, () => { if (gameStreams.get(pubHex) === s) removeVideoTile('gameshare', pubHex); }, VIDEO_REMOVE_MUTE_WINDOW_SCREEN_MS);
|
||||
return;
|
||||
}
|
||||
if (kind !== 'mic'){
|
||||
|
|
@ -3829,8 +3845,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-03</span><br>
|
||||
md5 <span class="stamp-md5">202400eb71552609f46039301779f8ed</span><br>
|
||||
sha256 <span class="stamp-sha">684fb8eb60e8a4a30f7a9781f51a3dba088401b874262a84f735f332269f5758</span><br>
|
||||
md5 <span class="stamp-md5">e7d4557587a42469e48e836866e4cc56</span><br>
|
||||
sha256 <span class="stamp-sha">027a8b232ffdcb7333dc18a1bf8f14ae68b582e3c7e9d9824288821ab80886dc</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