Fix live stream buffering and add websocket status
This commit is contained in:
@@ -46,6 +46,10 @@
|
||||
busy: false,
|
||||
streamOn: false,
|
||||
active: [],
|
||||
statusSocket: null,
|
||||
statusFallbackTimer: null,
|
||||
statusReconnectTimer: null,
|
||||
statusReconnectDelay: 500,
|
||||
sets: [],
|
||||
currentSetId: null,
|
||||
lastVariantPerGroup: new Map(), // anti-immediate-repeat memory
|
||||
@@ -354,9 +358,65 @@
|
||||
async function refreshActive() {
|
||||
try {
|
||||
const res = await fetchJson('/api/stream/status');
|
||||
state.active = (res.stream && res.stream.active) || [];
|
||||
renderActive();
|
||||
} catch { /* status polling is best-effort */ }
|
||||
applyStreamStatus(res.stream);
|
||||
} catch { /* status fallback is best-effort */ }
|
||||
}
|
||||
|
||||
function applyStreamStatus(stream) {
|
||||
if (!stream) return;
|
||||
state.active = stream.active || [];
|
||||
renderActive();
|
||||
}
|
||||
|
||||
function statusWsUrl() {
|
||||
const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
return `${proto}//${window.location.host}/ws/status`;
|
||||
}
|
||||
|
||||
function stopStatusFallback() {
|
||||
if (state.statusFallbackTimer) clearInterval(state.statusFallbackTimer);
|
||||
state.statusFallbackTimer = null;
|
||||
}
|
||||
|
||||
function startStatusFallback() {
|
||||
if (state.statusFallbackTimer) return;
|
||||
refreshActive();
|
||||
state.statusFallbackTimer = setInterval(refreshActive, 5000);
|
||||
}
|
||||
|
||||
function connectStatusSocket() {
|
||||
if (state.statusSocket && (
|
||||
state.statusSocket.readyState === WebSocket.OPEN ||
|
||||
state.statusSocket.readyState === WebSocket.CONNECTING
|
||||
)) return;
|
||||
|
||||
const ws = new WebSocket(statusWsUrl());
|
||||
state.statusSocket = ws;
|
||||
|
||||
ws.addEventListener('open', () => {
|
||||
state.statusReconnectDelay = 500;
|
||||
stopStatusFallback();
|
||||
ws.send(JSON.stringify({ type: 'getStatus' }));
|
||||
});
|
||||
|
||||
ws.addEventListener('message', (event) => {
|
||||
let msg = null;
|
||||
try { msg = JSON.parse(event.data); } catch { return; }
|
||||
if (msg && msg.type === 'streamStatus') applyStreamStatus(msg.stream);
|
||||
});
|
||||
|
||||
ws.addEventListener('close', () => {
|
||||
if (state.statusSocket === ws) state.statusSocket = null;
|
||||
startStatusFallback();
|
||||
clearTimeout(state.statusReconnectTimer);
|
||||
const delay = state.statusReconnectDelay;
|
||||
state.statusReconnectDelay = Math.min(10000, Math.round(state.statusReconnectDelay * 1.7));
|
||||
state.statusReconnectTimer = setTimeout(connectStatusSocket, delay);
|
||||
});
|
||||
|
||||
ws.addEventListener('error', () => {
|
||||
try { ws.close(); } catch { /* noop */ }
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSet(groupId) {
|
||||
@@ -453,5 +513,5 @@
|
||||
loadEffects();
|
||||
renderSetsSelect();
|
||||
renderActive();
|
||||
setInterval(refreshActive, 1500);
|
||||
connectStatusSocket();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user