feat(player): default Android playback to the mpv backend

With video on the MediaCodec plane, real bitstream passthrough, media3
demuxing, and the GL fallback ladder in place, mpv measures at parity
or better than ExoPlayer on every device class tested (Tegra, Mali,
Amlogic armv7, Adreno; API 28-36; phone, TV, and foldable), including
the two historical Android mpv failure modes: low-end TV playback and
Hi10P.

Installs that never chose a backend move to mpv; a stored ExoPlayer
choice is preserved, and the Player Backend toggle stays user-visible
as the escape hatch. The automatic ExoPlayer-to-mpv runtime fallback
is unchanged.
This commit is contained in:
edde746
2026-08-26 18:59:28 +02:00
parent 8f893e7a67
commit 3c6d398598
2 changed files with 10 additions and 8 deletions
+7 -7
View File
@@ -379,13 +379,13 @@ abstract class Player {
///
/// Returns a platform-specific implementation:
/// - macOS/iOS: [PlayerNative] using MPVKit/libmpv with Metal rendering
/// - Android: [PlayerAndroid] using ExoPlayer (default) or [PlayerNative] using MPV (fallback)
/// - Android: [PlayerNative] using MPV (default) or [PlayerAndroid] using ExoPlayer (opt-in)
/// - Windows: [PlayerWindows] using libmpv with native window embedding
/// - Linux: [PlayerLinux] using libmpv on a native Wayland video plane
///
/// On Android, pass [useExoPlayer] to override the default:
/// - true: Use ExoPlayer (default, better hardware support)
/// - false: Use MPV (more features, ASS subtitle rendering)
/// - false: Use MPV (default, more features, ASS subtitle rendering)
/// - true: Use ExoPlayer (the escape hatch for devices MPV mishandles)
///
/// [hardwareDecoding] is the session's hardware-decoding setting. The
/// Android mpv backend uses it to pick its initial video output — the fork's
@@ -394,13 +394,13 @@ abstract class Player {
/// MpvPlayerCore.initialVideoOutput; #2010).
factory Player({bool? useExoPlayer, bool hardwareDecoding = true}) {
if (Platform.isAndroid) {
// Default to ExoPlayer on Android, with MPV as fallback
// Default to MPV on Android, with ExoPlayer as the opt-in alternative.
// The caller should pass useExoPlayer based on SettingsService.useExoPlayer.
final useExo = useExoPlayer ?? true;
final useExo = useExoPlayer ?? false;
if (useExo) {
return PlayerAndroid(); // ExoPlayer (default)
return PlayerAndroid(); // ExoPlayer (opt-in)
}
return PlayerNative(hardwareDecoding: hardwareDecoding); // MPV fallback
return PlayerNative(hardwareDecoding: hardwareDecoding); // MPV (default)
}
if (Platform.isMacOS || Platform.isIOS) {
return PlayerNative();
+3 -1
View File
@@ -510,7 +510,9 @@ class SettingsService extends BaseSharedPreferencesService {
defaultValue: SpecialsOrdering.respectServer,
);
static const useExoPlayer = BoolPref('use_exoplayer', defaultValue: true);
/// mpv is the default Android backend; ExoPlayer remains selectable as the
/// escape hatch while it still ships.
static const useExoPlayer = BoolPref('use_exoplayer');
static const startupSection = EnumPref<NavigationTabId>(
'startup_section',
values: NavigationTabId.values,