diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index aac2125ca887..977fc6151604 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.12.3 + +* Enables ExoPlayer decoder fallback so that playback continues on a lower-priority decoder when the preferred decoder fails to initialize. + ## 2.12.2 * Fixes a [bug](https://github.com/flutter/flutter/issues/132934) where videos with a pixel aspect ratio other than 1.0 (anamorphic content) reported their coded size instead of their display size, causing them to be rendered stretched. diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java index a4b5a93890a4..70527456461a 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/platformview/PlatformViewVideoPlayer.java @@ -11,6 +11,7 @@ import androidx.media3.common.MediaItem; import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.DefaultLoadControl; +import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; import io.flutter.plugins.videoplayer.ExoPlayerEventListener; import io.flutter.plugins.videoplayer.VideoAsset; @@ -57,7 +58,9 @@ public static PlatformViewVideoPlayer create( asset.getMediaItem(), options, () -> { - ExoPlayer.Builder builder = new ExoPlayer.Builder(context); + ExoPlayer.Builder builder = + new ExoPlayer.Builder( + context, new DefaultRenderersFactory(context).setEnableDecoderFallback(true)); if (options.backBufferDurationMs != null) { if (options.backBufferDurationMs < 0) { throw new IllegalArgumentException("backBufferDurationMs must be at least 0"); diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java index c0a2d4189176..e0f2568d2568 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/texture/TextureVideoPlayer.java @@ -13,6 +13,7 @@ import androidx.media3.common.MediaItem; import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.DefaultLoadControl; +import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; import io.flutter.plugins.videoplayer.ExoPlayerEventListener; import io.flutter.plugins.videoplayer.VideoAsset; @@ -57,7 +58,9 @@ public static TextureVideoPlayer create( asset.getMediaItem(), options, () -> { - ExoPlayer.Builder builder = new ExoPlayer.Builder(context); + ExoPlayer.Builder builder = + new ExoPlayer.Builder( + context, new DefaultRenderersFactory(context).setEnableDecoderFallback(true)); if (options.backBufferDurationMs != null) { if (options.backBufferDurationMs < 0) { throw new IllegalArgumentException("backBufferDurationMs must be at least 0"); diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java index befb22778650..1f21595438f3 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/TextureVideoPlayerTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.*; import android.view.Surface; @@ -14,6 +15,7 @@ import androidx.media3.common.PlaybackParameters; import androidx.media3.common.Player; import androidx.media3.common.VideoSize; +import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; import io.flutter.plugins.videoplayer.texture.TextureVideoPlayer; import io.flutter.view.TextureRegistry; @@ -227,4 +229,34 @@ public void create_withBackBufferDuration_setsLoadControl() { player.dispose(); } } + + @Test + public void create_enablesDecoderFallback() { + android.content.Context mockContext = mock(android.content.Context.class); + VideoPlayerOptions options = new VideoPlayerOptions(); + + try (MockedConstruction mockedFactory = + mockConstruction( + DefaultRenderersFactory.class, + (mock, context) -> + when(mock.setEnableDecoderFallback(anyBoolean())).thenReturn(mock)); + MockedConstruction mockedBuilder = + mockConstruction( + ExoPlayer.Builder.class, + (mock, context) -> { + when(mock.setLoadControl(any())).thenReturn(mock); + when(mock.setTrackSelector(any())).thenReturn(mock); + when(mock.setMediaSourceFactory(any())).thenReturn(mock); + when(mock.build()).thenReturn(mockExoPlayer); + })) { + + TextureVideoPlayer player = + TextureVideoPlayer.create(mockContext, mockEvents, mockProducer, fakeVideoAsset, options); + + assertEquals(1, mockedBuilder.constructed().size()); + assertEquals(1, mockedFactory.constructed().size()); + verify(mockedFactory.constructed().get(0)).setEnableDecoderFallback(true); + player.dispose(); + } + } } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index fb3fca6317ac..a2b7f4b9f3db 100644 --- a/packages/video_player/video_player_android/pubspec.yaml +++ b/packages/video_player/video_player_android/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_android description: Android implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.12.2 +version: 2.12.3 environment: sdk: ^3.12.0