Umbau mit cameraSwitch Fix 1
This commit is contained in:
@@ -388,9 +388,14 @@ Eine `CameraSwitch`-Instanz pro Gerät — der **einzige** Öffner von `/dev/vid
|
||||
immer nur **einen** FFmpeg. Zustände `stopped | live | grabbing`, Mutex pro Kamera.
|
||||
|
||||
- **Live (Dauerbetrieb):** `ffmpeg -f v4l2 -input_format mjpeg -video_size 640x480
|
||||
-framerate 30 -i /dev/videoN -c:v copy -f mpjpeg pipe:1` → kein Re-Encode. Node parst
|
||||
-framerate 30 -i /dev/videoN -c:v mjpeg -q:v 5 -f mpjpeg pipe:1`. Node parst
|
||||
die mpjpeg-Frames (Content-Length-basiert), hält den letzten (für `/api/snapshot`),
|
||||
sendet sie an alle Stream-Clients. Crash → Auto-Restart nach 1,5 s.
|
||||
> ⚠ **`-c:v mjpeg` (Re-Encode), NICHT `-c:v copy`.** `copy` ist auf dieser Kamera
|
||||
> empirisch tot: 04/09 dokumentieren CPU **107%** + hängendes Bild (FFmpeg verschluckt
|
||||
> sich an den APP-Feldern des Kamera-MJPEG). Re-Encode = der bewährte ~50%-Pfad
|
||||
> (entspricht go2rtcs `#video=mjpeg`). **Dieser Fehler wurde am 2026-06-05 zunächst
|
||||
> wiederholt (copy) und dann korrigiert.**
|
||||
- **HD-Grab (`grabHires`):** Live-FFmpeg `SIGTERM` → **auf `close` warten** (FD frei) →
|
||||
1280-FFmpeg, warmlaufen (ab Frame ≥6, ≥15 KB, Breite ≥1000), besten Frame greifen →
|
||||
beenden, auf `close` warten → `finally`: **immer** Live zurück (Live hat Priorität).
|
||||
@@ -412,8 +417,8 @@ Ein Node-Container mit FFmpeg, Geräte durchgereicht, `group_add: video`. Env-Ov
|
||||
|
||||
- **Lokal verifiziert (ohne Kamera):** MJPEG-Parser (Unittest, Chunk-robust, `\r\n\r\n`
|
||||
im Body), HTTP-Routing (snapshot/stream/health, 404/503), Crash-Auto-Restart rate-limitiert.
|
||||
- **FFmpeg-Args = die der bisher funktionierenden go2rtc-Quelle** (`-f v4l2 -input_format
|
||||
mjpeg -video_size … -framerate …`), nur Ausgabe `-c:v copy -f mpjpeg`.
|
||||
- **FFmpeg = der bewährte go2rtc-`#video=mjpeg`-Pfad** (Re-Encode mjpeg→mjpeg, ~50% für
|
||||
2 Kameras), Ausgabe `-c:v mjpeg -q:v 5 -f mpjpeg`. **Nicht** `copy` (= 107%, s.o.).
|
||||
- **Auf der Hardware noch zu verifizieren:** CPU-Last, Latenz, HD-Blackout-Dauer, und der
|
||||
Bug-Reproweg unten.
|
||||
|
||||
@@ -436,8 +441,14 @@ Ein Node-Container mit FFmpeg, Geräte durchgereicht, `group_add: video`. Env-Ov
|
||||
|
||||
## Mögliche Folgeschritte
|
||||
|
||||
- **Hi-Res nativ?** `v4l2-ctl --list-formats-ext -d /dev/video0` — liefert die Kamera
|
||||
1280×960 als **MJPEG**? Falls nur YUYV → `-c:v copy` scheitert → andere native Auflösung
|
||||
oder bewusst Re-Encode (teurer).
|
||||
- **Auflösungen nativ MJPG?** ✅ **Bestätigt (2026-06-05)** via `v4l2-ctl --list-formats-ext
|
||||
-d /dev/video0`: Kamera liefert `MJPG` in **640×480 @ 30 fps** (Live) UND **1280×960 @
|
||||
30 fps** (HD). ABER: trotz nativem MJPG ist `-c:v copy` auf dieser Kamera tot (107%,
|
||||
APP-Feld-Fehler) → **`-c:v mjpeg` (Re-Encode)**. (Optional `HIRES_FPS=30` verkürzt den
|
||||
Warmup leicht.)
|
||||
- **CPU unter 50% drücken?** Re-Encode 2×640@30 ≈ 50% (wie go2rtc). Hebel, falls nötig
|
||||
(zuerst auf dem Host **messen**, nicht raten): `LIVE_FPS=15` (halbiert Encode-Last) oder
|
||||
Test des Bitstream-Filters `-c:v copy -bsf:v mjpeg2jpeg` (fügt fehlende Tables ohne
|
||||
Decode hinzu — ungetestet, könnte echtes Low-CPU bringen oder auch scheitern).
|
||||
- **On-Demand Live** (FFmpeg erst bei erstem Client) wäre stromsparender, ist aber bewusst
|
||||
weggelassen — Dauerbetrieb hält die Übergabe-Logik simpel (weniger Race-Fläche).
|
||||
|
||||
@@ -106,6 +106,16 @@ Encoder auf einem `/dev/videoN` sind konstruktiv ausgeschlossen.
|
||||
Crash-Auto-Restart rate-limitiert. **Auf der Hardware noch zu verifizieren:** CPU-Last,
|
||||
Latenz, HD-Blackout-Dauer, kein 106% nach Screenshot+Reconnect (Testplan in 05).
|
||||
|
||||
**FFmpeg-Argumente** sind identisch zu denen, die die *bisher funktionierende* go2rtc-
|
||||
Quelle erzeugte (`-f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i …`),
|
||||
nur `-c:v copy -f mpjpeg pipe:1` als Ausgabe → kein Re-Encode.
|
||||
**FFmpeg = der bewährte go2rtc-`#video=mjpeg`-Pfad:** `-f v4l2 -input_format mjpeg
|
||||
-video_size 640x480 -framerate 30 -i … -c:v mjpeg -q:v 5 -f mpjpeg pipe:1` (Re-Encode
|
||||
mjpeg→mjpeg, ~50% für 2 Kameras).
|
||||
|
||||
### ⚠ Regression am 2026-06-05 (eingebaut **und** korrigiert): `-c:v copy`
|
||||
|
||||
Erste Fassung des Schalters nutzte `-c:v copy` (Passthrough) → **CPU 100%+ und wieder
|
||||
hängendes Bild.** Ursache: `copy` ist auf dieser Kamera empirisch tot — 04/09 dokumentieren
|
||||
es (107%), FFmpeg verschluckt sich an den APP-Feldern des Kamera-MJPEG
|
||||
(`[mjpeg] unable to decode APP fields: Invalid data`) → keine validen Frames → Freeze.
|
||||
**Das war exakt der in 04/05 dokumentierte und ignorierte Punkt.** Fix: `-c:v copy` →
|
||||
`-c:v mjpeg` (Re-Encode, wie go2rtc). Lehre erneut: **erst die Doku-Fakten anwenden,
|
||||
dann bauen.**
|
||||
@@ -96,7 +96,7 @@ class CameraSwitch extends EventEmitter {
|
||||
'-f', 'v4l2', '-input_format', 'mjpeg',
|
||||
'-video_size', this.liveSize, '-framerate', String(this.liveFps),
|
||||
'-i', this.device,
|
||||
'-c:v', 'copy', '-f', 'mpjpeg', 'pipe:1',
|
||||
'-c:v', 'mjpeg', '-q:v', '5', '-f', 'mpjpeg', 'pipe:1',
|
||||
];
|
||||
let p;
|
||||
try {
|
||||
@@ -189,7 +189,7 @@ class CameraSwitch extends EventEmitter {
|
||||
'-f', 'v4l2', '-input_format', 'mjpeg',
|
||||
'-video_size', this.hiresSize, '-framerate', String(this.hiresFps),
|
||||
'-i', this.device,
|
||||
'-c:v', 'copy', '-f', 'mpjpeg', 'pipe:1',
|
||||
'-c:v', 'mjpeg', '-q:v', '5', '-f', 'mpjpeg', 'pipe:1',
|
||||
];
|
||||
let p;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user