From 8198ea9522df1962d89366c9a750eb82003fee36 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Mon, 15 Jun 2026 13:29:11 +0200 Subject: [PATCH] fix(android): wire ExoPlayer passthrough control --- .../plezy/exoplayer/ExoPlayerPlugin.kt | 24 ++++++++++++++++++- lib/mpv/player/platform/player_android.dart | 23 ++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt index 92da4487..cb947b8e 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt @@ -169,6 +169,7 @@ class ExoPlayerPlugin : "setVideoZoom" -> handleSetVideoZoom(call, result) "setDvConversionMode" -> handleSetDvConversionMode(call, result) "setAudioNormalization" -> handleSetAudioNormalization(call, result) + "setAudioPassthrough" -> handleSetAudioPassthrough(call, result) "observeProperty" -> handleObserveProperty(call, result) "setMpvProperty" -> handleSetMpvProperty(call, result) "setLogLevel" -> { @@ -201,6 +202,7 @@ class ExoPlayerPlugin : val bufferSizeBytes = call.argument("bufferSizeBytes") val tunnelingEnabled = call.argument("tunnelingEnabled") ?: true val dvConversionMode = call.argument("dvConversionMode") ?: "auto" + val audioPassthroughEnabled = call.argument("audioPassthroughEnabled") ?: false configuredBufferSizeBytes = bufferSizeBytes currentActivity.runOnUiThread { @@ -224,7 +226,8 @@ class ExoPlayerPlugin : } val success = playerCore?.initialize( bufferSizeBytes = bufferSizeBytes, - tunnelingEnabled = tunnelingEnabled + tunnelingEnabled = tunnelingEnabled, + audioPassthroughEnabled = audioPassthroughEnabled ) ?: false if (success && playerCore?.setDebugDvConversionMode(dvConversionMode) != true) { Log.w(TAG, "Invalid DV conversion mode during initialize: $dvConversionMode") @@ -647,6 +650,25 @@ class ExoPlayerPlugin : } ?: result.error("NO_ACTIVITY", "Activity not available", null) } + private fun handleSetAudioPassthrough(call: MethodCall, result: MethodChannel.Result) { + val enabled = call.argument("enabled") + if (enabled == null) { + result.error("INVALID_ARGS", "Missing 'enabled'", null) + return + } + val audioSpdif = if (enabled) "ac3,eac3,dts,dts-hd,truehd" else "" + pendingMpvProperties["audio-spdif"] = audioSpdif + if (usingMpvFallback) { + mpvCore?.setProperty("audio-spdif", audioSpdif) + result.success(true) + return + } + activity?.runOnUiThread { + playerCore?.setAudioPassthrough(enabled) + result.success(true) + } ?: result.error("NO_ACTIVITY", "Activity not available", null) + } + private fun handleSetMpvProperty(call: MethodCall, result: MethodChannel.Result) { val name = call.argument("name") val value = call.argument("value") diff --git a/lib/mpv/player/platform/player_android.dart b/lib/mpv/player/platform/player_android.dart index 949132cb..edcf4b59 100644 --- a/lib/mpv/player/platform/player_android.dart +++ b/lib/mpv/player/platform/player_android.dart @@ -13,6 +13,9 @@ class PlayerAndroid extends PlayerBase { bool _tunnelingEnabled = true; String _dvConversionMode = 'auto'; bool _audioNormalizationEnabled = false; + bool _audioPassthroughEnabled = false; + + static const String _passthroughCodecs = 'ac3,eac3,dts,dts-hd,truehd'; /// The native plugin switched from ExoPlayer to its mpv fallback for this /// session. Sticky for the instance lifetime, mirroring the native flag @@ -55,6 +58,9 @@ class PlayerAndroid extends PlayerBase { @override bool get providesNativeStats => true; + @override + bool get audioPassthroughActive => _audioPassthroughEnabled; + @override void handlePlayerEvent(String name, Map? data) { if (name == 'backend-switched') { @@ -88,6 +94,7 @@ class PlayerAndroid extends PlayerBase { 'bufferSizeBytes': _bufferSizeBytes, 'tunnelingEnabled': _tunnelingEnabled, 'dvConversionMode': _dvConversionMode, + 'audioPassthroughEnabled': _audioPassthroughEnabled, }); if (result != true) { throw Exception('Failed to initialize ExoPlayer'); @@ -280,6 +287,22 @@ class PlayerAndroid extends PlayerBase { await super.setAudioNormalization(enabled); } + @override + Future setAudioPassthrough(bool enabled) async { + if (disposed) return; + _audioPassthroughEnabled = enabled; + final initFuture = _initFuture; + if (initialized) { + await invoke('setAudioPassthrough', {'enabled': enabled}); + } else if (initFuture != null) { + await initFuture; + if (!disposed && initialized && _audioPassthroughEnabled == enabled) { + await invoke('setAudioPassthrough', {'enabled': enabled}); + } + } + await setProperty('audio-spdif', enabled ? _passthroughCodecs : ''); + } + @override Future getProperty(String name) async { if (disposed) return null;