Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 688f052

Browse files
authored
[video_player] Validate size only when assets contain video tracks on iOS (#4639)
1 parent de6bb34 commit 688f052

File tree

6 files changed

+78
-4
lines changed

6 files changed

+78
-4
lines changed

packages/video_player/video_player/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.2.12
2+
3+
* iOS: Validate size only when assets contain video tracks.
4+
15
## 2.2.11
26

37
* Removes dependency on `meta`.
Binary file not shown.

packages/video_player/video_player/example/integration_test/video_player_test.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,68 @@ void main() {
272272
skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android),
273273
);
274274
});
275+
276+
// Audio playback is tested to prevent accidental regression,
277+
// but could be removed in the future.
278+
group('asset audios', () {
279+
setUp(() {
280+
_controller = VideoPlayerController.asset('assets/Audio.mp3');
281+
});
282+
283+
testWidgets('can be initialized', (WidgetTester tester) async {
284+
await _controller.initialize();
285+
286+
expect(_controller.value.isInitialized, true);
287+
expect(_controller.value.position, const Duration(seconds: 0));
288+
expect(_controller.value.isPlaying, false);
289+
// Due to the duration calculation accurancy between platforms,
290+
// the milliseconds on Web will be a slightly different from natives.
291+
// The audio was made with 44100 Hz, 192 Kbps CBR, and 32 bits.
292+
expect(
293+
_controller.value.duration,
294+
Duration(seconds: 5, milliseconds: kIsWeb ? 42 : 41),
295+
);
296+
});
297+
298+
testWidgets('can be played', (WidgetTester tester) async {
299+
await _controller.initialize();
300+
// Mute to allow playing without DOM interaction on Web.
301+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
302+
await _controller.setVolume(0);
303+
304+
await _controller.play();
305+
await tester.pumpAndSettle(_playDuration);
306+
307+
expect(_controller.value.isPlaying, true);
308+
expect(
309+
_controller.value.position,
310+
(Duration position) => position > const Duration(milliseconds: 0),
311+
);
312+
});
313+
314+
testWidgets('can seek', (WidgetTester tester) async {
315+
await _controller.initialize();
316+
await _controller.seekTo(const Duration(seconds: 3));
317+
318+
expect(_controller.value.position, const Duration(seconds: 3));
319+
});
320+
321+
testWidgets('can be paused', (WidgetTester tester) async {
322+
await _controller.initialize();
323+
// Mute to allow playing without DOM interaction on Web.
324+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
325+
await _controller.setVolume(0);
326+
327+
// Play for a second, then pause, and then wait a second.
328+
await _controller.play();
329+
await tester.pumpAndSettle(_playDuration);
330+
await _controller.pause();
331+
final Duration pausedPosition = _controller.value.position;
332+
await tester.pumpAndSettle(_playDuration);
333+
334+
// Verify that we stopped playing after the pause.
335+
expect(_controller.value.isPlaying, false);
336+
expect(_controller.value.position, pausedPosition);
337+
});
338+
});
275339
}

packages/video_player/video_player/example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ flutter:
3636
- assets/Butterfly-209.webm
3737
- assets/bumble_bee_captions.srt
3838
- assets/bumble_bee_captions.vtt
39+
- assets/Audio.mp3

packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,12 +337,14 @@ - (void)updatePlayingState {
337337

338338
- (void)setupEventSinkIfReadyToPlay {
339339
if (_eventSink && !_isInitialized) {
340+
BOOL hasVideoTracks =
341+
[[self.player.currentItem.asset tracksWithMediaType:AVMediaTypeVideo] count] != 0;
340342
CGSize size = [self.player currentItem].presentationSize;
341343
CGFloat width = size.width;
342344
CGFloat height = size.height;
343345

344-
// The player has not yet initialized.
345-
if (height == CGSizeZero.height && width == CGSizeZero.width) {
346+
// The player has not yet initialized when it contains video tracks.
347+
if (hasVideoTracks && height == CGSizeZero.height && width == CGSizeZero.width) {
346348
return;
347349
}
348350
// The player may be initialized but still needs to determine the duration.
@@ -375,7 +377,10 @@ - (int64_t)position {
375377
}
376378

377379
- (int64_t)duration {
378-
return FLTCMTimeToMillis([[_player currentItem] duration]);
380+
// Note: https://openradar.appspot.com/radar?id=4968600712511488
381+
// `[AVPlayerItem duration]` can be `kCMTimeIndefinite`,
382+
// use `[[AVPlayerItem asset] duration]` instead.
383+
return FLTCMTimeToMillis([[[_player currentItem] asset] duration]);
379384
}
380385

381386
- (void)seekTo:(int)location {

packages/video_player/video_player/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter
33
widgets on Android, iOS, and web.
44
repository: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
6-
version: 2.2.11
6+
version: 2.2.12
77

88
environment:
99
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)