From 9fb8df7255d8c2d0d455bf50dd4216d0de706328 Mon Sep 17 00:00:00 2001 From: Trevor Mears Date: Thu, 1 Jan 2026 11:52:47 -0800 Subject: [PATCH 1/2] Improve FFmpeg startup speed and stream resilience --- server/routes/remux.js | 12 ++++++++++-- server/routes/transcode.js | 7 +++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/server/routes/remux.js b/server/routes/remux.js index 637c1cd..a7ca193 100644 --- a/server/routes/remux.js +++ b/server/routes/remux.js @@ -26,10 +26,15 @@ router.get('/', (req, res) => { const args = [ '-hide_banner', '-loglevel', 'warning', - // Error resilience: discard corrupt packets, generate timestamps - '-fflags', '+genpts+discardcorrupt+igndts', + // Low-latency startup: reduce probe/analyze time for faster first bytes + '-probesize', '32768', + '-analyzeduration', '0', + // Error resilience: discard corrupt packets, generate timestamps, ignore DTS, no buffering + '-fflags', '+genpts+discardcorrupt+igndts+nobuffer', // Ignore errors in stream and continue '-err_detect', 'ignore_err', + // Limit max demux delay to prevent buffering issues with bad timestamps + '-max_delay', '5000000', // Reconnect settings for network drops '-reconnect', '1', '-reconnect_streamed', '1', @@ -40,6 +45,9 @@ router.get('/', (req, res) => { // Convert AAC from ADTS format (TS) to ASC format (MP4) // Required when remuxing MPEG-TS with AAC audio to MP4 '-bsf:a', 'aac_adtstoasc', + // Handle timestamp discontinuities at output + '-fps_mode', 'passthrough', + '-max_muxing_queue_size', '1024', // Fragmented MP4 for streaming (browser-compatible) '-f', 'mp4', '-movflags', 'frag_keyframe+empty_moov+default_base_moof', diff --git a/server/routes/transcode.js b/server/routes/transcode.js index 6e8eed4..c825eeb 100644 --- a/server/routes/transcode.js +++ b/server/routes/transcode.js @@ -25,8 +25,11 @@ router.get('/', (req, res) => { const args = [ '-hide_banner', '-loglevel', 'warning', - // Error resilience: discard corrupt packets, generate timestamps, ignore DTS - '-fflags', '+genpts+discardcorrupt+igndts', + // Low-latency startup: reduce probe/analyze time for faster first bytes + '-probesize', '32768', + '-analyzeduration', '0', + // Error resilience: discard corrupt packets, generate timestamps, ignore DTS, no buffering + '-fflags', '+genpts+discardcorrupt+igndts+nobuffer', // Ignore errors in stream and continue '-err_detect', 'ignore_err', // Limit max demux delay to prevent buffering issues with bad timestamps From fc2f20d921461f2c2e7b5141372be069244b1032 Mon Sep 17 00:00:00 2001 From: Trevor Mears Date: Thu, 1 Jan 2026 12:18:03 -0800 Subject: [PATCH 2/2] Fixed issue with safari/edge native HLS path mistakenly switching to proxy mode in some cases --- public/js/components/VideoPlayer.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/public/js/components/VideoPlayer.js b/public/js/components/VideoPlayer.js index 1fafab2..1f01e4e 100644 --- a/public/js/components/VideoPlayer.js +++ b/public/js/components/VideoPlayer.js @@ -176,7 +176,7 @@ class VideoPlayer { btnMute.addEventListener('click', () => { this.video.muted = !this.video.muted; btnMute.classList.toggle('muted', this.video.muted); - + // Update icon const icon = btnMute.querySelector('.icon'); if (this.video.muted) { @@ -231,13 +231,13 @@ class VideoPlayer { this.video.addEventListener('click', showControls); this.video.addEventListener('touchstart', showControls); - + // Keep controls visible when video is paused this.video.addEventListener('pause', () => { controls.classList.add('show'); clearTimeout(controlsTimeout); }); - + this.video.addEventListener('play', () => { hideControls(); }); @@ -469,7 +469,9 @@ class VideoPlayer { // Transcoded streams are fragmented MP4 - play directly with