diff --git a/services/capture/src/capture-manager.js b/services/capture/src/capture-manager.js index 2d5fd34..581c619 100644 --- a/services/capture/src/capture-manager.js +++ b/services/capture/src/capture-manager.js @@ -7,6 +7,8 @@ import { createUploadStream } from './s3/client.js'; const S3_BUCKET = process.env.S3_BUCKET || 'wild-dragon'; +const PRE_ROLL_SECONDS = parseInt(process.env.PRE_ROLL_SECONDS || '5', 10); + // Growing-files mode: writes the master to a local SMB-backed share that the // editor can mount, instead of streaming to S3 in real time. The promotion @@ -1051,13 +1053,24 @@ exit "$BMXRC" // The stop handler sets needsProxy=true so the worker picks it up. const proxyKey = null; - const startedAt = new Date().toISOString(); - this._sessionIdForBridge = sessionId; const { inputArgs, isNetwork, bridgeProcess = null, audioFifo = null, interlaced = false, audioInputIndex = 0 } = await this._buildInputArgs({ sourceType, sourceBackend, device, port, board, sourceUrl, listen, listenPort, streamKey, }); + // ── Pre-roll: discard initial unstable frames ──────────────────────────── + if (bridgeProcess && (sourceType === 'deltacast' || sourceType === 'blackmagic' || sourceType === 'sdi')) { + console.log(`[capture] pre-rolling: discarding ${PRE_ROLL_SECONDS}s of frames`); + // Attach temporary drain listener. + bridgeProcess.stdout.on('data', () => {}); + await new Promise(r => setTimeout(r, PRE_ROLL_SECONDS * 1000)); + bridgeProcess.stdout.removeAllListeners('data'); + console.log(`[capture] pre-roll complete.`); + } + + const startedAt = new Date().toISOString(); + const recordingStartedAt = Date.now(); + // Audio input index is returned EXPLICITLY by _buildInputArgs (audioInputIndex) // rather than guessed from sourceType/FC_SLOT_ID — that guess was wrong for // the legacy deltacast FIFO path (which has audio at input 1 but no FC_SLOT_ID), diff --git a/services/web-ui/public/screens-ingest.jsx b/services/web-ui/public/screens-ingest.jsx index 9f7df4a..854d4cc 100644 --- a/services/web-ui/public/screens-ingest.jsx +++ b/services/web-ui/public/screens-ingest.jsx @@ -759,14 +759,6 @@ function RecorderRow({ recorder: initialRecorder, onRefresh }) { String(d % 60).padStart(2, '0'); }, [isRec, elapsedSecs]); - // Show live fps when recording and signal is healthy; fall back to configured value. - const displayFramerate = React.useMemo(() => { - if (isRec && liveStatus && liveStatus.currentFps != null && liveStatus.currentFps > 0) { - return Number(liveStatus.currentFps).toFixed(2) + ' fps'; - } - return recorder.framerate || 'native'; - }, [isRec, liveStatus, recorder.framerate]); - const displaySignal = liveStatus ? (liveStatus.signal || '·') : (isRec ? 'connecting…' : '·'); @@ -861,10 +853,6 @@ function RecorderRow({ recorder: initialRecorder, onRefresh }) { {displaySignal} -
-
Framerate
-
{displayFramerate}
-
{!isRec && ( @@ -958,11 +946,6 @@ function CapturePortChip({ port, sigEntry }) { {label} - {sigEntry && sigEntry.currentFps != null && ( - - {Number(sigEntry.currentFps).toFixed(1)} fps - - )}