From 7c651eb61fc0df2833ef48cb5d197a4d079ac08a Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:17:36 +0100 Subject: [PATCH] fix: cap ExoPlayer buffer size --- .../com/edde746/plezy/exoplayer/ExoPlayerCore.kt | 12 +++++++++++- .../com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt | 8 +++++--- lib/mpv/player/player_android.dart | 9 ++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt index 1b5eb9be..3609300a 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt @@ -36,6 +36,7 @@ import androidx.media3.common.Tracks import androidx.media3.common.VideoSize import androidx.media3.common.util.UnstableApi import androidx.media3.datasource.DefaultDataSource +import androidx.media3.exoplayer.DefaultLoadControl import androidx.media3.exoplayer.DefaultRenderersFactory import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.source.DefaultMediaSourceFactory @@ -202,7 +203,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { } } - fun initialize(): Boolean { + fun initialize(bufferSizeBytes: Int? = null): Boolean { if (isInitialized) { Log.d(TAG, "Already initialized") return true @@ -337,8 +338,17 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { val wrappedRenderersFactory = AssRenderersFactory(handler, renderersFactory) + val loadControl = DefaultLoadControl.Builder().apply { + if (bufferSizeBytes != null && bufferSizeBytes > 0) { + setTargetBufferBytes(bufferSizeBytes) + setPrioritizeTimeOverSizeThresholds(false) + Log.d(TAG, "Buffer byte limit set to ${bufferSizeBytes / 1024 / 1024}MB") + } + }.build() + exoPlayer = ExoPlayer.Builder(activity) .setTrackSelector(trackSelector!!) + .setLoadControl(loadControl) .setAudioAttributes(audioAttributes, false) // We handle audio focus manually .setMediaSourceFactory(mediaSourceFactory) .setRenderersFactory(wrappedRenderersFactory) 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 6720e204..7b7b3d65 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 @@ -96,7 +96,7 @@ class ExoPlayerPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { - "initialize" -> handleInitialize(result) + "initialize" -> handleInitialize(call, result) "dispose" -> handleDispose(result) "open" -> handleOpen(call, result) "play" -> handlePlay(result) @@ -125,7 +125,7 @@ class ExoPlayerPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, } } - private fun handleInitialize(result: MethodChannel.Result) { + private fun handleInitialize(call: MethodCall, result: MethodChannel.Result) { val currentActivity = activity if (currentActivity == null) { result.error("NO_ACTIVITY", "Activity not available", null) @@ -138,12 +138,14 @@ class ExoPlayerPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, return } + val bufferSizeBytes = call.argument("bufferSizeBytes") + currentActivity.runOnUiThread { try { playerCore = ExoPlayerCore(currentActivity).apply { delegate = this@ExoPlayerPlugin } - val success = playerCore?.initialize() ?: false + val success = playerCore?.initialize(bufferSizeBytes = bufferSizeBytes) ?: false // Start hidden playerCore?.setVisible(false) diff --git a/lib/mpv/player/player_android.dart b/lib/mpv/player/player_android.dart index ab0d76ed..f0788293 100644 --- a/lib/mpv/player/player_android.dart +++ b/lib/mpv/player/player_android.dart @@ -9,6 +9,8 @@ class PlayerAndroid extends PlayerBase { static const _methodChannel = MethodChannel('com.plezy/exo_player'); static const _eventChannel = EventChannel('com.plezy/exo_player/events'); + int? _bufferSizeBytes; + @override MethodChannel get methodChannel => _methodChannel; @@ -46,7 +48,9 @@ class PlayerAndroid extends PlayerBase { if (initialized) return; try { - final result = await methodChannel.invokeMethod('initialize'); + final result = await methodChannel.invokeMethod('initialize', { + 'bufferSizeBytes': _bufferSizeBytes, + }); initialized = result == true; if (!initialized) { throw Exception('Failed to initialize ExoPlayer'); @@ -181,6 +185,9 @@ class PlayerAndroid extends PlayerBase { case 'speed': await setRate(double.tryParse(value) ?? 1.0); break; + case 'demuxer-max-bytes': + _bufferSizeBytes = int.tryParse(value); + break; // Other properties are no-ops for ExoPlayer } }