From df58d1b3d5e522b9216cd9edb41e9ba489864686 Mon Sep 17 00:00:00 2001 From: Jakub Walusiak Date: Thu, 11 Jan 2024 17:43:23 +0100 Subject: [PATCH 1/2] [video_player_android] Handle BehindLiveWindowException --- .../video_player_android/CHANGELOG.md | 5 +++ .../plugins/videoplayer/VideoPlayer.java | 6 +++- .../plugins/videoplayer/VideoPlayerTest.java | 32 +++++++++++++++++-- .../example/lib/mini_controller.dart | 2 ++ .../video_player_android/pubspec.yaml | 2 +- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index 42d577e3fd3..172d8a8105e 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.3.12 + +* Adds error handling for `BehindLiveWindowException` +* Fix missing switch case in example + ## 2.3.11 * Updates links for the merge of flutter/plugins into flutter/packages. diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java index e130c995aa2..cde6290f00a 100644 --- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java +++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java @@ -228,7 +228,11 @@ public void onPlaybackStateChanged(final int playbackState) { @Override public void onPlayerError(final PlaybackException error) { setBuffering(false); - if (eventSink != null) { + if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { + // See https://exoplayer.dev/live-streaming.html#behindlivewindowexception-and-error_code_behind_live_window + exoPlayer.seekToDefaultPosition(); + exoPlayer.prepare(); + } else if (eventSink != null) { eventSink.error("VideoError", "Video player had error " + error, null); } } diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java index 194f7905b63..c49138b0fbe 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java @@ -5,15 +5,18 @@ package io.flutter.plugins.videoplayer; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.PlaybackException; +import com.google.android.exoplayer2.Player; import io.flutter.plugin.common.EventChannel; import io.flutter.view.TextureRegistry; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -154,4 +157,27 @@ public void sendInitializedSendsExpectedEvent_180RotationDegrees() { assertEquals(event.get("height"), 200); assertEquals(event.get("rotationCorrection"), 180); } + + @Test + public void behindLiveWindowErrorResets() { + List listeners = new LinkedList<>(); + doAnswer(invocation -> listeners.add(invocation.getArgument(0))) + .when(fakeExoPlayer) + .addListener(any()); + + VideoPlayer unused = + new VideoPlayer( + fakeExoPlayer, + fakeEventChannel, + fakeSurfaceTextureEntry, + fakeVideoPlayerOptions, + fakeEventSink); + + PlaybackException exception = + new PlaybackException(null, null, PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW); + listeners.forEach(listener -> listener.onPlayerError(exception)); + + verify(fakeExoPlayer).seekToDefaultPosition(); + verify(fakeExoPlayer).prepare(); + } } diff --git a/packages/video_player/video_player_android/example/lib/mini_controller.dart b/packages/video_player/video_player_android/example/lib/mini_controller.dart index fb79a77fb2c..75a832a23e6 100644 --- a/packages/video_player/video_player_android/example/lib/mini_controller.dart +++ b/packages/video_player/video_player_android/example/lib/mini_controller.dart @@ -245,6 +245,8 @@ class MiniController extends ValueNotifier { break; case VideoEventType.unknown: break; + case VideoEventType.isPlayingStateUpdate: + break; } } diff --git a/packages/video_player/video_player_android/pubspec.yaml b/packages/video_player/video_player_android/pubspec.yaml index 9d9fc02e2e9..7bf68270613 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.3.11 +version: 2.3.12 environment: sdk: ">=2.14.0 <3.0.0" From 6ca509c588bf73bfaf7ae338a19a82af520b37dc Mon Sep 17 00:00:00 2001 From: Jakub Walusiak Date: Thu, 1 Feb 2024 16:50:11 +0100 Subject: [PATCH 2/2] Nits in changelog and tests --- packages/video_player/video_player_android/CHANGELOG.md | 2 +- .../java/io/flutter/plugins/videoplayer/VideoPlayerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player_android/CHANGELOG.md b/packages/video_player/video_player_android/CHANGELOG.md index fb7cd98261c..1606316b554 100644 --- a/packages/video_player/video_player_android/CHANGELOG.md +++ b/packages/video_player/video_player_android/CHANGELOG.md @@ -1,7 +1,7 @@ ## 2.4.12 * Updates compileSdk version to 34. -* Adds error handling for `BehindLiveWindowException` +* Adds error handling for `BehindLiveWindowException`, which may occur upon live-video playback failure. ## 2.4.11 diff --git a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java index f024914b3f4..85c1715dd6c 100644 --- a/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java +++ b/packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java @@ -283,7 +283,7 @@ public void onIsPlayingChangedSendsExpectedEvent() { } @Test - public void behindLiveWindowErrorResets() { + public void behindLiveWindowErrorResetsPlayerToDefaultPosition() { List listeners = new LinkedList<>(); doAnswer(invocation -> listeners.add(invocation.getArgument(0))) .when(fakeExoPlayer)