From 57f1310bd42cbe73850dc25605ad028069bb0c38 Mon Sep 17 00:00:00 2001 From: XZH Date: Fri, 28 Aug 2026 16:22:56 -0700 Subject: [PATCH] fix(player): stabilize progressive captions --- assets/js/player.js | 21 ++++++++++++++------- src/invidious/views/components/player.ecr | 10 +--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/assets/js/player.js b/assets/js/player.js index b5acbec2d..d5432a652 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -658,7 +658,7 @@ function processCueElement(cueEl, currentTime) { } function applyProgressiveCaptions(currentTime) { - const cueElements = document.querySelectorAll('.vjs-text-track-cue'); + const cueElements = player.el().querySelectorAll('.vjs-text-track-cue'); if (!cueElements || cueElements.length === 0) return; for (let i = 0; i < cueElements.length; i++) { @@ -669,6 +669,7 @@ function applyProgressiveCaptions(currentTime) { (function initProgressiveCaptionsLoop() { let rafId = null; let rvfcId = null; + let rvfcVideoEl = null; let isLoopRunning = false; function updateCaptionFrame() { @@ -693,6 +694,7 @@ function applyProgressiveCaptions(currentTime) { function scheduleNextFrame(videoEl) { isLoopRunning = true; if (videoEl && typeof videoEl.requestVideoFrameCallback === 'function') { + rvfcVideoEl = videoEl; rvfcId = videoEl.requestVideoFrameCallback(function () { updateCaptionFrame(); }); @@ -712,15 +714,14 @@ function applyProgressiveCaptions(currentTime) { function stopCaptionLoop() { isLoopRunning = false; - const tech = player.tech(true); - const videoEl = tech && tech.el(); - if (videoEl && typeof videoEl.cancelVideoFrameCallback === 'function' && rvfcId !== null) { - videoEl.cancelVideoFrameCallback(rvfcId); + if (rvfcVideoEl && typeof rvfcVideoEl.cancelVideoFrameCallback === 'function' && rvfcId !== null) { + rvfcVideoEl.cancelVideoFrameCallback(rvfcId); } if (rafId !== null) { window.cancelAnimationFrame(rafId); } rvfcId = null; + rvfcVideoEl = null; rafId = null; } @@ -762,6 +763,11 @@ function applyProgressiveCaptions(currentTime) { // For real-time updates to captions (if currently showing) function update_captions() { applyProgressiveCaptions(player.currentTime()); + const textTrackDisplay = player.getChild('textTrackDisplay'); + if (textTrackDisplay && typeof textTrackDisplay.updateDisplay === 'function') { + textTrackDisplay.updateDisplay(); + applyProgressiveCaptions(player.currentTime()); + } } function toggle_fullscreen() { @@ -952,6 +958,7 @@ if (player.share) player.share(shareOptions); (function initCaptionLoading() { const tracks = player.textTracks(); let preferredTrackSelected = false; + let captionTrackShowing = false; let prefetchStarted = false; function prefetchCaptionSource() { @@ -973,6 +980,7 @@ if (player.share) player.share(shareOptions); if (!firstCaptionTrack) firstCaptionTrack = track; if (track.mode === 'showing') { + captionTrackShowing = true; preferredTrackSelected = preferredTrackSelected || player_data.preferred_caption_found; } @@ -981,8 +989,7 @@ if (player.share) player.share(shareOptions); if (player_data.preferred_caption_found && !preferredTrackSelected && firstCaptionTrack) { preferredTrackSelected = true; firstCaptionTrack.mode = 'showing'; - } else if (!player_data.preferred_caption_found && !prefetchStarted && - caption_track_sources.length > 0) { + } else if (!captionTrackShowing && !prefetchStarted && caption_track_sources.length > 0) { prefetchStarted = true; prefetchCaptionSource(); } diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr index 2046d0d2c..9e2c81105 100644 --- a/src/invidious/views/components/player.ecr +++ b/src/invidious/views/components/player.ecr @@ -68,15 +68,7 @@ <% end %> <% end %> - <% preferred_captions.each do |caption| - api_captions_url = "/api/v1/captions/" - api_captions_url = invidious_companion.public_url.to_s + api_captions_url if (invidious_companion) - api_captions_check_id = "&check=#{invidious_companion_check_id}" - %> - - <% end %> - - <% captions.each do |caption| + <% (preferred_captions + captions).each do |caption| api_captions_url = "/api/v1/captions/" api_captions_url = invidious_companion.public_url.to_s + api_captions_url if (invidious_companion) api_captions_check_id = "&check=#{invidious_companion_check_id}"