Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[video_player_avfoundation] fix video playback speed resetting on iOS 16+ #8274

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,60 @@ - (void)testFailedToLoadVideoEventShouldBeAlwaysSent {
[self waitForExpectationsWithTimeout:10.0 handler:nil];
}

- (void)testPlaybackSpeedRemainsAfterSeek {
NSObject<FlutterTextureRegistry> *mockTextureRegistry =
OCMProtocolMock(@protocol(FlutterTextureRegistry));
NSObject<FlutterPluginRegistrar> *registrar =
[GetPluginRegistry() registrarForPlugin:@"PlaybackSpeedRemainsAfterSeek"];
NSObject<FlutterPluginRegistrar> *partialRegistrar = OCMPartialMock(registrar);
OCMStub([partialRegistrar textures]).andReturn(mockTextureRegistry);

// Create mock video output and AVPlayer
AVPlayerItemVideoOutput *mockVideoOutput = OCMPartialMock([[AVPlayerItemVideoOutput alloc] init]);
StubAVPlayer *mockAVPlayer = [[StubAVPlayer alloc] init];

// Set up the player factory
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:mockAVPlayer output:mockVideoOutput]
displayLinkFactory:nil
registrar:partialRegistrar];

// Initialize the video player plugin
FlutterError *initError;
[videoPlayerPlugin initialize:&initError];
XCTAssertNil(initError);

FVPCreationOptions *create = [FVPCreationOptions makeWithAsset:nil
uri:@"https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8"
packageName:nil
formatHint:nil
httpHeaders:@{}];
FlutterError *createError;
NSNumber *textureId = [videoPlayerPlugin createWithOptions:create error:&createError];
XCTAssertNil(createError);

// Ensure player was created
FVPVideoPlayer *player = videoPlayerPlugin.playersByTextureId[textureId];
XCTAssertNotNil(player);
AVPlayer *avPlayer = player.player;

// Set playback speed to 2.0
[player setPlaybackSpeed:2.0];
XCTAssertEqual(avPlayer.rate, 2.0, @"Playback speed should be set to 2.0");

// Perform a seek operation
[videoPlayerPlugin seekTo:1234
forPlayer:textureId.integerValue
completion:^(FlutterError *_Nullable error) {
XCTAssertNil(error);
}];

// After seek, verify playback speed remains unchanged
XCTAssertEqual(avPlayer.rate, 2.0, @"Playback speed should remain 2.0 after seeking");
XCTAssertEqual(avPlayer.defaultRate, 2.0, @"Default playback speed should be 2.0 after seeking");
}


#if TARGET_OS_IOS
- (void)validateTransformFixForOrientation:(UIImageOrientation)orientation {
AVAssetTrack *track = [[FakeAVAssetTrack alloc] initWithOrientation:orientation];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,10 @@ - (void)setPlaybackSpeed:(double)speed {
}
return;
}

if (@available(iOS 16, *)) {
sha3rawi33 marked this conversation as resolved.
Show resolved Hide resolved
// this will avoid resetting playback speed to 1.0x on seeking
_player.defaultRate = speed;
}
_player.rate = speed;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,5 +374,20 @@ void main() {
),
]));
});

test('playback speed should remain after seeking', () async {
// Set initial playback speed
await player.setPlaybackSpeed(1, 2.0); // Set to 2.0x
expect(log.log.last, 'setPlaybackSpeed');
expect(log.playbackSpeed, 2.0);

// Now seek to a different position
await player.seekTo(1, const Duration(milliseconds: 5000)); // Seek to 5 seconds
expect(log.log.last, 'seekTo');
expect(log.position, 5000);

// After seeking, the playback speed should still be 2.0x
expect(log.playbackSpeed, 2.0);
});
});
}
Loading