Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/video_player/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
3 changes: 3 additions & 0 deletions packages/video_player/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
final PlatformException e = obj;
value = VideoPlayerValue.erroneous(e.message);
_timer?.cancel();
if (!initializingCompleter.isCompleted) {
initializingCompleter.completeError(obj);
}
}

_eventSubscription = VideoPlayerPlatform.instance
Expand Down
2 changes: 1 addition & 1 deletion packages/video_player/video_player/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
57 changes: 44 additions & 13 deletions packages/video_player/video_player/test/video_player_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines +141 to +148
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Why the try/finally here? Is the catchError not really catching the error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just used to reset the forceInitError flag to ensure if any other error is thrown during testing the flag is reset so other tests can complete without issue.

}
});

test('file', () async {
final VideoPlayerController controller =
VideoPlayerController.file(File('a.avi'));
Expand Down Expand Up @@ -437,6 +452,7 @@ class FakeVideoPlayerPlatform {
List<MethodCall> calls = <MethodCall>[];
List<Map<String, dynamic>> dataSourceDescriptions = <Map<String, dynamic>>[];
final Map<int, FakeVideoEventStream> streams = <int, FakeVideoEventStream>{};
bool forceInitError = false;
int nextTextureId = 0;
final Map<int, Duration> _positions = <int, Duration>{};

Expand All @@ -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<dynamic, dynamic> dataSource = call.arguments;
dataSourceDescriptions.add(dataSource.cast<String, dynamic>());
return Future<Map<String, int>>.sync(() {
Expand Down Expand Up @@ -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);
}
Expand All @@ -490,16 +507,20 @@ class FakeVideoEventStream {
int width;
int height;
Duration duration;
bool initWithError;
FakeEventsChannel eventsChannel;

void onListen() {
final Map<String, dynamic> initializedEvent = <String, dynamic>{
'event': 'initialized',
'duration': duration.inMilliseconds,
'width': width,
'height': height,
};
eventsChannel.sendEvent(initializedEvent);
if (!initWithError) {
eventsChannel.sendEvent(<String, dynamic>{
'event': 'initialized',
'duration': duration.inMilliseconds,
'width': width,
'height': height,
});
} else {
eventsChannel.sendError('VideoError', 'Video player had error XYZ');
}
}
}

Expand All @@ -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) {});
}
}