Skip to content

Commit 55515f6

Browse files
[video_player] Make video player avfoundation seek to async (#3299)
[video_player] Make video player avfoundation seek to async
1 parent 8972499 commit 55515f6

File tree

11 files changed

+365
-340
lines changed

11 files changed

+365
-340
lines changed

packages/video_player/video_player_avfoundation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.4.2
2+
3+
* Makes seekTo async and only complete when AVPlayer.seekTo completes.
4+
15
## 2.4.1
26

37
* Clarifies explanation of endorsement in README.

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ void main() {
7676

7777
await controller.seekTo(const Duration(seconds: 3));
7878

79-
// TODO(stuartmorgan): Switch to _controller.position once seekTo is
80-
// fixed on the native side to wait for completion, so this is testing
81-
// the native code rather than the MiniController position cache.
82-
expect(controller.value.position, const Duration(seconds: 3));
79+
expect(await controller.position, const Duration(seconds: 3));
8380
});
8481

8582
testWidgets('can be paused', (WidgetTester tester) async {

packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
@interface FLTVideoPlayer : NSObject <FlutterStreamHandler>
1313
@property(readonly, nonatomic) AVPlayer *player;
1414
@property(readonly, nonatomic) AVPlayerLayer *playerLayer;
15+
@property(readonly, nonatomic) int64_t position;
1516
@end
1617

1718
@interface FLTVideoPlayerPlugin (Test) <FLTAVFoundationVideoPlayerApi>
@@ -106,10 +107,30 @@ - (void)testSeekToInvokesTextureFrameAvailableOnTextureRegistry {
106107
OCMStub([partialRegistrar textures]).andReturn(mockTextureRegistry);
107108
FLTVideoPlayerPlugin *videoPlayerPlugin =
108109
(FLTVideoPlayerPlugin *)[[FLTVideoPlayerPlugin alloc] initWithRegistrar:partialRegistrar];
109-
FLTPositionMessage *message = [FLTPositionMessage makeWithTextureId:@101 position:@0];
110+
110111
FlutterError *error;
111-
[videoPlayerPlugin seekTo:message error:&error];
112+
[videoPlayerPlugin initialize:&error];
113+
XCTAssertNil(error);
114+
FLTCreateMessage *create = [FLTCreateMessage
115+
makeWithAsset:nil
116+
uri:@"https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8"
117+
packageName:nil
118+
formatHint:nil
119+
httpHeaders:@{}];
120+
FLTTextureMessage *textureMessage = [videoPlayerPlugin create:create error:&error];
121+
NSNumber *textureId = textureMessage.textureId;
122+
123+
XCTestExpectation *initializedExpectation = [self expectationWithDescription:@"seekTo completes"];
124+
FLTPositionMessage *message = [FLTPositionMessage makeWithTextureId:textureId position:@1234];
125+
[videoPlayerPlugin seekTo:message
126+
completion:^(FlutterError *_Nullable error) {
127+
[initializedExpectation fulfill];
128+
}];
129+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
112130
OCMVerify([mockTextureRegistry textureFrameAvailable:message.textureId.intValue]);
131+
132+
FLTVideoPlayer *player = videoPlayerPlugin.playersByTextureId[textureId];
133+
XCTAssertEqual([player position], 1234);
113134
}
114135

115136
- (void)testDeregistersFromPlayer {

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,11 @@ - (int64_t)duration {
403403
return FLTCMTimeToMillis([[[_player currentItem] asset] duration]);
404404
}
405405

406-
- (void)seekTo:(int)location {
407-
// TODO(stuartmorgan): Update this to use completionHandler: to only return
408-
// once the seek operation is complete once the Pigeon API is updated to a
409-
// version that handles async calls.
406+
- (void)seekTo:(int)location completionHandler:(void (^)(BOOL))completionHandler {
410407
[_player seekToTime:CMTimeMake(location, 1000)
411-
toleranceBefore:kCMTimeZero
412-
toleranceAfter:kCMTimeZero];
408+
toleranceBefore:kCMTimeZero
409+
toleranceAfter:kCMTimeZero
410+
completionHandler:completionHandler];
413411
}
414412

415413
- (void)setIsLooping:(BOOL)isLooping {
@@ -636,10 +634,16 @@ - (FLTPositionMessage *)position:(FLTTextureMessage *)input error:(FlutterError
636634
return result;
637635
}
638636

639-
- (void)seekTo:(FLTPositionMessage *)input error:(FlutterError **)error {
637+
- (void)seekTo:(FLTPositionMessage *)input
638+
completion:(void (^)(FlutterError *_Nullable))completion {
640639
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
641-
[player seekTo:input.position.intValue];
642-
[self.registry textureFrameAvailable:input.textureId.intValue];
640+
[player seekTo:input.position.intValue
641+
completionHandler:^(BOOL finished) {
642+
dispatch_async(dispatch_get_main_queue(), ^{
643+
[self.registry textureFrameAvailable:input.textureId.intValue];
644+
completion(nil);
645+
});
646+
}];
643647
}
644648

645649
- (void)pause:(FLTTextureMessage *)input error:(FlutterError **)error {

packages/video_player/video_player_avfoundation/ios/Classes/messages.g.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Copyright 2013 The Flutter Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v2.0.1), do not edit directly.
4+
// Autogenerated from Pigeon (v8.0.0), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
6+
67
#import <Foundation/Foundation.h>
8+
79
@protocol FlutterBinaryMessenger;
810
@protocol FlutterMessageCodec;
911
@class FlutterError;
@@ -97,7 +99,7 @@ NSObject<FlutterMessageCodec> *FLTAVFoundationVideoPlayerApiGetCodec(void);
9799
/// @return `nil` only when `error != nil`.
98100
- (nullable FLTPositionMessage *)position:(FLTTextureMessage *)msg
99101
error:(FlutterError *_Nullable *_Nonnull)error;
100-
- (void)seekTo:(FLTPositionMessage *)msg error:(FlutterError *_Nullable *_Nonnull)error;
102+
- (void)seekTo:(FLTPositionMessage *)msg completion:(void (^)(FlutterError *_Nullable))completion;
101103
- (void)pause:(FLTTextureMessage *)msg error:(FlutterError *_Nullable *_Nonnull)error;
102104
- (void)setMixWithOthers:(FLTMixWithOthersMessage *)msg
103105
error:(FlutterError *_Nullable *_Nonnull)error;

0 commit comments

Comments
 (0)