'use strict'; const express = require('express'); const http = require('http'); const path = require('path'); const { createProxyMiddleware } = require('http-proxy-middleware'); const { createSnapshotRouter } = require('./src/snapshotService'); const PORT = parseInt(process.env.PORT ?? '8444', 10); const GO2RTC_URL = process.env.GO2RTC_URL ?? 'http://localhost:1984'; const GO2RTC_PORT = parseInt(process.env.GO2RTC_PORT ?? '1984', 10); const app = express(); // ── 1. Eigene Endpunkte (vor dem Proxy registrieren) ───────────────────────── // Stabile Snapshot-API für das Homing-Projekt app.use('/api/snapshot', createSnapshotRouter(GO2RTC_URL)); app.get('/health', async (_req, res) => { try { const r = await fetch(`${GO2RTC_URL}/api/streams`); const streams = r.ok ? await r.json() : {}; res.json({ status: r.ok ? 'ok' : 'degraded', cameras: Object.keys(streams) }); } catch (err) { res.status(503).json({ status: 'down', error: err.message }); } }); // Gibt dem Viewer die go2rtc-Port-Nummer mit – Browser baut WS direkt zu go2rtc. // Trennung HTTP (Node) / WebSocket (go2rtc) ist sauberer als ein fragiler WS-Proxy. app.get('/config.json', (_req, res) => { res.json({ go2rtcPort: GO2RTC_PORT }); }); // ── 2. HTTP-Proxy zu go2rtc (nur für Script-Dateien und API ohne WS) ───────── // /api/ws NICHT hier proxy-en – das macht der Browser direkt (s. viewer.js). const go2rtcProxy = createProxyMiddleware({ target: GO2RTC_URL, changeOrigin: true, pathFilter: ['/api', '/video-rtc.js', '/video-stream.js'], logger: console, on: { error: (err, req, res) => { console.error('[HPM] proxy error:', err.message); if (!res.headersSent) res.status(502).json({ error: 'go2rtc nicht erreichbar' }); }, }, }); app.use(go2rtcProxy); // ── 3. Statische Dateien (eigener Viewer) ──────────────────────────────────── app.use(express.static(path.join(__dirname, 'public'))); // ── Start ───────────────────────────────────────────────────────────────────── const server = http.createServer(app); server.listen(PORT, '0.0.0.0', () => { console.log(`AppRobotWebcam http://0.0.0.0:${PORT}`); console.log(` go2rtc HTTP: ${GO2RTC_URL}`); console.log(` go2rtc WS: ws://[host]:${GO2RTC_PORT} (Browser verbindet direkt)`); console.log(` Viewer: http://0.0.0.0:${PORT}/`); console.log(` Snapshot API: http://0.0.0.0:${PORT}/api/snapshot/cam0`); }); const shutdown = (sig) => { console.log(`\n${sig} – shutting down`); server.close(() => process.exit(0)); }; process.on('SIGINT', () => shutdown('SIGINT')); process.on('SIGTERM', () => shutdown('SIGTERM'));