# AppRobotWebcam Webcam-Service für den AppRobot. Liefert Live-MJPEG-Streams und HD-Standbilder über einen einzelnen HTTP-Port — als Docker-Container, ohne externe Streaming-Server. ## Was es tut | | | |---|---| | **Live-Stream** | MJPEG multipart im Browser ``, ~139 ms Latenz | | **HD-Snapshot** | Ein JPEG pro Kamera auf Knopfdruck oder per HTTP GET | | **Snapshot alle** | Alle Kameras parallel in einem Schritt | | **REST-API** | Kameraliste, Snapshots, Streams — für andere Container nutzbar | ## Kameras (aktuell) | ID | Modell | Live | HD-Grab | |---|---|---|---| | cam0 | Logitech C270 | 640×480 | 1280×960 | | cam1 | Logitech C270 | 640×480 | 1280×960 | | cam2 | Logitech C920 | 640×480 | 1920×1080 | Konfiguration ausschliesslich über `cameras.json` — kein Redeploy bei Kamera-Änderungen. ## Zugriff ``` http://:8444/ Viewer http://:8444/api/stream/cam0 Live-MJPEG http://:8444/api/snapshot/cam0 640er JPEG http://:8444/api/snapshot/cam0/hires HD-JPEG http://:8444/api/cameras Kamera-Metadaten (JSON) http://:8444/health Status ``` ## Deploy (Portainer) 1. Portainer → Stacks → Web editor → `docker-compose.yaml` einfügen 2. `APP_PATH` auf den absoluten Pfad des Projektverzeichnisses setzen 3. Deploy — der Container baut sich selbst (Node + FFmpeg) ```yaml # Minimal-Konfiguration: APP_PATH=/home/user/appRobotWebcam ``` ## Architektur ``` cameras.json → server.js → CameraSwitch (/dev/videoN) ├── Live: ffmpeg → MJPEG → Browser └── Grab: Live stoppen → hires → zurück ``` Ein FFmpeg pro Kamera, nie zwei gleichzeitig. Das `close`-Event ist der harte Beweis „Gerät frei" — kein Race, kein 106%-CPU-Bug (der mit go2rtc aufgetreten war). ## Dokumentation | Datei | Inhalt | |---|---| | `doc/01_WebcamRoadmap.md` | Ziel, Architektur, Entwicklungsgeschichte | | `doc/05_screenShot_roadmap.md` | HD-Grab, Encode-Qualität, Kamera-Eigenheiten | | `doc/07_multipleCam_roadmap.md` | cameras.json-Referenz, Multi-Kamera-Setup | | `doc/09_Bug_reports.md` | Bug-Dokumentation |