I\'m working on an app that will play sound files. If I open apple music app, the slider let me moving between the song where I am.
Other apps like spotify
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 :-)
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
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
I have answered this here command center Scrubber on lock screen swift
Basically you just need the nowPlaying metadata then for each function you want you enable it and add a handler for it.
I realised that comments about this only being for Apple were wrong when I saw the Librivox app had a working scrubber.
There’s no API to support that—as you’ve noticed, the built-in Music app is the only one that gets to use it. If you’d like an addition to the API, your best option is to file an enhancement request.
update: looks like as of iOS 9.1 this may no longer be the case—see PatrickV’s answer.
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()
}