fix: focus mode uses fast JPEG refresh (200ms) — no codec, works everywhere

This commit is contained in:
Claus Lohmar 2026-08-05 13:06:36 +01:00
parent b68171f370
commit 901edcf594

View file

@ -94,21 +94,23 @@ function renderLiveGrid() {
// ── Focus Overlay ──
let focusIdx = -1;
let focusTimer = null;
function openFocus(cam) {
focusIdx = cameras.indexOf(cam);
const overlay = document.getElementById('focus-overlay');
overlay.classList.remove('hidden');
updateFocus();
refreshFocus();
renderThumbs();
// Fast JPEG refresh — 200ms = ~5fps, smooth enough for monitoring.
focusTimer = setInterval(refreshFocus, 200);
}
function updateFocus() {
function refreshFocus() {
if (focusIdx < 0 || focusIdx >= cameras.length) return;
const cam = cameras[focusIdx];
document.getElementById('focus-title').textContent = cam.name;
document.getElementById('focus-time').textContent = new Date().toLocaleTimeString() + ' live';
// go2rtc MJPEG stream proxied through NextNVR — same origin, no CORS issues.
const img = document.getElementById('focus-video');
img.src = `/stream/${cam.id}?type=sub&t=${Date.now()}`;
img.src = `/recordings/${cam.name || cam.id}/latest.jpg?t=${Date.now()}`;
}
function renderThumbs() {
const strip = document.getElementById('focus-thumbs');
@ -124,20 +126,22 @@ function renderThumbs() {
}
document.getElementById('focus-close').addEventListener('click', () => {
document.getElementById('focus-overlay').classList.add('hidden');
if (focusTimer) { clearInterval(focusTimer); focusTimer = null; }
});
document.getElementById('focus-prev').addEventListener('click', () => {
if (focusIdx > 0) { focusIdx--; updateFocus(); renderThumbs(); }
if (focusIdx > 0) { focusIdx--; refreshFocus(); renderThumbs(); }
});
document.getElementById('focus-next').addEventListener('click', () => {
if (focusIdx < cameras.length - 1) { focusIdx++; updateFocus(); renderThumbs(); }
if (focusIdx < cameras.length - 1) { focusIdx++; refreshFocus(); renderThumbs(); }
});
document.addEventListener('keydown', e => {
if (document.getElementById('focus-overlay').classList.contains('hidden')) return;
if (e.key === 'Escape') {
document.getElementById('focus-overlay').classList.add('hidden');
if (focusTimer) { clearInterval(focusTimer); focusTimer = null; }
}
if (e.key === 'ArrowLeft' && focusIdx > 0) { focusIdx--; updateFocus(); renderThumbs(); }
if (e.key === 'ArrowRight' && focusIdx < cameras.length - 1) { focusIdx++; updateFocus(); renderThumbs(); }
if (e.key === 'ArrowLeft' && focusIdx > 0) { focusIdx--; refreshFocus(); renderThumbs(); }
if (e.key === 'ArrowRight' && focusIdx < cameras.length - 1) { focusIdx++; refreshFocus(); renderThumbs(); }
});
// ── Playback ──