From 022f469b7b444830ffdb5e557e58a336de38c73f Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Sat, 28 Feb 2026 10:38:37 -0700 Subject: [PATCH 1/2] another attempt to get the video to play correctly after programattically changing sources --- app/client/src/components/misc/VideoJSPlayer.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/client/src/components/misc/VideoJSPlayer.js b/app/client/src/components/misc/VideoJSPlayer.js index e915444..6b336f8 100644 --- a/app/client/src/components/misc/VideoJSPlayer.js +++ b/app/client/src/components/misc/VideoJSPlayer.js @@ -98,12 +98,21 @@ const VideoJSPlayer = ({ if (sources && currentSourceIndex + 1 < sources.length) { const currentTime = player.currentTime() || 0 currentSourceIndex += 1 + + // Clear any existing error state so the player can load the new source + player.error(null) + player.removeClass('vjs-error') + + // Hide the big play button and poster to avoid the "play overlay" flash + player.bigPlayButton.hide() + player.hasStarted(true) + const updatedSources = sources.map((s, i) => ({ ...s, selected: i === currentSourceIndex, })) player.src(updatedSources) - player.one('loadedmetadata', () => { + player.one('canplay', () => { if (currentTime > 0) { player.currentTime(currentTime) } From 27a73c704262e3bb06add2baf239611773606eb4 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Sat, 28 Feb 2026 11:07:52 -0700 Subject: [PATCH 2/2] add a buffer count to auto downgrade if constantly hitting the buffer window but not long enough to trigger the buffer stall window --- .../src/components/misc/VideoJSPlayer.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/client/src/components/misc/VideoJSPlayer.js b/app/client/src/components/misc/VideoJSPlayer.js index 6b336f8..8e346a1 100644 --- a/app/client/src/components/misc/VideoJSPlayer.js +++ b/app/client/src/components/misc/VideoJSPlayer.js @@ -15,6 +15,12 @@ const SEEK_TOLERANCE_SECONDS = 0.5 // How long to wait while buffering before switching to a lower quality source (in ms) const BUFFER_STALL_TIMEOUT_MS = 5000 +// Number of buffering events within the window that triggers a quality downgrade +const BUFFER_COUNT_THRESHOLD = 4 + +// Sliding window duration for counting buffering events (in ms) +const BUFFER_COUNT_WINDOW_MS = 30000 + const VideoJSPlayer = ({ sources, poster, @@ -93,6 +99,7 @@ const VideoJSPlayer = ({ // Switch to a lower quality source if stuck buffering let bufferStallTimer = null let currentSourceIndex = 0 + let bufferTimestamps = [] const switchToNextSource = () => { if (sources && currentSourceIndex + 1 < sources.length) { @@ -145,11 +152,25 @@ const VideoJSPlayer = ({ } }) - // Auto-downgrade quality when buffering stalls + // Auto-downgrade quality when buffering stalls or buffers too frequently player.on('waiting', () => { + // Track buffering frequency in a sliding window + const now = Date.now() + bufferTimestamps.push(now) + bufferTimestamps = bufferTimestamps.filter((t) => now - t < BUFFER_COUNT_WINDOW_MS) + + if (bufferTimestamps.length >= BUFFER_COUNT_THRESHOLD) { + bufferTimestamps = [] + clearStallTimer() + switchToNextSource() + return + } + + // Single long stall fallback clearStallTimer() bufferStallTimer = setTimeout(() => { if (player.paused() || player.readyState() < 3) { + bufferTimestamps = [] switchToNextSource() } }, BUFFER_STALL_TIMEOUT_MS)