93 lines
5.0 KiB
YAML
93 lines
5.0 KiB
YAML
name: approbotwebcam
|
||
|
||
# ════════════════════════════════════════════════════════════════════════════
|
||
# AppRobotWebcam – Node-MJPEG-Schalter
|
||
# ════════════════════════════════════════════════════════════════════════════
|
||
#
|
||
# Node besitzt jede Kamera direkt (eine CameraSwitch-Instanz pro /dev/videoN).
|
||
# Live: FFmpeg → MJPEG multipart → Browser <img>. Latenz: ~139 ms.
|
||
# HD-Grab: Live-FFmpeg stoppen (close-Event = FD frei) → hires-FFmpeg →
|
||
# JPEG an Client → Live zurück. Auflösungen in cameras.json konfiguriert.
|
||
#
|
||
# Kameras (aktuell, by-id = stabil über Reboots):
|
||
# cam0 C270 /dev/video0 Live 640×480, Hires 1280×960
|
||
# cam1 C270 /dev/video2 Live 640×480, Hires 1280×960
|
||
# cam2 C920 /dev/video4 Live 640×480, Hires 1920×1080
|
||
#
|
||
# Portainer: Stack → Web editor → dieses YAML → Deploy.
|
||
# APP_PATH = /absoluter/pfad/zum/appRobotWebcam
|
||
#
|
||
# Firewall: TCP 8444 (Viewer + Stream + API)
|
||
#
|
||
# Zugriff:
|
||
# Viewer: http://<host>:8444/
|
||
# Live-Stream: http://<host>:8444/api/stream/cam0
|
||
# Snapshot: http://<host>:8444/api/snapshot/cam0
|
||
# HD-Snapshot: http://<host>:8444/api/snapshot/cam0/hires
|
||
# Kamera-Liste: http://<host>:8444/api/cameras
|
||
# Status: http://<host>:8444/health
|
||
# ════════════════════════════════════════════════════════════════════════════
|
||
|
||
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:
|
||
# by-id (Host) → /dev/videoN (Container) – stabil über Reboots und USB-Re-Plugs.
|
||
# Rechte Seite = Pfad den cameras.json + FFmpeg im Container sehen.
|
||
- /dev/v4l/by-id/usb-046d_0825_3BB3FE20-video-index0:/dev/video0 # cam0 – C270 (046d:0825)
|
||
- /dev/v4l/by-id/usb-046d_081b_342D4F40-video-index0:/dev/video2 # cam1 – C270 (046d:081b)
|
||
- /dev/v4l/by-id/usb-046d_HD_Pro_Webcam_C920_9C5591DF-video-index0:/dev/video4 # cam2 – C920
|
||
group_add:
|
||
- video
|
||
environment:
|
||
- NODE_ENV=production
|
||
- PORT=8444
|
||
# Kamera-Konfiguration (Gerät, Name, Auflösung) → cameras.json im APP_PATH
|
||
# Globale Fallback-Werte (gelten wenn cameras.json keinen Wert hat):
|
||
# - LIVE_SIZE=640x480
|
||
# - LIVE_FPS=30
|
||
# - HIRES_SIZE=1280x960
|
||
# - HIRES_FPS=15
|
||
# - ENCODE_MODE=copybsf # copybsf = Bitstream-Copy, niedrige CPU (Default)
|
||
# # mjpeg = Re-Encode (~50%, Fallback falls copybsf zickt)
|
||
# - ON_DEMAND=true # Live nur bei Zuschauern (Default); 'false' = dauerhaft an
|
||
# - IDLE_GRACE_MS=15000 # Karenz nach letztem Zuschauer vor dem Stop
|
||
|
||
# ── Hinweise ────────────────────────────────────────────────────────────────────
|
||
# • Neue oder geänderte Kamera: cameras.json anpassen + Redeploy (kein Code-Änderung).
|
||
# by-id-Namen ermitteln: ls -la /dev/v4l/by-id/
|
||
# Neues Device hier eintragen (by-id → /dev/videoN), dann cameras.json-Eintrag.
|
||
#
|
||
# • Bleibt eine Kamera schwarz oder liefert falsche Auflösung?
|
||
# Direkt auf dem Host testen (ohne Docker, beweist was die Kamera real kann):
|
||
# node tools/hires-probe.js /dev/video4 1920x1080 copybsf
|
||
# Alternativ manuell:
|
||
# v4l2-ctl --list-formats-ext -d /dev/video4 # MJPG-Auflösungen anzeigen
|
||
# Nur MJPEG-native Auflösungen in cameras.json verwenden (YUYV = Software-Encode = ~50% CPU).
|
||
#
|
||
# • HD-Grab liefert schlechte Qualität?
|
||
# Standard ist copybsf (Kamera-JPEG pur, keine zweite Kompression).
|
||
# "hiresEncode": "mjpeg" in cameras.json nur als Fallback, erzeugt Re-Encode-Artefakte.
|
||
#
|
||
# • Code-Stand im Container prüfen:
|
||
# docker exec AppRobotWebcam grep -n "Grab (minWidth" src/cameraSwitch.js
|
||
# Zeigt die neue Log-Zeile → aktueller Code läuft. "1280-Grab" → staler Code.
|
||
#
|
||
# • Compose v2 ist Pflicht (dockerfile_inline). Bei Portainer-Warnung: Docker-Engine updaten.
|
||
# ────────────────────────────────────────────────────────────────────────────────
|