80 lines
4.4 KiB
YAML
80 lines
4.4 KiB
YAML
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 (<img>). 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://<host>:8444/
|
||
# Live-Stream: http://<host>:8444/api/stream/cam0
|
||
# Snapshot (Homing): http://<host>:8444/api/snapshot/cam0 (+ /hires)
|
||
#
|
||
# ROLLBACK auf den alten go2rtc-Aufbau: git checkout <commit> -- 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:
|
||
# Jede Kamera aus cameras.json muss hier aufgeführt sein.
|
||
# Empfehlung: statt /dev/videoN → persistente by-id-Pfade verwenden
|
||
# (ls -la /dev/v4l/by-id/ auf dem Server zeigt die Namen)
|
||
- /dev/video0:/dev/video0 # C270 (046d:0825) → cam0 in cameras.json
|
||
- /dev/video2:/dev/video2 # C270 (046d:081b) → cam1 in cameras.json
|
||
- /dev/video4:/dev/video4 # C920 HD Pro → cam2 in cameras.json
|
||
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 ────────────────────────────────────────────────────────────────────
|
||
# • 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.
|
||
# ────────────────────────────────────────────────────────────────────────────────
|