Claude: WebRTC Versuch
This commit is contained in:
@@ -2,46 +2,47 @@
|
||||
|
||||
const express = require('express');
|
||||
|
||||
// Returns an Express router mounted at /api/snapshot
|
||||
// GET /api/snapshot → JSON listing of cameras
|
||||
// GET /api/snapshot/cam0 → latest JPEG from cam0
|
||||
// GET /api/snapshot/cam1 → latest JPEG from cam1
|
||||
function createSnapshotRouter(streams) {
|
||||
// Proxiert go2rtc-Frame-API als /api/snapshot/:id
|
||||
// GET /api/snapshot → JSON mit Kamera-Liste (von go2rtc /api/streams)
|
||||
// GET /api/snapshot/cam0 → aktuelles JPEG-Frame (von go2rtc /api/frame?src=cam0)
|
||||
function createSnapshotRouter(go2rtcUrl) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', (_req, res) => {
|
||||
res.json({
|
||||
cameras: streams.map((s, i) => ({
|
||||
id: `cam${i}`,
|
||||
device: s.device,
|
||||
running: s.isRunning,
|
||||
clients: s.clientCount,
|
||||
hasFrame: s.latestFrame !== null,
|
||||
url: `/api/snapshot/cam${i}`,
|
||||
})),
|
||||
});
|
||||
router.get('/', async (_req, res) => {
|
||||
try {
|
||||
const r = await fetch(`${go2rtcUrl}/api/streams`);
|
||||
if (!r.ok) throw new Error(`go2rtc ${r.status}`);
|
||||
const streams = await r.json();
|
||||
res.json({
|
||||
cameras: Object.keys(streams).map(id => ({
|
||||
id,
|
||||
url: `/api/snapshot/${id}`,
|
||||
})),
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(503).json({ error: `go2rtc nicht erreichbar: ${err.message}` });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', (req, res) => {
|
||||
const idx = parseInt(req.params.id.replace('cam', ''), 10);
|
||||
if (isNaN(idx) || !streams[idx]) {
|
||||
return res.status(404).json({ error: 'camera not found' });
|
||||
router.get('/:id', async (req, res) => {
|
||||
const { id } = req.params;
|
||||
try {
|
||||
const upstream = await fetch(`${go2rtcUrl}/api/frame?src=${encodeURIComponent(id)}`);
|
||||
if (!upstream.ok) {
|
||||
return res.status(upstream.status).json({ error: 'kein Frame verfügbar' });
|
||||
}
|
||||
const buf = Buffer.from(await upstream.arrayBuffer());
|
||||
res.set({
|
||||
'Content-Type': 'image/jpeg',
|
||||
'Content-Length': buf.length,
|
||||
'Cache-Control': 'no-store',
|
||||
'X-Camera-Id': id,
|
||||
'X-Timestamp': new Date().toISOString(),
|
||||
});
|
||||
res.end(buf);
|
||||
} catch (err) {
|
||||
res.status(503).json({ error: `go2rtc: ${err.message}` });
|
||||
}
|
||||
|
||||
const frame = streams[idx].latestFrame;
|
||||
if (!frame) {
|
||||
return res.status(503).json({ error: 'no frame available yet – stream may still be starting' });
|
||||
}
|
||||
|
||||
res.set({
|
||||
'Content-Type': 'image/jpeg',
|
||||
'Content-Length': frame.length,
|
||||
'Cache-Control': 'no-store',
|
||||
'X-Camera-Id': `cam${idx}`,
|
||||
'X-Camera-Device': streams[idx].device,
|
||||
'X-Timestamp': new Date().toISOString(),
|
||||
});
|
||||
res.end(frame);
|
||||
});
|
||||
|
||||
return router;
|
||||
|
||||
Reference in New Issue
Block a user