From f6dea03c055c2dcada00225849eff5e3b906a5ae Mon Sep 17 00:00:00 2001 From: tapframe Date: Sun, 28 Dec 2025 02:21:01 +0530 Subject: [PATCH] users can now toggle between - auto/mpv exclusively --- src/components/player/AndroidVideoPlayer.tsx | 11 +++- src/hooks/useSettings.ts | 2 + src/screens/PlayerSettingsScreen.tsx | 61 +++++++++++++++++++- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index f5fb9a73..39f1f59b 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -94,9 +94,18 @@ const AndroidVideoPlayer: React.FC = () => { const [isTransitioningStream, setIsTransitioningStream] = useState(false); // Dual video engine state: ExoPlayer primary, MPV fallback - const [useExoPlayer, setUseExoPlayer] = useState(true); + // If videoPlayerEngine is 'mpv', always use MPV; otherwise use auto behavior + const [useExoPlayer, setUseExoPlayer] = useState(settings.videoPlayerEngine !== 'mpv'); const hasExoPlayerFailed = useRef(false); + // Sync useExoPlayer with settings when videoPlayerEngine changes + useEffect(() => { + if (settings.videoPlayerEngine === 'mpv') { + setUseExoPlayer(false); + } + // Note: We don't reset to true when 'auto' because ExoPlayer might have failed + }, [settings.videoPlayerEngine]); + // Subtitle addon state const [availableSubtitles, setAvailableSubtitles] = useState([]); const [isLoadingSubtitleList, setIsLoadingSubtitleList] = useState(false); diff --git a/src/hooks/useSettings.ts b/src/hooks/useSettings.ts index c89257f6..e76651f2 100644 --- a/src/hooks/useSettings.ts +++ b/src/hooks/useSettings.ts @@ -89,6 +89,7 @@ export interface AppSettings { enableStreamsBackdrop: boolean; // Enable blurred backdrop background on StreamsScreen mobile useExternalPlayerForDownloads: boolean; // Enable/disable external player for downloaded content // Android MPV player settings + videoPlayerEngine: 'auto' | 'mpv'; // Video player engine: auto (ExoPlayer primary, MPV fallback) or mpv (MPV only) decoderMode: 'auto' | 'sw' | 'hw' | 'hw+'; // Decoder mode: auto (auto-copy), sw (software), hw (mediacodec-copy), hw+ (mediacodec) gpuMode: 'gpu' | 'gpu-next'; // GPU rendering mode: gpu (standard) or gpu-next (advanced HDR/color) } @@ -153,6 +154,7 @@ export const DEFAULT_SETTINGS: AppSettings = { streamCacheTTL: 60 * 60 * 1000, // Default: 1 hour in milliseconds enableStreamsBackdrop: true, // Enable by default (new behavior) // Android MPV player settings + videoPlayerEngine: 'auto', // Default to auto (ExoPlayer primary, MPV fallback) decoderMode: 'auto', // Default to auto (best compatibility and performance) gpuMode: 'gpu', // Default to gpu (gpu-next for advanced HDR) }; diff --git a/src/screens/PlayerSettingsScreen.tsx b/src/screens/PlayerSettingsScreen.tsx index 930c424d..af529c3b 100644 --- a/src/screens/PlayerSettingsScreen.tsx +++ b/src/screens/PlayerSettingsScreen.tsx @@ -335,9 +335,68 @@ const PlayerSettingsScreen: React.FC = () => { - {/* Decoder Mode for Android Internal Player */} + {/* Video Player Engine for Android */} {Platform.OS === 'android' && !settings.useExternalPlayer && ( <> + + + + + + + + Video Player Engine + + + Auto uses ExoPlayer with MPV fallback. MPV uses MPV exclusively. + + + + + {([ + { id: 'auto', label: 'Auto', desc: 'ExoPlayer + MPV fallback' }, + { id: 'mpv', label: 'MPV', desc: 'MPV only' }, + ] as const).map((option) => ( + updateSetting('videoPlayerEngine', option.id)} + style={[ + styles.optionButton, + styles.optionButtonWide, + settings.videoPlayerEngine === option.id && { backgroundColor: currentTheme.colors.primary }, + ]} + > + + {option.label} + + + ))} + + + + {/* Decoder Mode for Android Internal Player */}