[video_player] Validate size only when assets contain video tracks on iOS (#4639)
diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md
index 9f23fd0..2513b20 100644
--- a/packages/video_player/video_player/CHANGELOG.md
+++ b/packages/video_player/video_player/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.2.12
+
+* iOS: Validate size only when assets contain video tracks.
+
## 2.2.11
* Removes dependency on `meta`.
diff --git a/packages/video_player/video_player/example/assets/Audio.mp3 b/packages/video_player/video_player/example/assets/Audio.mp3
new file mode 100644
index 0000000..355eb9b
--- /dev/null
+++ b/packages/video_player/video_player/example/assets/Audio.mp3
Binary files differ
diff --git a/packages/video_player/video_player/example/integration_test/video_player_test.dart b/packages/video_player/video_player/example/integration_test/video_player_test.dart
index d652c04..0c2252b 100644
--- a/packages/video_player/video_player/example/integration_test/video_player_test.dart
+++ b/packages/video_player/video_player/example/integration_test/video_player_test.dart
@@ -272,4 +272,68 @@
skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android),
);
});
+
+ // Audio playback is tested to prevent accidental regression,
+ // but could be removed in the future.
+ group('asset audios', () {
+ setUp(() {
+ _controller = VideoPlayerController.asset('assets/Audio.mp3');
+ });
+
+ testWidgets('can be initialized', (WidgetTester tester) async {
+ await _controller.initialize();
+
+ expect(_controller.value.isInitialized, true);
+ expect(_controller.value.position, const Duration(seconds: 0));
+ expect(_controller.value.isPlaying, false);
+ // Due to the duration calculation accurancy between platforms,
+ // the milliseconds on Web will be a slightly different from natives.
+ // The audio was made with 44100 Hz, 192 Kbps CBR, and 32 bits.
+ expect(
+ _controller.value.duration,
+ Duration(seconds: 5, milliseconds: kIsWeb ? 42 : 41),
+ );
+ });
+
+ 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);
+
+ expect(_controller.value.isPlaying, true);
+ expect(
+ _controller.value.position,
+ (Duration position) => position > const Duration(milliseconds: 0),
+ );
+ });
+
+ testWidgets('can seek', (WidgetTester tester) async {
+ await _controller.initialize();
+ await _controller.seekTo(const Duration(seconds: 3));
+
+ expect(_controller.value.position, const Duration(seconds: 3));
+ });
+
+ testWidgets('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();
+ await tester.pumpAndSettle(_playDuration);
+ await _controller.pause();
+ final Duration pausedPosition = _controller.value.position;
+ await tester.pumpAndSettle(_playDuration);
+
+ // Verify that we stopped playing after the pause.
+ expect(_controller.value.isPlaying, false);
+ expect(_controller.value.position, pausedPosition);
+ });
+ });
}
diff --git a/packages/video_player/video_player/example/pubspec.yaml b/packages/video_player/video_player/example/pubspec.yaml
index 6fa02c4..eef6eb7 100644
--- a/packages/video_player/video_player/example/pubspec.yaml
+++ b/packages/video_player/video_player/example/pubspec.yaml
@@ -36,3 +36,4 @@
- assets/Butterfly-209.webm
- assets/bumble_bee_captions.srt
- assets/bumble_bee_captions.vtt
+ - assets/Audio.mp3
diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m
index b581cd8..d5bea17 100644
--- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m
+++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m
@@ -337,12 +337,14 @@
- (void)setupEventSinkIfReadyToPlay {
if (_eventSink && !_isInitialized) {
+ BOOL hasVideoTracks =
+ [[self.player.currentItem.asset tracksWithMediaType:AVMediaTypeVideo] count] != 0;
CGSize size = [self.player currentItem].presentationSize;
CGFloat width = size.width;
CGFloat height = size.height;
- // The player has not yet initialized.
- if (height == CGSizeZero.height && width == CGSizeZero.width) {
+ // The player has not yet initialized when it contains video tracks.
+ if (hasVideoTracks && height == CGSizeZero.height && width == CGSizeZero.width) {
return;
}
// The player may be initialized but still needs to determine the duration.
@@ -375,7 +377,10 @@
}
- (int64_t)duration {
- return FLTCMTimeToMillis([[_player currentItem] duration]);
+ // Note: https://openradar.appspot.com/radar?id=4968600712511488
+ // `[AVPlayerItem duration]` can be `kCMTimeIndefinite`,
+ // use `[[AVPlayerItem asset] duration]` instead.
+ return FLTCMTimeToMillis([[[_player currentItem] asset] duration]);
}
- (void)seekTo:(int)location {
diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml
index 0eb7a4e..e725db7 100644
--- a/packages/video_player/video_player/pubspec.yaml
+++ b/packages/video_player/video_player/pubspec.yaml
@@ -3,7 +3,7 @@
widgets on Android, iOS, and web.
repository: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
-version: 2.2.11
+version: 2.2.12
environment:
sdk: ">=2.14.0 <3.0.0"