diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md index 7b8727bbb951..f97f9f1c5e41 100644 --- a/packages/video_player/video_player_avfoundation/CHANGELOG.md +++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.11.0 + +* Implements `setPreventsDisplaySleepDuringVideoPlayback` using + `AVPlayer.preventsDisplaySleepDuringVideoPlayback`. + ## 2.10.0 * Implements `getVideoTracks()` and `selectVideoTrack()` methods for video track (quality) selection using AVFoundation. diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift index 7ee2da937ee5..72bbe1e44658 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift @@ -376,6 +376,26 @@ private let hlsAudioTestURI = #expect((inspectableAVPlayer.afterTolerance?.intValue ?? 0) > 0) } + @Test func setPreventsDisplaySleepDuringVideoPlayback() { + let stubAVFactory = StubFVPAVFactory(player: AVPlayer()) + let player = FVPVideoPlayer( + playerItem: StubPlayerItem(), + avFactory: stubAVFactory, + viewProvider: StubViewProvider()) + let listener = StubEventListener() + player.eventListener = listener + + var error: FlutterError? + // The setter should update the underlying AVPlayer in both directions. + player.setPreventsDisplaySleepDuringVideoPlayback(false, error: &error) + #expect(error == nil) + #expect(player.player.preventsDisplaySleepDuringVideoPlayback == false) + + player.setPreventsDisplaySleepDuringVideoPlayback(true, error: &error) + #expect(error == nil) + #expect(player.player.preventsDisplaySleepDuringVideoPlayback == true) + } + /// Sanity checks a video player playing the given URL with the actual AVPlayer. This is essentially /// a mini integration test of the player component. /// diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m index c5c4865ffe1c..316aa6237c25 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m @@ -661,6 +661,11 @@ - (void)selectAudioTrackAtIndex:(NSInteger)trackIndex } } +- (void)setPreventsDisplaySleepDuringVideoPlayback:(BOOL)preventsDisplaySleepDuringVideoPlayback + error:(FlutterError *_Nullable *_Nonnull)error { + self.player.preventsDisplaySleepDuringVideoPlayback = preventsDisplaySleepDuringVideoPlayback; +} + #pragma mark - Private - (int64_t)duration { diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m index 7591b3d9b3c0..b60dc5357725 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m @@ -741,4 +741,32 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM [channel setMessageHandler:nil]; } } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.video_player_avfoundation." + @"VideoPlayerInstanceApi." + @"setPreventsDisplaySleepDuringVideoPlayback", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(setPreventsDisplaySleepDuringVideoPlayback: + error:)], + @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to " + @"@selector(setPreventsDisplaySleepDuringVideoPlayback:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + BOOL arg_preventsDisplaySleepDuringVideoPlayback = + [GetNullableObjectAtIndex(args, 0) boolValue]; + FlutterError *error; + [api setPreventsDisplaySleepDuringVideoPlayback:arg_preventsDisplaySleepDuringVideoPlayback + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } } diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h index c3ef91c0d42a..7927aca8ec68 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h @@ -113,6 +113,8 @@ NSObject *FVPGetVideoPlayerInstanceMessagesCodec(void); /// Pass 0 to enable auto quality selection. - (void)selectVideoTrackWithBitrate:(NSInteger)bitrate error:(FlutterError *_Nullable *_Nonnull)error; +- (void)setPreventsDisplaySleepDuringVideoPlayback:(BOOL)preventsDisplaySleepDuringVideoPlayback + error:(FlutterError *_Nullable *_Nonnull)error; @end extern void SetUpFVPVideoPlayerInstanceApi(id binaryMessenger, diff --git a/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart b/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart index 062a759f4de2..c98edfc15ec8 100644 --- a/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart +++ b/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart @@ -171,6 +171,16 @@ class AVFoundationVideoPlayer extends VideoPlayerPlatform { return _api.setMixWithOthers(mixWithOthers); } + @override + Future setPreventsDisplaySleepDuringVideoPlayback( + int playerId, + bool preventsDisplaySleepDuringVideoPlayback, + ) { + return _playerWith( + id: playerId, + ).setPreventsDisplaySleepDuringVideoPlayback(preventsDisplaySleepDuringVideoPlayback); + } + @override Future> getAudioTracks(int playerId) async { final List nativeData = await _playerWith( @@ -341,6 +351,10 @@ class _PlayerInstance { Future setPlaybackSpeed(double speed) => _api.setPlaybackSpeed(speed); + Future setPreventsDisplaySleepDuringVideoPlayback( + bool preventsDisplaySleepDuringVideoPlayback, + ) => _api.setPreventsDisplaySleepDuringVideoPlayback(preventsDisplaySleepDuringVideoPlayback); + Future seekTo(Duration position) { return _api.seekTo(position.inMilliseconds); } diff --git a/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart b/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart index 4906bfc9e0be..31a1b219e8c8 100644 --- a/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart +++ b/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart @@ -588,4 +588,22 @@ class VideoPlayerInstanceApi { _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); } + + Future setPreventsDisplaySleepDuringVideoPlayback( + bool preventsDisplaySleepDuringVideoPlayback, + ) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPreventsDisplaySleepDuringVideoPlayback$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([ + preventsDisplaySleepDuringVideoPlayback, + ]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); + } } diff --git a/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart b/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart index 73d7a9bc3dcf..1b62742e88db 100644 --- a/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart +++ b/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart @@ -122,4 +122,7 @@ abstract class VideoPlayerInstanceApi { /// Pass 0 to enable auto quality selection. @ObjCSelector('selectVideoTrackWithBitrate:') void selectVideoTrack(int bitrate); + + @ObjCSelector('setPreventsDisplaySleepDuringVideoPlayback:') + void setPreventsDisplaySleepDuringVideoPlayback(bool preventsDisplaySleepDuringVideoPlayback); } diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index 3db8aead3861..9a1e29eab6d1 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_avfoundation description: iOS and macOS implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.10.0 +version: 2.11.0 environment: sdk: ^3.10.0 @@ -25,7 +25,7 @@ dependencies: flutter: sdk: flutter meta: ^1.10.0 - video_player_platform_interface: ^6.7.0 + video_player_platform_interface: ^6.8.0 dev_dependencies: build_runner: ^2.3.3 diff --git a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart index a8d312514ae0..16dfd7e9d881 100644 --- a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart +++ b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart @@ -342,6 +342,24 @@ void main() { verify(playerApi.setPlaybackSpeed(speed)); }); + group('setPreventsDisplaySleepDuringVideoPlayback', () { + test('passes true', () async { + final (AVFoundationVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi) = + setUpMockPlayer(playerId: 1); + await player.setPreventsDisplaySleepDuringVideoPlayback(1, true); + + verify(playerApi.setPreventsDisplaySleepDuringVideoPlayback(true)); + }); + + test('passes false', () async { + final (AVFoundationVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi) = + setUpMockPlayer(playerId: 1); + await player.setPreventsDisplaySleepDuringVideoPlayback(1, false); + + verify(playerApi.setPreventsDisplaySleepDuringVideoPlayback(false)); + }); + }); + test('seekTo', () async { final (AVFoundationVideoPlayer player, _, MockVideoPlayerInstanceApi playerApi) = setUpMockPlayer(playerId: 1); diff --git a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart index 7102c443a86d..c4841bd8b38e 100644 --- a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart +++ b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart @@ -244,4 +244,17 @@ class MockVideoPlayerInstanceApi extends _i1.Mock implements _i3.VideoPlayerInst returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + + @override + _i5.Future setPreventsDisplaySleepDuringVideoPlayback( + bool? preventsDisplaySleepDuringVideoPlayback, + ) => + (super.noSuchMethod( + Invocation.method(#setPreventsDisplaySleepDuringVideoPlayback, [ + preventsDisplaySleepDuringVideoPlayback, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); }