From d3b39ca9cdec03ab5021de2e14ac3182c48953ab Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 19 Oct 2021 11:56:22 -0700 Subject: [PATCH 1/2] [video_player] Initialize player when size and duration become available --- .../video_player/video_player/CHANGELOG.md | 4 ++ .../ios/RunnerUITests/VideoPlayerUITests.m | 39 ++++++++++++------- .../video_player/example/lib/main.dart | 1 + .../ios/Classes/FLTVideoPlayerPlugin.m | 18 +++++++++ .../video_player/video_player/pubspec.yaml | 2 +- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/packages/video_player/video_player/CHANGELOG.md b/packages/video_player/video_player/CHANGELOG.md index 539a5520e5be..9eb9d24679d0 100644 --- a/packages/video_player/video_player/CHANGELOG.md +++ b/packages/video_player/video_player/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.6 + +* Initialize player when size and duration become available on iOS + ## 2.2.5 * Support to closed caption WebVTT format added. diff --git a/packages/video_player/video_player/example/ios/RunnerUITests/VideoPlayerUITests.m b/packages/video_player/video_player/example/ios/RunnerUITests/VideoPlayerUITests.m index 62d8c532ca03..5452c11cbf86 100644 --- a/packages/video_player/video_player/example/ios/RunnerUITests/VideoPlayerUITests.m +++ b/packages/video_player/video_player/example/ios/RunnerUITests/VideoPlayerUITests.m @@ -18,33 +18,46 @@ - (void)setUp { [self.app launch]; } -- (void)testTabs { +- (void)testPlayVideo { XCUIApplication* app = self.app; XCUIElement* remoteTab = [app.otherElements elementMatchingPredicate:[NSPredicate predicateWithFormat:@"selected == YES"]]; - if (![remoteTab waitForExistenceWithTimeout:30.0]) { - os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription); - XCTFail(@"Failed due to not able to find selected Remote tab"); - } + XCTAssertTrue([remoteTab waitForExistenceWithTimeout:30.0]); XCTAssertTrue([remoteTab.label containsString:@"Remote"]); + XCUIElement* playButton = app.staticTexts[@"Play"]; + XCTAssertTrue([playButton waitForExistenceWithTimeout:30.0]); + [playButton tap]; + + XCUIElement* chirpClosedCaption = app.staticTexts[@"[ Birds chirping ]"]; + XCTAssertTrue([chirpClosedCaption waitForExistenceWithTimeout:30.0]); + + XCUIElement* buzzClosedCaption = app.staticTexts[@"[ Buzzing ]"]; + XCTAssertTrue([buzzClosedCaption waitForExistenceWithTimeout:30.0]); + + XCUIElement* playbackSpeed1x = app.staticTexts[@"Playback speed\n1.0x"]; + XCTAssertTrue([playbackSpeed1x waitForExistenceWithTimeout:30.0]); + [playbackSpeed1x tap]; + + XCUIElement* playbackSpeed5xButton = app.buttons[@"5.0x"]; + XCTAssertTrue([playbackSpeed5xButton waitForExistenceWithTimeout:30.0]); + [playbackSpeed5xButton tap]; + + XCUIElement* playbackSpeed5x = app.staticTexts[@"Playback speed\n5.0x"]; + XCTAssertTrue([playbackSpeed5x waitForExistenceWithTimeout:30.0]); + + // Cycle through tabs. for (NSString* tabName in @[ @"Asset", @"List example" ]) { NSPredicate* predicate = [NSPredicate predicateWithFormat:@"label BEGINSWITH %@", tabName]; XCUIElement* unselectedTab = [app.staticTexts elementMatchingPredicate:predicate]; - if (![unselectedTab waitForExistenceWithTimeout:30.0]) { - os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription); - XCTFail(@"Failed due to not able to find unselected %@ tab", tabName); - } + XCTAssertTrue([unselectedTab waitForExistenceWithTimeout:30.0]); XCTAssertFalse(unselectedTab.isSelected); [unselectedTab tap]; XCUIElement* selectedTab = [app.otherElements elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label BEGINSWITH %@", tabName]]; - if (![selectedTab waitForExistenceWithTimeout:30.0]) { - os_log_error(OS_LOG_DEFAULT, "%@", app.debugDescription); - XCTFail(@"Failed due to not able to find selected %@ tab", tabName); - } + XCTAssertTrue([selectedTab waitForExistenceWithTimeout:30.0]); XCTAssertTrue(selectedTab.isSelected); } } diff --git a/packages/video_player/video_player/example/lib/main.dart b/packages/video_player/video_player/example/lib/main.dart index f035720396dd..042982798d54 100644 --- a/packages/video_player/video_player/example/lib/main.dart +++ b/packages/video_player/video_player/example/lib/main.dart @@ -298,6 +298,7 @@ class _ControlsOverlay extends StatelessWidget { Icons.play_arrow, color: Colors.white, size: 100.0, + semanticLabel: 'Play', ), ), ), diff --git a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m index f0f672d87431..8eeb5dd1019d 100644 --- a/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m +++ b/packages/video_player/video_player/ios/Classes/FLTVideoPlayerPlugin.m @@ -52,6 +52,8 @@ - (void)updatePlayingState; static void* timeRangeContext = &timeRangeContext; static void* statusContext = &statusContext; +static void* presentationSizeContext = &presentationSizeContext; +static void* durationContext = &durationContext; static void* playbackLikelyToKeepUpContext = &playbackLikelyToKeepUpContext; static void* playbackBufferEmptyContext = &playbackBufferEmptyContext; static void* playbackBufferFullContext = &playbackBufferFullContext; @@ -71,6 +73,14 @@ - (void)addObservers:(AVPlayerItem*)item { forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:statusContext]; + [item addObserver:self + forKeyPath:@"presentationSize" + options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew + context:presentationSizeContext]; + [item addObserver:self + forKeyPath:@"duration" + options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew + context:durationContext]; [item addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew @@ -286,6 +296,14 @@ - (void)observeValueForKeyPath:(NSString*)path [self updatePlayingState]; break; } + } else if (context == presentationSizeContext || context == durationContext) { + AVPlayerItem* item = (AVPlayerItem*)object; + if (item.status == AVPlayerItemStatusReadyToPlay) { + // When the player item is ready, it still may not have determined its presentation size or + // duration. When these properties are finally set, initialize the player. + [self sendInitialized]; + [self updatePlayingState]; + } } else if (context == playbackLikelyToKeepUpContext) { if ([[_player currentItem] isPlaybackLikelyToKeepUp]) { [self updatePlayingState]; diff --git a/packages/video_player/video_player/pubspec.yaml b/packages/video_player/video_player/pubspec.yaml index a6ee2d594656..c002ed859f2c 100644 --- a/packages/video_player/video_player/pubspec.yaml +++ b/packages/video_player/video_player/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter 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.5 +version: 2.2.6 environment: sdk: ">=2.14.0 <3.0.0" From c1a7c0de865e67f07d6c0620e5f73f7bfc111d06 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 27 Oct 2021 13:59:58 -0700 Subject: [PATCH 2/2] Review comments --- .../example/ios/Runner.xcodeproj/project.pbxproj | 4 ++-- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../video_player/ios/Classes/FLTVideoPlayerPlugin.m | 13 +++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj index 2921ef9161be..d19d578b6fb4 100644 --- a/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -269,7 +269,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1100; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/packages/video_player/video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/video_player/video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3f1ee9541e2f..0632b6533bc8 100644 --- a/packages/video_player/video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/video_player/video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@