diff --git a/src/screens/settings/PlaybackSettingsScreen.tsx b/src/screens/settings/PlaybackSettingsScreen.tsx index 88743597..a0327b54 100644 --- a/src/screens/settings/PlaybackSettingsScreen.tsx +++ b/src/screens/settings/PlaybackSettingsScreen.tsx @@ -70,6 +70,10 @@ const SUBTITLE_SOURCE_OPTIONS = [ { value: 'any', label: 'Any Available', description: 'Use first available subtitle track' }, ]; +/** + * Quality options for the "Auto-play First Stream" feature. + * These are used in the bottom sheet selection to allow users to target specific resolutions. + */ const AUTOPLAY_QUALITY_OPTIONS = [ { id: '4320p', label: '8K' }, { id: '4K', label: '4K' }, diff --git a/src/screens/streams/useStreamsScreen.ts b/src/screens/streams/useStreamsScreen.ts index 0e88faa0..104ebd7d 100644 --- a/src/screens/streams/useStreamsScreen.ts +++ b/src/screens/streams/useStreamsScreen.ts @@ -252,6 +252,8 @@ export const useStreamsScreen = () => { const preferredLanguage = settings.autoplayPreferredLanguage; // 1. Try to find streams matching preferred language + // Uses a robust set of variations (e.g. 'spa' for Spanish) to match against + // various stream metadata fields (lang, title, description). let languageMatchedStreams = allStreams; if (preferredLanguage && preferredLanguage !== 'Any') { languageMatchedStreams = allStreams.filter(item => { @@ -272,7 +274,8 @@ export const useStreamsScreen = () => { }); } - // 2. If no language match (and language wasn't 'Any'), just play the "first" stream + // 2. Fallback: If no language match (and language wasn't 'Any'), just play the "first" prioritized stream. + // Priority is determined by provider order then stream's original position. if (languageMatchedStreams.length === 0 && allStreams.length > 0) { // Sort by provider priority and original index to find the "first" one const sortedByPriority = [...allStreams].sort((a, b) => { @@ -285,9 +288,9 @@ export const useStreamsScreen = () => { if (languageMatchedStreams.length === 0) return null; - // 3. Among language-matched streams, find the one closest to target quality - // Sort primarily by how close the stream quality is to the preferred quality - // If quality is identical, sort by provider priority and then addon's internal order + // 3. Among language-matched streams, find the one closest to target quality. + // Sort primarily by how close the stream quality is to the preferred quality. + // If quality is identical, sort by provider priority and then addon's internal order. languageMatchedStreams.sort((a, b) => { // Calculate absolute difference from target quality // Note: 0 quality (unknown/auto) is treated as being far from any specific target diff --git a/src/screens/streams/utils.ts b/src/screens/streams/utils.ts index b3836339..de1ccb70 100644 --- a/src/screens/streams/utils.ts +++ b/src/screens/streams/utils.ts @@ -89,27 +89,36 @@ export const filterStreamsByLanguage = ( /** * Extract numeric quality from stream title + * Maps common quality labels (4K, 8K) to their vertical resolution (2160p, 4320p) + * and extracts numeric values from patterns like "1080p". */ export const getQualityNumeric = (title: string | undefined): number => { if (!title) return 0; // Check for 4K first (treat as 2160p) - if (/\b4k\b/i.test(title)) { + if (/\b(4k|uhd)\b/i.test(title)) { return 2160; } + + // Check for 8K (treat as 4320p) + if (/\b8k\b/i.test(title)) { + return 4320; + } + // General pattern for numbers followed by 'p' (e.g., 1080p, 3660p) const matchWithP = title.match(/(\d+)p/i); if (matchWithP) return parseInt(matchWithP[1], 10); - const qualityPatterns = [/\b(240|360|480|720|1080|1440|2160|4320|8000)\b/i]; - - for (const pattern of qualityPatterns) { + // Standalone common resolutions if 'p' suffix is missing (e.g., "UHD 2160") + const commonResolutions = [/\b(140|240|360|480|720|1080|1440|2160|3660|4320|8000)\b/]; + for (const pattern of commonResolutions) { const match = title.match(pattern); if (match) { const quality = parseInt(match[1], 10); - if (quality >= 240 && quality <= 8000) return quality; + if (quality >= 140 && quality <= 8000) return quality; } } + return 0; };