Skip to content

Commit

Permalink
fix(video_player): buffering state events missing on Android & Web (f…
Browse files Browse the repository at this point in the history
…ixes flutter/flutter#28494) (#2563)
  • Loading branch information
kmod-midori authored Dec 17, 2020
1 parent cb54e7c commit 143b261
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.0-nullsafety.4

* Fixed an issue where `isBuffering` was not updating on Android.

## 2.0.0-nullsafety.3

* Dart null safety requires `2.12`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,21 @@ public void onCancel(Object o) {

exoPlayer.addListener(
new EventListener() {
private boolean isBuffering = false;

public void setBuffering(boolean buffering) {
if (isBuffering != buffering) {
isBuffering = buffering;
Map<String, Object> event = new HashMap<>();
event.put("event", isBuffering ? "bufferingStart" : "bufferingEnd");
eventSink.success(event);
}
}

@Override
public void onPlaybackStateChanged(final int playbackState) {
if (playbackState == Player.STATE_BUFFERING) {
setBuffering(true);
sendBufferingUpdate();
} else if (playbackState == Player.STATE_READY) {
if (!isInitialized) {
Expand All @@ -184,10 +195,15 @@ public void onPlaybackStateChanged(final int playbackState) {
event.put("event", "completed");
eventSink.success(event);
}

if (playbackState != Player.STATE_BUFFERING) {
setBuffering(false);
}
}

@Override
public void onPlayerError(final ExoPlaybackException error) {
setBuffering(false);
if (eventSink != null) {
eventSink.error("VideoError", "Video player had error " + error, null);
}
Expand Down
56 changes: 54 additions & 2 deletions example/integration_test/video_player_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// TODO(amirh): Remove this once flutter_driver supports null safety.
// https://github.com/flutter/flutter/issues/71379
// @dart = 2.9
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:integration_test/integration_test.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -34,10 +35,58 @@ void main() {
const Duration(seconds: 7, milliseconds: 540));
});

testWidgets(
'reports buffering status',
(WidgetTester tester) async {
VideoPlayerController networkController = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
);
await networkController.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await networkController.setVolume(0);
final Completer<void> started = Completer();
final Completer<void> ended = Completer();
bool startedBuffering = false;
bool endedBuffering = false;
networkController.addListener(() {
if (networkController.value.isBuffering && !startedBuffering) {
startedBuffering = true;
started.complete();
}
if (startedBuffering &&
!networkController.value.isBuffering &&
!endedBuffering) {
endedBuffering = true;
ended.complete();
}
});

await networkController.play();
await networkController.seekTo(const Duration(seconds: 5));
await tester.pumpAndSettle(_playDuration);
await networkController.pause();

expect(networkController.value.isPlaying, false);
expect(networkController.value.position,
(Duration position) => position > const Duration(seconds: 0));

await started;
expect(startedBuffering, true);

await ended;
expect(endedBuffering, true);
},
skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android),
);

testWidgets(
'can be played',
(WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

await _controller.play();
await tester.pumpAndSettle(_playDuration);
Expand All @@ -63,6 +112,9 @@ void main() {
'can be paused',
(WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

// Play for a second, then pause, and then wait a second.
await _controller.play();
Expand Down Expand Up @@ -109,6 +161,6 @@ void main() {

await tester.pumpAndSettle();
expect(_controller.value.isPlaying, true);
});
}, skip: kIsWeb); // Web does not support local assets.
});
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Flutter plugin for displaying inline video with other Flutter
# 0.10.y+z is compatible with 1.0.0, if you land a breaking change bump
# the version to 2.0.0.
# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0
version: 2.0.0-nullsafety.3
version: 2.0.0-nullsafety.4
homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player

flutter:
Expand Down

0 comments on commit 143b261

Please sign in to comment.