Add guest tally (on air / off air) and host connection warning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c2549bfab0
commit
f5c5c593f9
7 files changed
+82
-4
No files matched your search
+32
-2
@@ -16,17 +16,47 @@ function connect(){
|
||||
}
|
||||
|
||||
let flashT = null;
|
||||
function flashTitle(){ // visual only - the host page must never make sound on the rig
|
||||
function flashTitle(text){ // visual only - the host page must never make sound on the rig
|
||||
if (flashT) return; const base = document.title; let on = false;
|
||||
flashT = setInterval(() => { document.title = (on = !on) ? '💬 Guest message' : base; }, 1000);
|
||||
flashT = setInterval(() => { document.title = (on = !on) ? (text || '💬 Guest message') : base; }, 1000);
|
||||
const stop = () => { clearInterval(flashT); flashT = null; document.title = base; document.removeEventListener('visibilitychange', stop); };
|
||||
document.addEventListener('visibilitychange', stop);
|
||||
}
|
||||
|
||||
// ---- tally (sign on the guest's page only)
|
||||
let onAir = false;
|
||||
$('#tally').onclick = () => send({t:'onair', on: !onAir});
|
||||
|
||||
// ---- connection warning: audible trouble on the guest -> show path over the last 10 s.
|
||||
// Concealed frames (PLC) and underruns are what listeners hear; FEC recoveries are not.
|
||||
let hist = [], warnLevel = 0;
|
||||
function checkTrouble(c){
|
||||
const box = $('#warn');
|
||||
if (!c) { hist = []; box.className = 'warnbox hidden'; warnLevel = 0; return; }
|
||||
const now = Date.now(), j = c.jb;
|
||||
if (j) hist.push({t: now, plc: j.plc, ur: j.underruns});
|
||||
while (hist.length && now - hist[0].t > 10000) hist.shift();
|
||||
let plc = 0, ur = 0;
|
||||
if (hist.length > 1) { const a = hist[0], b = hist[hist.length-1]; plc = b.plc - a.plc; ur = b.ur - a.ur; }
|
||||
const n = (k, w) => k + ' ' + w + (k === 1 ? '' : 's');
|
||||
let level = 0, msg = '';
|
||||
if (c.pc === 'disconnected' || c.pc === 'failed') { level = 2; msg = 'Guest audio ' + c.pc + ' - their network dropped out.'; }
|
||||
else if (c.pc === 'connected' && (plc >= 25 || ur >= 3)) { level = 2; msg = 'Guest connection is bad: ' + n(plc, 'patched gap') + ', ' + n(ur, 'dropout') + ' in the last 10 s.'; }
|
||||
else if (c.pc === 'connected' && (plc >= 3 || ur >= 1)) { level = 1; msg = 'Guest connection wobbling: ' + n(plc, 'patched gap') + ', ' + n(ur, 'dropout') + ' in the last 10 s.'; }
|
||||
box.textContent = msg; box.className = 'warnbox' + (level === 2 ? ' bad' : '') + (level ? '' : ' hidden');
|
||||
if (level === 2 && warnLevel < 2 && document.hidden) flashTitle('⚠ Guest connection');
|
||||
warnLevel = level;
|
||||
}
|
||||
|
||||
function fmtDur(s){ const m = Math.floor(s/60); return m + ':' + String(s%60).padStart(2,'0'); }
|
||||
|
||||
function render(s){
|
||||
$('#link').value = s.link || '';
|
||||
onAir = !!s.onAir;
|
||||
$('#tally').textContent = onAir ? '● ON AIR' : 'Off air';
|
||||
$('#tally').classList.toggle('on', onAir);
|
||||
$('#tally').disabled = !s.link;
|
||||
checkTrouble(s.call);
|
||||
$('#copy').disabled = $('#revoke').disabled = !s.link;
|
||||
const name = s.guestName || 'Guest (anonymous)';
|
||||
const c = s.call;
|
||||
|
||||
Reference in new issue
Block a user