feat(capture): AUDIO_OFFSET_MS knob for fixed A/V alignment trim
The deltacast bridge captures audio and video on separate VHD streams; any constant capture-path latency difference shows as a fixed A/V offset (e.g. audio slightly ahead of video) even though stream lengths stay locked (no drift, verified ~1 frame over 461s). AUDIO_OFFSET_MS applies an -itsoffset on the SDI/Deltacast audio input only: positive DELAYS audio (audio-ahead case), negative advances it. Default 0 = no change, fully non-destructive, clamped to +/-1000ms. Lets an operator dial out residual offset with a lipsync loop without a code change.
This commit is contained in:
parent
e64281c9fd
commit
c40de38c45
1 changed files with 17 additions and 0 deletions
|
|
@ -197,6 +197,21 @@ const CAPTURE_GPU_INDEX = (() => {
|
|||
// as an encoder option right after -c:v. Returns [] when no pin is configured.
|
||||
const nvencGpuSel = () => (CAPTURE_GPU_INDEX != null ? ['-gpu', String(CAPTURE_GPU_INDEX)] : []);
|
||||
|
||||
// Optional fixed A/V alignment trim for the SDI/Deltacast audio input. The
|
||||
// deltacast bridge captures audio and video on separate VHD streams; any
|
||||
// constant capture-path latency difference between them shows as a fixed A/V
|
||||
// offset (e.g. audio slightly ahead of video) even though stream LENGTHS stay
|
||||
// locked (no drift). AUDIO_OFFSET_MS lets an operator dial that out without a
|
||||
// rebuild: POSITIVE value DELAYS audio (use when audio is AHEAD of video),
|
||||
// NEGATIVE advances it. Applied as ffmpeg `-itsoffset` on the audio input only.
|
||||
// Default 0 = no change (fully non-destructive). Range-clamped to ±1000 ms.
|
||||
const audioOffsetArgs = () => {
|
||||
const raw = parseFloat(process.env.AUDIO_OFFSET_MS || '0');
|
||||
if (!Number.isFinite(raw) || raw === 0) return [];
|
||||
const ms = Math.max(-1000, Math.min(1000, raw));
|
||||
return ['-itsoffset', (ms / 1000).toFixed(4)];
|
||||
};
|
||||
|
||||
function hevcNvencArgs(framerate, growing) {
|
||||
const base = ['-c:v', 'hevc_nvenc', ...nvencGpuSel(), '-preset', 'p4', '-rc', 'vbr', '-profile:v', 'main10'];
|
||||
if (growing) {
|
||||
|
|
@ -821,6 +836,8 @@ class CaptureManager {
|
|||
'-f', 's16le',
|
||||
'-ar', '48000',
|
||||
'-ac', '2',
|
||||
// Optional fixed A/V trim (env AUDIO_OFFSET_MS); default empty = no shift.
|
||||
...audioOffsetArgs(),
|
||||
'-i', audioFifoPath,
|
||||
],
|
||||
isNetwork: false,
|
||||
|
|
|
|||
Loading…
Reference in a new issue