fix(android): wire ExoPlayer passthrough control

This commit is contained in:
edde746
2026-06-15 13:31:42 +02:00
parent e069d30555
commit 8198ea9522
2 changed files with 46 additions and 1 deletions
@@ -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<Int>("bufferSizeBytes")
val tunnelingEnabled = call.argument<Boolean>("tunnelingEnabled") ?: true
val dvConversionMode = call.argument<String>("dvConversionMode") ?: "auto"
val audioPassthroughEnabled = call.argument<Boolean>("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<Boolean>("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<String>("name")
val value = call.argument<String>("value")
@@ -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<void> 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<String?> getProperty(String name) async {
if (disposed) return null;