Improve subtitle restoration for mobile devices

Increases subtitle restoration attempts and uses exponential backoff to better support mobile devices where text tracks may load slowly. Adds logic to only warn when subtitle tracks are present but the desired language is not found, and improves error handling for native text track access.
This commit is contained in:
Yiannis Christodoulou 2025-10-18 22:00:20 +03:00
parent b2729d16aa
commit 1887c262d5

View File

@ -340,9 +340,28 @@ class UserPreferences {
// Set flag to prevent auto-save during restoration // Set flag to prevent auto-save during restoration
this.isRestoringSubtitles = true; this.isRestoringSubtitles = true;
// Multiple attempts with increasing delays to ensure text tracks are loaded // Multiple attempts with increasing delays to ensure text tracks are loaded
// Mobile devices need more time and attempts
const maxAttempts = 10; // Increased from 5 for mobile compatibility
const attemptToApplySubtitles = (attempt = 1) => { const attemptToApplySubtitles = (attempt = 1) => {
const textTracks = player.textTracks(); const textTracks = player.textTracks();
// Check if we have any subtitle tracks loaded yet
let hasSubtitleTracks = false;
for (let i = 0; i < textTracks.length; i++) {
if (textTracks[i].kind === 'subtitles') {
hasSubtitleTracks = true;
break;
}
}
// If no subtitle tracks found yet and we have attempts left, retry with longer delay
if (!hasSubtitleTracks && attempt < maxAttempts) {
// Use exponential backoff: 100ms, 200ms, 400ms, 800ms, etc.
const delay = Math.min(100 * Math.pow(1.5, attempt - 1), 1000);
setTimeout(() => attemptToApplySubtitles(attempt + 1), delay);
return;
}
// First, disable all subtitle tracks // First, disable all subtitle tracks
for (let i = 0; i < textTracks.length; i++) { for (let i = 0; i < textTracks.length; i++) {
const track = textTracks[i]; const track = textTracks[i];
@ -401,13 +420,17 @@ class UserPreferences {
// Clear the restoration flag after a longer delay to ensure all events have settled // Clear the restoration flag after a longer delay to ensure all events have settled
setTimeout(() => { setTimeout(() => {
this.isRestoringSubtitles = false; this.isRestoringSubtitles = false;
}, 600); // Increased to 3 seconds }, 600);
// If not found and we haven't tried too many times, try again // If not found and we haven't tried too many times, try again with longer delay
if (!found && attempt < 5) { if (!found && attempt < maxAttempts) {
setTimeout(() => attemptToApplySubtitles(attempt + 1), attempt * 50); const delay = Math.min(100 * Math.pow(1.5, attempt - 1), 1000);
setTimeout(() => attemptToApplySubtitles(attempt + 1), delay);
} else if (!found) { } else if (!found) {
console.warn('Could not find subtitle track for language:', savedLanguage); // Only log warning if we had subtitle tracks but couldn't match the language
if (hasSubtitleTracks) {
console.warn('Could not find subtitle track for language:', savedLanguage);
}
// Clear flag even if not found // Clear flag even if not found
this.isRestoringSubtitles = false; this.isRestoringSubtitles = false;
} }
@ -428,7 +451,9 @@ class UserPreferences {
ttList.addEventListener('addtrack', onAddTrack, { once: true }); ttList.addEventListener('addtrack', onAddTrack, { once: true });
ttList.addEventListener('change', onChange, { once: true }); ttList.addEventListener('change', onChange, { once: true });
} }
} catch (e) {} } catch {
// Silently ignore errors accessing native text track list
}
} else { } else {
// Ensure subtitles are off on load when not enabled // Ensure subtitles are off on load when not enabled
try { try {