diff --git a/cameras.json b/cameras.json
index 26ddfcf..eaa7d27 100644
--- a/cameras.json
+++ b/cameras.json
@@ -28,7 +28,8 @@
"stream": true,
"hires": true,
"note": "usb-046d_HD_Pro_Webcam_C920_9C5591DF-video-index0",
- "hiresSize": "1920x1080"
+ "hiresSize": "1920x1080",
+ "hiresEncode": "mjpeg"
}
]
}
diff --git a/doc/05_screenShot_roadmap.md b/doc/05_screenShot_roadmap.md
index 89186d7..06fbc3d 100644
--- a/doc/05_screenShot_roadmap.md
+++ b/doc/05_screenShot_roadmap.md
@@ -1,483 +1,204 @@
-> # ⛔ ABGELÖST (2026-06-05) — dieser Ansatz war die Ursache des 106%-Bugs
->
-> Der unten beschriebene **Consumer-Umhängen-Ansatz mit go2rtc** (`cam0` loslassen →
-> go2rtc gibt Gerät frei → `cam0_hires` greifen) hat sich als **prinzipiell racy**
-> erwiesen: go2rtcs API kann nicht zuverlässig melden, wann FFmpeg `/dev/videoN`
-> freigibt → zwei Encoder auf einem Gerät → **106% CPU + Freeze** (siehe `09_Bug_reports.md`).
->
-> **Aktuelle, maßgebliche Architektur:** **Node-MJPEG-Schalter, go2rtc entfernt.**
-> Node besitzt die Kameras selbst; das `close`-Event des eigenen FFmpeg ist der harte
-> Beweis „Gerät frei". Das Race ist damit konstruktiv ausgeschlossen.
->
-> | | alt (unten, abgelöst) | **neu (maßgeblich)** |
-> |-|----------------------|----------------------|
-> | Geräte-Öffner | go2rtc | **Node** `src/cameraSwitch.js` |
-> | Live | go2rtc-WS + `video-stream.js` | MJPEG multipart → `
` |
-> | HD-Grab | 2. go2rtc-Stream `cam_hires` (Race) | Schalter: Live stoppen (`close`=FD frei) → 1280 → zurück |
-> | Multi-User | brach | gelöst (ein FFmpeg → Fan-out) |
->
-> **→ Neue Architektur + Hardware-Testplan stehen weiter unten in diesem Dokument
-> (Abschnitt „## Node-MJPEG-Schalter").** Alles ab hier bis dorthin ist **Historie**.
+# AppRobotWebcam – Snapshot & HD-Grab
----
-
-# AppRobotWebcam – Hi-Res-Snapshot via Consumer-Umhängen ⛔ (historisch)
-
-> Status: **Phase 2 implementiert und funktional** (2026-06-04):
-> HD-Grab liefert echten 1280×960-Frame (76071 bytes bestätigt). Bekanntes Problem
-> behoben: `_hires`-Streams aus Kameraliste gefiltert. CPU ~35 % stabil.
-> Vorgeschichte & gescheiterte Ansätze: siehe `04_Delay_roadmap.md` (Abschnitt
-> „KONSOLIDIERT"). Diese Datei beschreibt den Ansatz, der die dort dokumentierten
-> Fehler **strukturell** umgeht.
-
----
-
-## Grundidee
-
-Das Kernproblem aller bisherigen Versuche: **Eine USB-Kamera lässt sich nur einmal
-öffnen**, und der Live-Viewer zwingt go2rtc, das Gerät zu halten (per on-demand-
-Reconnect). Jeder Versuch, go2rtc das Gerät zu *entreißen* oder die Live-Quelle zur
-Laufzeit *umzuschalten*, ist gescheitert (device-busy, bzw. `PATCH` hängt an → 107 %).
-
-**Neuer Ansatz – das Problem umdrehen:** Nicht das Gerät dem Stream entreißen, sondern
-**die Zuschauer vom Live-Stream wegziehen.** Hat `cam0` keine Zuschauer mehr, stoppt
-go2rtc den Producer von selbst (on-demand) und gibt das Gerät frei. Dann kann ein
-separater Hi-Res-Stream es kurz für sich haben.
-
-### Warum das sicher ist (im Gegensatz zu allem vorher)
-
-- **`cam0` wird nie verändert.** Kein `PATCH`/`PUT`/`DELETE` auf den Live-Stream.
- Das Append-Problem (107 %) kann nicht auftreten.
-- **Zur Laufzeit nur LESENDE go2rtc-Aufrufe**: `GET /api/streams`, `GET /api/frame.jpeg`.
- Die einzige „schreibende" Änderung ist das Hinzufügen von `cam0_hires` in der Config
- (per Redeploy, nicht zur Laufzeit).
-- **Kleiner Schadensradius**: Geht etwas schief, ist die Erholung „Browser wieder auf
- `cam0` hängen" → go2rtc startet `cam0` neu. Keine kaputte Stream-Definition, die bis
- zum Neustart hängt.
-
-Damit respektiert der Ansatz die eisernen Regeln aus `04_*` (Snapshot-Pfad read-only,
-keine Laufzeit-Mutation von cam0/cam1).
+> Status: **Implementiert**. Architektur seit 2026-06-05 (Node-MJPEG-Schalter).
+> Gemessene Werte: Latenz 139 ms, ~5 % idle, ~35 %/Kamera aktiv, HD-Grab ~2–3 s.
---
## Architektur
-| Stream | Quelle | on-demand | Zweck |
-|--------|--------|-----------|-------|
-| `cam0` | Kamera @640 | ja | **unverändert** – Live-Stream |
-| `cam1` | Kamera @640 | ja | **unverändert** – Live-Stream |
-| `cam0_hires` | Kamera @1280×960 | ja | **nur** für den Hi-Res-Grab (Phase 2) |
-| `cam1_hires` | Kamera @1280×960 | ja | dito für cam1 |
-
-**Platzhalter = rein clientseitig**, kein go2rtc-Stream nötig:
-Der Browser friert beim Umhängen den zuletzt gezeigten Live-Frame auf einem `