[video_player_avfoundation] Implement preventsDisplaySleepDuringVideoPlayback (#11547)
## Description
Implements the `setPreventsDisplaySleepDuringVideoPlayback` platform interface method using `AVPlayer.preventsDisplaySleepDuringVideoPlayback` on iOS and macOS.
AVFoundation implementation breakout PR for flutter/packages#11225.
## Dependencies
- **Depends on the `video_player_platform_interface` 6.7.0 breakout PR.** CI will fail until that PR lands and the new interface version is published. Keeping this PR in draft until then.
## Changes
- Implements `setPreventsDisplaySleepDuringVideoPlayback` in `FVPVideoPlayer.m` and wires it through the Dart platform implementation.
- Adds the Pigeon method definition and regenerates messages (includes a pigeon v26.1.7 → v26.2.3 bump carried over from the parent PR).
- Bumps `video_player_avfoundation` to 2.10.0 and updates the `video_player_platform_interface` constraint to ^6.7.0.
- Updates CHANGELOG.
## Related
- Parent PR: flutter/packages#11225
- Fixes: flutter/flutter#183520
diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md
index 7b8727b..f97f9f1 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 7ee2da9..72bbe1e 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 @@
#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 c5c4865..316aa62 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)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 7591b3d..b60dc53 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 @@
[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<id> *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 c3ef91c..7927aca 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 @@
/// 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<FlutterBinaryMessenger> 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 062a759..c98edfc 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
@@ -172,6 +172,16 @@
}
@override
+ Future<void> setPreventsDisplaySleepDuringVideoPlayback(
+ int playerId,
+ bool preventsDisplaySleepDuringVideoPlayback,
+ ) {
+ return _playerWith(
+ id: playerId,
+ ).setPreventsDisplaySleepDuringVideoPlayback(preventsDisplaySleepDuringVideoPlayback);
+ }
+
+ @override
Future<List<VideoAudioTrack>> getAudioTracks(int playerId) async {
final List<MediaSelectionAudioTrackData> nativeData = await _playerWith(
id: playerId,
@@ -341,6 +351,10 @@
Future<void> setPlaybackSpeed(double speed) => _api.setPlaybackSpeed(speed);
+ Future<void> setPreventsDisplaySleepDuringVideoPlayback(
+ bool preventsDisplaySleepDuringVideoPlayback,
+ ) => _api.setPreventsDisplaySleepDuringVideoPlayback(preventsDisplaySleepDuringVideoPlayback);
+
Future<void> 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 4906bfc..31a1b21 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 @@
_extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
}
+
+ Future<void> setPreventsDisplaySleepDuringVideoPlayback(
+ bool preventsDisplaySleepDuringVideoPlayback,
+ ) async {
+ final pigeonVar_channelName =
+ 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPreventsDisplaySleepDuringVideoPlayback$pigeonVar_messageChannelSuffix';
+ final pigeonVar_channel = BasicMessageChannel<Object?>(
+ pigeonVar_channelName,
+ pigeonChannelCodec,
+ binaryMessenger: pigeonVar_binaryMessenger,
+ );
+ final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[
+ preventsDisplaySleepDuringVideoPlayback,
+ ]);
+ final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
+
+ _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 73d7a9b..1b62742 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 @@
/// 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 3db8aea..9a1e29e 100644
--- a/packages/video_player/video_player_avfoundation/pubspec.yaml
+++ b/packages/video_player/video_player_avfoundation/pubspec.yaml
@@ -2,7 +2,7 @@
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 @@
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 a8d3125..16dfd7e 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 @@
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 7102c44..c4841bd 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 @@
returnValueForMissingStub: _i5.Future<void>.value(),
)
as _i5.Future<void>);
+
+ @override
+ _i5.Future<void> setPreventsDisplaySleepDuringVideoPlayback(
+ bool? preventsDisplaySleepDuringVideoPlayback,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(#setPreventsDisplaySleepDuringVideoPlayback, [
+ preventsDisplaySleepDuringVideoPlayback,
+ ]),
+ returnValue: _i5.Future<void>.value(),
+ returnValueForMissingStub: _i5.Future<void>.value(),
+ )
+ as _i5.Future<void>);
}