Files
mek-tech-showcase/server/lib/camera-proxy.js
T

48 lines
1.4 KiB
JavaScript

const cache = require('./cache');
const { getCameraById } = require('./sources/smart-city-infra');
const UA = 'Mozilla/5.0 (compatible; MekTechShowcase/1.0)';
async function fetchImage(url) {
const res = await fetch(url, {
headers: { 'User-Agent': UA, Accept: 'image/*' },
signal: AbortSignal.timeout(8000)
});
if (!res.ok) return null;
const type = res.headers.get('content-type') || '';
if (!type.includes('image')) return null;
const buffer = Buffer.from(await res.arrayBuffer());
if (buffer.length < 800) return null;
return { buffer, contentType: type.split(';')[0] || 'image/jpeg' };
}
async function fetchCameraFrame(cameraId) {
const cam = getCameraById(cameraId);
if (!cam) return null;
const cacheKey = `cam-frame-${cameraId}`;
const cached = cache.get(cacheKey, 1100);
if (cached) return cached;
if (cam.youtubeId) {
const urls = [
`https://i.ytimg.com/vi/${cam.youtubeId}/maxresdefault_live.jpg`,
`https://i.ytimg.com/vi/${cam.youtubeId}/hqdefault_live.jpg`,
`https://i.ytimg.com/vi/${cam.youtubeId}/hqdefault.jpg`
];
for (const url of urls) {
try {
const frame = await fetchImage(`${url}?t=${Date.now()}`);
if (frame) {
cache.set(cacheKey, frame);
return frame;
}
} catch (_) { /* try next */ }
}
}
return null;
}
module.exports = { fetchCameraFrame };