users can now toggle between - auto/mpv exclusively

This commit is contained in:
tapframe 2025-12-28 02:21:01 +05:30
parent 6e2ddd2dda
commit f6dea03c05
3 changed files with 72 additions and 2 deletions

View file

@ -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<WyzieSubtitle[]>([]);
const [isLoadingSubtitleList, setIsLoadingSubtitleList] = useState(false);

View file

@ -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)
};

View file

@ -335,9 +335,68 @@ const PlayerSettingsScreen: React.FC = () => {
</View>
</View>
{/* Decoder Mode for Android Internal Player */}
{/* Video Player Engine for Android */}
{Platform.OS === 'android' && !settings.useExternalPlayer && (
<>
<View style={[styles.settingItem, styles.settingItemBorder, { borderTopColor: 'rgba(255,255,255,0.08)', borderTopWidth: 1 }]}>
<View style={styles.settingContent}>
<View style={[
styles.settingIconContainer,
{ backgroundColor: 'rgba(255,255,255,0.1)' }
]}>
<MaterialIcons
name="play-circle-filled"
size={20}
color={currentTheme.colors.primary}
/>
</View>
<View style={styles.settingText}>
<Text
style={[
styles.settingTitle,
{ color: currentTheme.colors.text },
]}
>
Video Player Engine
</Text>
<Text
style={[
styles.settingDescription,
{ color: currentTheme.colors.textMuted },
]}
>
Auto uses ExoPlayer with MPV fallback. MPV uses MPV exclusively.
</Text>
</View>
</View>
<View style={styles.optionButtonsRow}>
{([
{ id: 'auto', label: 'Auto', desc: 'ExoPlayer + MPV fallback' },
{ id: 'mpv', label: 'MPV', desc: 'MPV only' },
] as const).map((option) => (
<TouchableOpacity
key={option.id}
onPress={() => updateSetting('videoPlayerEngine', option.id)}
style={[
styles.optionButton,
styles.optionButtonWide,
settings.videoPlayerEngine === option.id && { backgroundColor: currentTheme.colors.primary },
]}
>
<Text
style={[
styles.optionButtonText,
{ color: settings.videoPlayerEngine === option.id ? '#fff' : currentTheme.colors.text },
]}
>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
{/* Decoder Mode for Android Internal Player */}
<View style={[styles.settingItem, styles.settingItemBorder, { borderTopColor: 'rgba(255,255,255,0.08)', borderTopWidth: 1 }]}>
<View style={styles.settingContent}>
<View style={[