diff --git a/cameras.json b/cameras.json index cfb2c0c..8c7ffbe 100644 --- a/cameras.json +++ b/cameras.json @@ -8,7 +8,8 @@ "stream": true, "hires": true, "note": "usb-046d_0825_3BB3FE20-video-index0", - "hiresSize": "1280x960" + "hiresSize": "1280x960", + "liveSize": "320x240" }, { "id": "cam1", @@ -18,7 +19,8 @@ "stream": true, "hires": true, "note": "usb-046d_081b_342D4F40-video-index0", - "hiresSize": "1280x960" + "hiresSize": "1280x960", + "liveSize": "320x240" }, { "id": "cam2", @@ -28,7 +30,8 @@ "stream": true, "hires": true, "note": "usb-046d_HD_Pro_Webcam_C920_9C5591DF-video-index0", - "hiresSize": "1920x1080" + "hiresSize": "1920x1080", + "liveSize": "320x240" } ] } diff --git a/doc/12_cameraConfig_roadmap.md b/doc/12_cameraConfig_roadmap.md new file mode 100644 index 0000000..93ffa74 --- /dev/null +++ b/doc/12_cameraConfig_roadmap.md @@ -0,0 +1,117 @@ +## Roadmap – Dynamische Kamera-Konfiguration (config.html) + +**Ziel:** Live-Auflösung pro Kamera zur Laufzeit umschalten, ohne Datei-Editor oder Container-Restart. + +--- + +## Kontext + +Alle drei Kameras (C270, C920, C922) unterstützen dieselben MJPEG-nativen Auflösungen: + +| Auflösung | Pixel | Faktor ggü. 640×480 | +|-----------|-------|----------------------| +| 160×120 | 19'200 | −96% | +| 320×240 | 76'800 | −83% | +| 640×360 | 230'400 | −53% (16:9) | +| 640×480 | 307'200 | Referenz (aktuell) | +| 800×600 | 480'000 | +56% | +| 1280×720 | 921'600 | +200% | + +Nur MJPEG-native Auflösungen verwenden – sonst fällt V4L2 auf YUYV (unkomprimiert) zurück +und FFmpeg muss software-encoden (~50% CPU pro Kamera). + +**Priorität:** Latenz > CPU > Bildqualität. Bandbreite ist der Engpass beim Internet-Zugriff. + +--- + +## Geplante UI: `/config.html` + +Separate Admin-Seite (kein Viewer-Umbau nötig). Pro Kamera eine Zeile: + +``` +┌─────────────────────────────────────────────────────┐ +│ Kamera-Konfiguration │ +├──────────┬────────────┬──────────┬──────────────────┤ +│ cam0 │ Kamera 0 │ [320×240 ▼] │ Live: 320×240│ +│ cam1 │ Kamera 1 │ [640×360 ▼] │ Live: 640×360│ +│ cam2 │ Kamera 2 │ [Aus ▼] │ Live: aus │ +├──────────┴────────────┴──────────┴──────────────────┤ +│ [Speichern & Neu starten] │ +└─────────────────────────────────────────────────────┘ +``` + +**ComboBox-Optionen pro Kamera:** +- `Aus` → Stream deaktivieren (`stream: false`) +- `160×120` +- `320×240` +- `640×360` +- `640×480` (aktuell Default) +- `800×600` +- `1280×720` + +--- + +## Implementierung + +### Phase 1 – API-Endpunkt (server.js / neues Modul) + +**GET `/api/config`** → liefert aktuelle Konfiguration aller Kameras: +```json +{ + "cameras": [ + { "id": "cam0", "liveSize": "320x240", "stream": true }, + ... + ] +} +``` + +**POST `/api/config`** → nimmt neue Konfiguration entgegen: +```json +{ + "cameras": [ + { "id": "cam0", "liveSize": "640x360", "stream": true }, + { "id": "cam1", "liveSize": "320x240", "stream": true }, + { "id": "cam2", "stream": false } + ] +} +``` + +Ablauf im Handler: +1. Validierung (nur erlaubte Auflösungen akzeptieren) +2. `cameras.json` aktualisieren +3. Pro geänderter Kamera: Live-FFmpeg stoppen (`_killCurrentAndWait`) + mit neuen Params neu starten (`_spawnLive`) – kein Container-Restart nötig + +### Phase 2 – `config.html` (statische Seite in `/public`) + +- Liest beim Laden `GET /api/config` +- Zeigt pro Kamera ein `