From 7451d7c7036676438a073e099c8caa6e7b76ae3f Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Sun, 31 May 2026 16:15:16 -0400 Subject: [PATCH] fix(playout): lighter 360p/20fps preview encode so the CPU re-mux keeps up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 720p30 libx264 preview re-encode couldn't sustain real time on the CPU-only sidecar (running alongside CasparCG's mixer + STREAM consumer): the UDP input overran and the HLS output stalled, freezing the playlist so hls.js saw a static live edge (monitor black). Drop the confidence monitor to 360p / 20fps / ultrafast (-g 40 = 2.0s GOP) — a fraction of the cost, sustains real time comfortably. NVENC would be ideal but the image's static ffmpeg has no nvenc encoder; 360p ultrafast is plenty for a preview. Co-Authored-By: Claude Opus 4.8 --- services/playout/src/playout-manager.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/services/playout/src/playout-manager.js b/services/playout/src/playout-manager.js index 989c767..c846483 100644 --- a/services/playout/src/playout-manager.js +++ b/services/playout/src/playout-manager.js @@ -230,12 +230,19 @@ export class PlayoutManager { // logs "sliding 0.00 / MISSED", never loads a fragment, and the monitor // stays black even though the stream decodes cleanly server-side. A // standalone ffmpeg honours -force_key_frames, so every GOP (and thus - // every HLS segment) is exactly 2.0s. fps=30 forces CFR; scale to 720p - // keeps the confidence monitor cheap. - '-vf', 'fps=30,scale=-2:720,format=yuv420p', - '-c:v', 'libx264', '-preset', 'veryfast', '-tune', 'zerolatency', - '-b:v', '1500k', '-maxrate', '2M', '-bufsize', '4M', - '-g', '60', '-keyint_min', '60', '-sc_threshold', '0', + // every HLS segment) is exactly 2.0s. + // + // This is a CONFIDENCE MONITOR, kept deliberately tiny: 360p / 20fps / + // ultrafast. The sidecar has no NVENC, so this is a CPU libx264 encode + // running ALONGSIDE CasparCG's mixer + its own STREAM consumer. At 720p30 + // the re-encode couldn't sustain real time, the UDP input overran, and the + // HLS output stalled (playlist froze → monitor black). 360p20 ultrafast is + // a fraction of the cost and keeps up comfortably. fps=20 forces CFR; + // -g 40 = 2.0s GOP at 20fps. + '-vf', 'fps=20,scale=-2:360,format=yuv420p', + '-c:v', 'libx264', '-preset', 'ultrafast', '-tune', 'zerolatency', + '-b:v', '600k', '-maxrate', '800k', '-bufsize', '1200k', + '-g', '40', '-keyint_min', '40', '-sc_threshold', '0', '-force_key_frames', 'expr:gte(t,n_forced*2)', '-f', 'hls', '-hls_time', '2',