mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
refactor(cctv): separate camera source and scene components
This commit is contained in:
1 parent
ca5f5fff93
commit
519bc6c362
32 files changed
+6873
-4835
No files matched your search
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
ACTIVE_FRAME_REFRESH_MS,
|
||||
FRAME_ENDPOINT,
|
||||
MEDIA_ENDPOINT,
|
||||
} from './policy.js';
|
||||
function safeNumber(value, fallback = NaN) {
|
||||
const n = Number(value);
|
||||
return Number.isFinite(n) ? n : fallback;
|
||||
}
|
||||
function frameUrlFor(camera, refreshMs = ACTIVE_FRAME_REFRESH_MS) {
|
||||
const cadenceMs = Math.max(
|
||||
1000,
|
||||
safeNumber(refreshMs, ACTIVE_FRAME_REFRESH_MS),
|
||||
);
|
||||
const tick = Math.floor(Date.now() / cadenceMs);
|
||||
const params = new URLSearchParams({
|
||||
label: camera.name,
|
||||
city: camera.city,
|
||||
lat: camera.lat.toFixed(6),
|
||||
lon: camera.lon.toFixed(6),
|
||||
heading: String(Math.round(camera.headingDeg)),
|
||||
fov: String(Math.round(camera.fovDeg)),
|
||||
pitch: String(Math.round(camera.pitchDeg || -10)),
|
||||
ts: String(tick),
|
||||
});
|
||||
return `${FRAME_ENDPOINT}/${encodeURIComponent(camera.id)}?${params.toString()}`;
|
||||
}
|
||||
function mediaUrlFor(camera) {
|
||||
return `${MEDIA_ENDPOINT}/${encodeURIComponent(camera.id)}?ts=${Math.floor(Date.now() / 15000)}`;
|
||||
}
|
||||
/** Supply catalog/health records and the existing registered camera URL families. */
|
||||
export function createCctvSource({
|
||||
fetchImpl = (...args) => globalThis.fetch(...args),
|
||||
} = {}) {
|
||||
async function read(path, key, { signal } = {}) {
|
||||
signal?.throwIfAborted();
|
||||
const response = await fetchImpl(path, { cache: 'no-store', signal });
|
||||
if (!response.ok) throw new Error('Camera source HTTP ' + response.status);
|
||||
const payload = await response.json();
|
||||
signal?.throwIfAborted();
|
||||
if (!Array.isArray(payload?.[key]))
|
||||
throw new Error('Malformed camera ' + key + ' snapshot');
|
||||
return payload;
|
||||
}
|
||||
return {
|
||||
getCatalog(options) {
|
||||
return read('/api/cctv/sources', 'sources', options);
|
||||
},
|
||||
getHealth(options) {
|
||||
return read('/api/cctv/health', 'cameras', options);
|
||||
},
|
||||
getFrameUrl: frameUrlFor,
|
||||
getMediaUrl: mediaUrlFor,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user