Skip to content

Commit 2424147

Browse files
authored
[video_player_android] Handle BehindLiveWindowException (#5869)
This PR adds error handling for BehindLiveWindowException when playing video streams as recommended in [ExoPlayer docs](https://developer.android.com/media/media3/exoplayer/live-streaming#behindlivewindowexception-and) Fixes flutter/flutter#100478
1 parent 41a0078 commit 2424147

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

packages/video_player/video_player_android/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
## NEXT
1+
## 2.4.12
22

33
* Updates compileSdk version to 34.
4+
* Adds error handling for `BehindLiveWindowException`, which may occur upon live-video playback failure.
45

56
## 2.4.11
67

packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,11 @@ public void onPlaybackStateChanged(final int playbackState) {
227227
@Override
228228
public void onPlayerError(@NonNull final PlaybackException error) {
229229
setBuffering(false);
230-
if (eventSink != null) {
230+
if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
231+
// See https://exoplayer.dev/live-streaming.html#behindlivewindowexception-and-error_code_behind_live_window
232+
exoPlayer.seekToDefaultPosition();
233+
exoPlayer.prepare();
234+
} else if (eventSink != null) {
231235
eventSink.error("VideoError", "Video player had error " + error, null);
232236
}
233237
}

packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,25 @@
55
package io.flutter.plugins.videoplayer;
66

77
import static org.junit.Assert.assertEquals;
8+
import static org.mockito.ArgumentMatchers.any;
89
import static org.mockito.ArgumentMatchers.anyBoolean;
10+
import static org.mockito.Mockito.*;
911
import static org.mockito.Mockito.any;
1012
import static org.mockito.Mockito.doAnswer;
11-
import static org.mockito.Mockito.mock;
1213
import static org.mockito.Mockito.never;
1314
import static org.mockito.Mockito.spy;
1415
import static org.mockito.Mockito.times;
15-
import static org.mockito.Mockito.verify;
16-
import static org.mockito.Mockito.when;
1716

1817
import com.google.android.exoplayer2.ExoPlayer;
1918
import com.google.android.exoplayer2.Format;
19+
import com.google.android.exoplayer2.PlaybackException;
20+
import com.google.android.exoplayer2.Player;
2021
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
2122
import io.flutter.plugin.common.EventChannel;
2223
import io.flutter.view.TextureRegistry;
2324
import java.util.HashMap;
25+
import java.util.LinkedList;
26+
import java.util.List;
2427
import java.util.Map;
2528
import org.junit.Before;
2629
import org.junit.Test;
@@ -278,4 +281,28 @@ public void onIsPlayingChangedSendsExpectedEvent() {
278281
assertEquals(event2.get("event"), "isPlayingStateUpdate");
279282
assertEquals(event2.get("isPlaying"), false);
280283
}
284+
285+
@Test
286+
public void behindLiveWindowErrorResetsPlayerToDefaultPosition() {
287+
List<Player.Listener> listeners = new LinkedList<>();
288+
doAnswer(invocation -> listeners.add(invocation.getArgument(0)))
289+
.when(fakeExoPlayer)
290+
.addListener(any());
291+
292+
VideoPlayer unused =
293+
new VideoPlayer(
294+
fakeExoPlayer,
295+
fakeEventChannel,
296+
fakeSurfaceTextureEntry,
297+
fakeVideoPlayerOptions,
298+
fakeEventSink,
299+
httpDataSourceFactorySpy);
300+
301+
PlaybackException exception =
302+
new PlaybackException(null, null, PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW);
303+
listeners.forEach(listener -> listener.onPlayerError(exception));
304+
305+
verify(fakeExoPlayer).seekToDefaultPosition();
306+
verify(fakeExoPlayer).prepare();
307+
}
281308
}

packages/video_player/video_player_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: video_player_android
22
description: Android implementation of the video_player plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
5-
version: 2.4.11
5+
version: 2.4.12
66

77
environment:
88
sdk: ">=3.0.0 <4.0.0"

0 commit comments

Comments
 (0)