How can I make the Control Center slider editable?
There is the changePlaybackPositionCommand API with the associated Event MPChangePlaybackPositionCommandEvent.positionTime (see https://developer.apple.com/library/ios/releasenotes/General/iOS91APIDiffs/Objective-C/MediaPlayer.html)
I tried
[commandCenter.changePlaybackPositionCommand
addTarget: self
action: @selector( onChangePlaybackPositionCommand: )]
with the associated method
- (MPRemoteCommandHandlerStatus) onChangePlaybackPositionCommand:
(MPChangePlaybackPositionCommandEvent *) event
{
NSLog(@"changePlaybackPosition to %f", event.positionTime);
return MPRemoteCommandHandlerStatusSuccess;
}
but the cursor is still not movable and the method is not called. I guess I still miss something
The New Way for iOS 12+ and Swift 4+
Following is an improved way of handling scrubbing in Remote Play Center:
// Handle remote events
func setupRemoteTransportControls() {
let commandCenter = MPRemoteCommandCenter.shared()
// Scrubber
commandCenter.changePlaybackPositionCommand.addTarget { [weak self](remoteEvent) -> MPRemoteCommandHandlerStatus in
guard let self = self else {return .commandFailed}
if let player = self.player {
let playerRate = player.rate
if let event = remoteEvent as? MPChangePlaybackPositionCommandEvent {
player.seek(to: CMTime(seconds: event.positionTime, preferredTimescale: CMTimeScale(1000)), completionHandler: { [weak self](success) in
guard let self = self else {return}
if success {
self.player?.rate = playerRate
}
})
return .success
}
}
return .commandFailed
}
// Register to receive events
UIApplication.shared.beginReceivingRemoteControlEvents()
}
In addition to implementing the callback, it seems that you would have to set the canBeControlledByScrubbing
property to true. Unfortunately, there is no public accessor to set it, so you would have to do it as follows (and won't be able to submit your app to the AppStore):
NSNumber *shouldScrub = [NSNumber numberWithBool:YES];
[[[MPRemoteCommandCenter sharedCommandCenter] changePlaybackPositionCommand]
performSelector:@selector(setCanBeControlledByScrubbing:) withObject:shouldScrub];
[[[MPRemoteCommandCenter sharedCommandCenter] changePlaybackPositionCommand]
addTarget:self
action:@selector(handleChangePlaybackPositionCommand:)];
If you do it like this, you will get the callback on your handleChangePlaybackPositionCommand:
method, taking an MPChangePlaybackPositionCommandEvent
as its only parameter.
If you do want to support older versions of iOS than 9.1, I'd suggest to check for the iOS version before executing the above code to prevent crashes (You can either do it using the new API introduced with iOS 8, or if you want to support iOS 7 and earlier as well, using something like
[[[UIDevice currentDevice] systemVersion] compare:@"9.1" options:NSNumericSearch] != NSOrderedAscending
I hope this helps :-)
As of 2020 with Swift 5, if we only use commandCenter.changePlaybackPositionCommand
it won't work, we also need to set metadata with MPMediaItemPropertyPlaybackDuration
for the player then we can use the slider.
Check this article from Apple: https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/creating_a_basic_video_player_ios_and_tvos/controlling_background_audio
Look at the section: Provide Display Metadata