I am developing a music player that plays music in the background.
The application has integration with both Spotify and Apple music, the user will authenticate only in one of the services.
At the moment, I can play music in the app and in the background with both services. I was also able to install MPNowPlayingInfoCenter , and it displays the correct information, but play / pause, next track and previous tracks only work when the user authenticates with Spotify.
MPNowPlayingInfoCenter Shows Music Information
When a user synchronizes with the Apple Music service and tries to use any commands, the application cannot receive notifications, instead it seems that the Apple Music application is processing it, thus playing the next song on the Apple Music Playlist instead of the playlist of my application.
I use AVPlayer to play music when syncing with Apple Music and SPTAudioStreamingController when syncing with Spotify.
I also checked the requirements suggested by the mat on this issue: xcode - information about MPNowPlayingInfoCenter is not displayed on iOS 8
Here is the Media Center installation code:
- (void)setMediaCenterinfoForPlayer:(id)player { SPTAudioStreamingController *spotifyPlayer; AVPlayer *localPlayer; NSMutableDictionary *trackInfo = [[NSMutableDictionary alloc] initWithDictionary: @{ MPMediaItemPropertyTitle: self.currentTrack.name, MPMediaItemPropertyArtist: ((SPTArtist *)self.currentTrack.artists[0]).name, MPMediaItemPropertyAlbumTitle : self.currentTrack.album.name, MPNowPlayingInfoPropertyPlaybackRate: @(1.0) }]; if ([player isKindOfClass:[SPTAudioStreamingController class]]) { spotifyPlayer = (SPTAudioStreamingController *)player; [trackInfo setObject:[NSNumber numberWithFloat:spotifyPlayer.currentPlaybackPosition] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; [trackInfo setObject:[NSNumber numberWithFloat:spotifyPlayer.currentTrackDuration] forKey:MPMediaItemPropertyPlaybackDuration]; } else { localPlayer = (AVPlayer *)player; NSTimeInterval playbackTime = [self currentPlaybackTimeForPlayer:player]; [trackInfo setObject:@(playbackTime) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; [trackInfo setObject:@(CMTimeGetSeconds(localPlayer.currentItem.asset.duration)) forKey:MPMediaItemPropertyPlaybackDuration]; } [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = trackInfo; [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; Class playingInfoCenter = NSClassFromString(@"MPNowPlayingInfoCenter"); if (playingInfoCenter) { [self albumURLCoverForCurrentTrackWithBlock:^(UIImage *albumImage) { MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:albumImage]; [trackInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork]; [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:trackInfo]; }]; } }
Here is the code for handling the events:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event { if (event.type == UIEventTypeRemoteControl) { MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter]; NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo]; [playingInfo setObject:[NSNumber numberWithFloat:[AudioPlayerManager sharedInstance].spotifyPlayer.currentPlaybackPosition] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; center.nowPlayingInfo = playingInfo; if (event.subtype == UIEventSubtypeRemoteControlPlay) { [[AudioPlayerManager sharedInstance] playTrack]; } else if (event.subtype == UIEventSubtypeRemoteControlPause) { [[AudioPlayerManager sharedInstance] pauseTrack]; } else if (event.subtype == UIEventSubtypeRemoteControlPreviousTrack) { [[AudioPlayerManager sharedInstance] previousTrack]; } else if (event.subtype == UIEventSubtypeRemoteControlNextTrack) { [[AudioPlayerManager sharedInstance] nextTrack]; } [[NSNotificationCenter defaultCenter] postNotificationName:kEventTypeRemoteControlUpdateState object:self]; } }
Hope someone can tell me a way to solve this situation. Thanks!