Multicam (c) buffer
This commit is contained in:
@@ -200,11 +200,21 @@ class CameraSwitch extends EventEmitter {
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
// ── HD-Grab: Live sauber stoppen → 1280 greifen → Live zurück ──────────────
|
||||
// Garantie: zwischen Stop und 1280-Start liegt das `close`-Event des Live-
|
||||
// ── HD-Grab: Live sauber stoppen → hires greifen → Live zurück ──────────────
|
||||
// Garantie: zwischen Stop und hires-Start liegt das `close`-Event des Live-
|
||||
// FFmpeg → /dev/videoN ist frei. Niemals zwei Encoder gleichzeitig.
|
||||
//
|
||||
// minWidth wird automatisch aus hiresSize abgeleitet (90 % der Soll-Breite),
|
||||
// damit Frames die noch auf der alten Live-Auflösung basieren abgelehnt werden.
|
||||
// Beispiel: hiresSize="1920x1080" → minWidth=1728 → lehnt 1280er-Frames ab.
|
||||
async grabHires(opts = {}) {
|
||||
const { minSize = 15000, minWidth = 1000, settleFrames = 6, maxWaitMs = 6000 } = opts;
|
||||
const hiresW = parseInt(this.hiresSize.split('x')[0], 10);
|
||||
const {
|
||||
minSize = 15000,
|
||||
minWidth = Math.floor(hiresW * 0.9), // nur Frames bei (fast) der angeforderten Breite
|
||||
settleFrames = 6,
|
||||
maxWaitMs = 10000, // mehr Zeit: Kamera braucht nach Format-Wechsel länger
|
||||
} = opts;
|
||||
if (this.lock) throw new Error('HD-Grab läuft bereits');
|
||||
this.lock = true;
|
||||
const t0 = Date.now();
|
||||
@@ -213,12 +223,19 @@ class CameraSwitch extends EventEmitter {
|
||||
try {
|
||||
// 1. Live-FFmpeg beenden, auf Prozess-Ende warten (= Device-FD frei)
|
||||
await this._killCurrentAndWait();
|
||||
this.state = 'grabbing';
|
||||
console.log(`[cam ${this.id}] HD: Live gestoppt nach ${Date.now() - t0}ms, Gerät frei → 1280-Grab`);
|
||||
|
||||
// 2. 1280-FFmpeg starten, warmlaufen lassen, besten Frame greifen
|
||||
// Kurze Pause: v4l2-Buffer der Kamera können noch Frames der alten Live-
|
||||
// Auflösung enthalten (z.B. 640×480-Rest wenn hires 1920×1080 fordert).
|
||||
// 300 ms genügen damit die Kamera den Format-Reset abschliessen kann.
|
||||
await sleep(300);
|
||||
|
||||
this.state = 'grabbing';
|
||||
console.log(`[cam ${this.id}] HD: Live gestoppt nach ${Date.now() - t0}ms, Gerät frei → ${this.hiresSize}-Grab (minWidth=${minWidth})`);
|
||||
|
||||
// 2. hires-FFmpeg starten, warmlaufen lassen, besten Frame greifen
|
||||
const jpeg = await this._captureHires({ minSize, minWidth, settleFrames, maxWaitMs });
|
||||
console.log(`[cam ${this.id}] HD OK – ${jpeg.length} bytes, Breite=${readJpegWidth(jpeg) ?? '?'} (${Date.now() - t0}ms)`);
|
||||
const gotW = readJpegWidth(jpeg) ?? '?';
|
||||
console.log(`[cam ${this.id}] HD OK – ${jpeg.length} bytes, Breite=${gotW}px (Soll: ${hiresW}px, ${Date.now() - t0}ms)`);
|
||||
return jpeg;
|
||||
} finally {
|
||||
// 3. Zurück auf Live, sofern noch Verbraucher da sind (On-Demand). Live hat Priorität.
|
||||
|
||||
Reference in New Issue
Block a user