name: approbotwebcam # ════════════════════════════════════════════════════════════════════════════ # NODE-MJPEG-SCHALTER – ein Node-Container besitzt die Kameras selbst # ════════════════════════════════════════════════════════════════════════════ # # Node startet pro Kamera EINEN FFmpeg (640 MJPEG passthrough) und verteilt den # Stream als multipart/x-mixed-replace an die Browser (). Für HD-Snapshots # stoppt der Schalter den Live-FFmpeg sauber (Prozess-close = Gerät frei), # greift 1280×960, schaltet zurück. go2rtc wird NICHT mehr gebraucht. # # Warum so: go2rtcs API konnte nicht zuverlässig melden, wann FFmpeg das Gerät # freigibt → Race (zwei Encoder auf /dev/videoN = ~108% CPU). Wenn Node FFmpeg # selbst startet, ist dessen 'close'-Event der harte Beweis „Gerät frei". # Siehe doc/09_Bug_reports.md. # # Portainer: Stack → Web editor → dieses YAML → Deploy. # APP_PATH = /absoluter/pfad/zum/appRobotWebcam (Code muss dort liegen) # # Firewall (Internet): TCP 8444 (Viewer + Stream + API). Sonst nichts mehr. # # Zugriff: # Viewer: http://:8444/ # Live-Stream: http://:8444/api/stream/cam0 # Snapshot (Homing): http://:8444/api/snapshot/cam0 (+ /hires) # # ROLLBACK auf den alten go2rtc-Aufbau: git checkout -- docker-compose.yaml # server.js public/ src/ (der go2rtc-Stand liegt in der Git-Historie). # ════════════════════════════════════════════════════════════════════════════ services: webcam: build: context: /tmp dockerfile_inline: | FROM node:lts-bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg \ && rm -rf /var/lib/apt/lists/* WORKDIR /usr/src/app EXPOSE 8444 image: approbotwebcam:latest container_name: AppRobotWebcam restart: unless-stopped network_mode: host command: sh -c "npm install --omit=dev && node server.js" volumes: - ${APP_PATH:-.}:/usr/src/app devices: - /dev/video0:/dev/video0 - /dev/video2:/dev/video2 group_add: - video environment: - NODE_ENV=production - PORT=8444 # Optional: Geräte/Auflösung überschreiben (sonst Auto-Detect + Defaults) # - DEV0=/dev/video0 # - DEV1=/dev/video2 # - LIVE_SIZE=640x480 # - LIVE_FPS=30 # - HIRES_SIZE=1280x960 # - HIRES_FPS=15 # ── Hinweise ──────────────────────────────────────────────────────────────────── # • Bleibt eine Kamera schwarz? Geräte prüfen: v4l2-ctl --list-devices # und ob 640x480 bzw. 1280x960 als MJPEG nativ angeboten werden: # v4l2-ctl --list-formats-ext -d /dev/video0 # Nur MJPEG-native Auflösungen bleiben CPU-arm (YUYV → Software-Encode = teuer). # • Meckert Portainer über sehr alte Compose-Syntax (dockerfile_inline)? Dann # Compose/Docker-Engine aktualisieren – dieser Aufbau braucht Compose v2. # ────────────────────────────────────────────────────────────────────────────────