diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 013e20f93118..f96308b447f4 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.5+1 + +* Fixes issue where `initialize()` `Future` stalls when failing to load source + data and does not throw an error. + ## 0.10.5 * Support `web` by default. diff --git a/packages/video_player/video_player/lib/video_player.dart b/packages/video_player/video_player/lib/video_player.dart index cb24ac8cb100..c41b47c1cacf 100644 --- a/packages/video_player/video_player/lib/video_player.dart +++ b/packages/video_player/video_player/lib/video_player.dart @@ -272,6 +272,9 @@ class VideoPlayerController extends ValueNotifier { final PlatformException e = obj; value = VideoPlayerValue.erroneous(e.message); _timer?.cancel(); + if (!initializingCompleter.isCompleted) { + initializingCompleter.completeError(obj); + } } _eventSubscription = VideoPlayerPlatform.instance diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index 43c9ead07d25..33af2872ff14 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -1,7 +1,7 @@ name: video_player description: Flutter plugin for displaying inline video with other Flutter widgets on Android and iOS. -version: 0.10.5 +version: 0.10.5+1 homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player flutter: diff --git a/packages/video_player/video_player/test/video_player_test.dart b/packages/video_player/video_player/test/video_player_test.dart index d2a90b7182c9..ebabacb1dc48 100644 --- a/packages/video_player/video_player/test/video_player_test.dart +++ b/packages/video_player/video_player/test/video_player_test.dart @@ -134,6 +134,21 @@ void main() { }); }); + test('init errors', () async { + final VideoPlayerController controller = VideoPlayerController.network( + 'http://testing.com/invalid_url', + ); + try { + dynamic error; + fakeVideoPlayerPlatform.forceInitError = true; + await controller.initialize().catchError((dynamic e) => error = e); + final PlatformException platformEx = error; + expect(platformEx.code, equals('VideoError')); + } finally { + fakeVideoPlayerPlatform.forceInitError = false; + } + }); + test('file', () async { final VideoPlayerController controller = VideoPlayerController.file(File('a.avi')); @@ -437,6 +452,7 @@ class FakeVideoPlayerPlatform { List calls = []; List> dataSourceDescriptions = >[]; final Map streams = {}; + bool forceInitError = false; int nextTextureId = 0; final Map _positions = {}; @@ -447,8 +463,8 @@ class FakeVideoPlayerPlatform { initialized.complete(true); break; case 'create': - streams[nextTextureId] = FakeVideoEventStream( - nextTextureId, 100, 100, const Duration(seconds: 1)); + streams[nextTextureId] = FakeVideoEventStream(nextTextureId, 100, 100, + const Duration(seconds: 1), forceInitError); final Map dataSource = call.arguments; dataSourceDescriptions.add(dataSource.cast()); return Future>.sync(() { @@ -481,7 +497,8 @@ class FakeVideoPlayerPlatform { } class FakeVideoEventStream { - FakeVideoEventStream(this.textureId, this.width, this.height, this.duration) { + FakeVideoEventStream(this.textureId, this.width, this.height, this.duration, + this.initWithError) { eventsChannel = FakeEventsChannel( 'flutter.io/videoPlayer/videoEvents$textureId', onListen); } @@ -490,16 +507,20 @@ class FakeVideoEventStream { int width; int height; Duration duration; + bool initWithError; FakeEventsChannel eventsChannel; void onListen() { - final Map initializedEvent = { - 'event': 'initialized', - 'duration': duration.inMilliseconds, - 'width': width, - 'height': height, - }; - eventsChannel.sendEvent(initializedEvent); + if (!initWithError) { + eventsChannel.sendEvent({ + 'event': 'initialized', + 'duration': duration.inMilliseconds, + 'width': width, + 'height': height, + }); + } else { + eventsChannel.sendError('VideoError', 'Video player had error XYZ'); + } } } @@ -522,13 +543,23 @@ class FakeEventsChannel { } void sendEvent(dynamic event) { + _sendMessage(const StandardMethodCodec().encodeSuccessEnvelope(event)); + } + + void sendError(String code, [String message, dynamic details]) { + _sendMessage(const StandardMethodCodec().encodeErrorEnvelope( + code: code, + message: message, + details: details, + )); + } + + void _sendMessage(ByteData data) { // TODO(jackson): This has been deprecated and should be replaced // with `ServicesBinding.instance.defaultBinaryMessenger` when it's // available on all the versions of Flutter that we test. // ignore: deprecated_member_use defaultBinaryMessenger.handlePlatformMessage( - eventsMethodChannel.name, - const StandardMethodCodec().encodeSuccessEnvelope(event), - (ByteData data) {}); + eventsMethodChannel.name, data, (ByteData data) {}); } }