Skip to content

Commit 76e84c0

Browse files
authored
[video_player] Initialize player when size and duration become available (flutter#4438)
1 parent bb62aaa commit 76e84c0

File tree

7 files changed

+57
-20
lines changed

7 files changed

+57
-20
lines changed

packages/video_player/video_player/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.2.6
2+
3+
* Initialize player when size and duration become available on iOS
4+
15
## 2.2.5
26

37
* Support to closed caption WebVTT format added.

packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 50;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -269,7 +269,7 @@
269269
97C146E61CF9000F007C117D /* Project object */ = {
270270
isa = PBXProject;
271271
attributes = {
272-
LastUpgradeCheck = 1100;
272+
LastUpgradeCheck = 1300;
273273
ORGANIZATIONNAME = "The Flutter Authors";
274274
TargetAttributes = {
275275
97C146ED1CF9000F007C117D = {

packages/video_player/video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1100"
3+
LastUpgradeVersion = "1300"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

packages/video_player/video_player/example/ios/RunnerUITests/VideoPlayerUITests.m

+26-13
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,46 @@ - (void)setUp {
1818
[self.app launch];
1919
}
2020

21-
- (void)testTabs {
21+
- (void)testPlayVideo {
2222
XCUIApplication* app = self.app;
2323

2424
XCUIElement* remoteTab = [app.otherElements
2525
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"selected == YES"]];
26-
if (![remoteTab waitForExistenceWithTimeout:30.0]) {
27-
os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription);
28-
XCTFail(@"Failed due to not able to find selected Remote tab");
29-
}
26+
XCTAssertTrue([remoteTab waitForExistenceWithTimeout:30.0]);
3027
XCTAssertTrue([remoteTab.label containsString:@"Remote"]);
3128

29+
XCUIElement* playButton = app.staticTexts[@"Play"];
30+
XCTAssertTrue([playButton waitForExistenceWithTimeout:30.0]);
31+
[playButton tap];
32+
33+
XCUIElement* chirpClosedCaption = app.staticTexts[@"[ Birds chirping ]"];
34+
XCTAssertTrue([chirpClosedCaption waitForExistenceWithTimeout:30.0]);
35+
36+
XCUIElement* buzzClosedCaption = app.staticTexts[@"[ Buzzing ]"];
37+
XCTAssertTrue([buzzClosedCaption waitForExistenceWithTimeout:30.0]);
38+
39+
XCUIElement* playbackSpeed1x = app.staticTexts[@"Playback speed\n1.0x"];
40+
XCTAssertTrue([playbackSpeed1x waitForExistenceWithTimeout:30.0]);
41+
[playbackSpeed1x tap];
42+
43+
XCUIElement* playbackSpeed5xButton = app.buttons[@"5.0x"];
44+
XCTAssertTrue([playbackSpeed5xButton waitForExistenceWithTimeout:30.0]);
45+
[playbackSpeed5xButton tap];
46+
47+
XCUIElement* playbackSpeed5x = app.staticTexts[@"Playback speed\n5.0x"];
48+
XCTAssertTrue([playbackSpeed5x waitForExistenceWithTimeout:30.0]);
49+
50+
// Cycle through tabs.
3251
for (NSString* tabName in @[ @"Asset", @"List example" ]) {
3352
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"label BEGINSWITH %@", tabName];
3453
XCUIElement* unselectedTab = [app.staticTexts elementMatchingPredicate:predicate];
35-
if (![unselectedTab waitForExistenceWithTimeout:30.0]) {
36-
os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription);
37-
XCTFail(@"Failed due to not able to find unselected %@ tab", tabName);
38-
}
54+
XCTAssertTrue([unselectedTab waitForExistenceWithTimeout:30.0]);
3955
XCTAssertFalse(unselectedTab.isSelected);
4056
[unselectedTab tap];
4157

4258
XCUIElement* selectedTab = [app.otherElements
4359
elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label BEGINSWITH %@", tabName]];
44-
if (![selectedTab waitForExistenceWithTimeout:30.0]) {
45-
os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription);
46-
XCTFail(@"Failed due to not able to find selected %@ tab", tabName);
47-
}
60+
XCTAssertTrue([selectedTab waitForExistenceWithTimeout:30.0]);
4861
XCTAssertTrue(selectedTab.isSelected);
4962
}
5063
}

packages/video_player/video_player/example/lib/main.dart

+1
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ class _ControlsOverlay extends StatelessWidget {
298298
Icons.play_arrow,
299299
color: Colors.white,
300300
size: 100.0,
301+
semanticLabel: 'Play',
301302
),
302303
),
303304
),

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

+22-3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ - (void)updatePlayingState;
5252

5353
static void* timeRangeContext = &timeRangeContext;
5454
static void* statusContext = &statusContext;
55+
static void* presentationSizeContext = &presentationSizeContext;
56+
static void* durationContext = &durationContext;
5557
static void* playbackLikelyToKeepUpContext = &playbackLikelyToKeepUpContext;
5658
static void* playbackBufferEmptyContext = &playbackBufferEmptyContext;
5759
static void* playbackBufferFullContext = &playbackBufferFullContext;
@@ -71,6 +73,14 @@ - (void)addObservers:(AVPlayerItem*)item {
7173
forKeyPath:@"status"
7274
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
7375
context:statusContext];
76+
[item addObserver:self
77+
forKeyPath:@"presentationSize"
78+
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
79+
context:presentationSizeContext];
80+
[item addObserver:self
81+
forKeyPath:@"duration"
82+
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
83+
context:durationContext];
7484
[item addObserver:self
7585
forKeyPath:@"playbackLikelyToKeepUp"
7686
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
@@ -282,10 +292,19 @@ - (void)observeValueForKeyPath:(NSString*)path
282292
break;
283293
case AVPlayerItemStatusReadyToPlay:
284294
[item addOutput:_videoOutput];
285-
[self sendInitialized];
295+
[self setupEventSinkIfReadyToPlay];
286296
[self updatePlayingState];
287297
break;
288298
}
299+
} else if (context == presentationSizeContext || context == durationContext) {
300+
AVPlayerItem* item = (AVPlayerItem*)object;
301+
if (item.status == AVPlayerItemStatusReadyToPlay) {
302+
// Due to an apparent bug, when the player item is ready, it still may not have determined
303+
// its presentation size or duration. When these properties are finally set, re-check if
304+
// all required properties and instantiate the event sink if it is not already set up.
305+
[self setupEventSinkIfReadyToPlay];
306+
[self updatePlayingState];
307+
}
289308
} else if (context == playbackLikelyToKeepUpContext) {
290309
if ([[_player currentItem] isPlaybackLikelyToKeepUp]) {
291310
[self updatePlayingState];
@@ -316,7 +335,7 @@ - (void)updatePlayingState {
316335
_displayLink.paused = !_isPlaying;
317336
}
318337

319-
- (void)sendInitialized {
338+
- (void)setupEventSinkIfReadyToPlay {
320339
if (_eventSink && !_isInitialized) {
321340
CGSize size = [self.player currentItem].presentationSize;
322341
CGFloat width = size.width;
@@ -425,7 +444,7 @@ - (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
425444
// This line ensures the 'initialized' event is sent when the event
426445
// 'AVPlayerItemStatusReadyToPlay' fires before _eventSink is set (this function
427446
// onListenWithArguments is called)
428-
[self sendInitialized];
447+
[self setupEventSinkIfReadyToPlay];
429448
return nil;
430449
}
431450

packages/video_player/video_player/pubspec.yaml

+1-1
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.5
6+
version: 2.2.6
77

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

0 commit comments

Comments
 (0)