I have a video player that can play from the iOS command center and lock screen. When I toggle a play/pause button in my app, it should update the play/pause button in the command center (MPRemoteCommandCenter) by updating the nowPlayingInfo (MPNowPlayingInfoCenter). I'm not sure why it's not updating.
For example, if I pause the video with a custom button in my app, the command center still shows the pause button (meaning the video is still playing which is wrong.)
This is how I update the nowPlayingInfo:
func updateMPNowPlayingInforCenterMetadata() {
guard video != nil else {
nowPlayingInfoCenter.nowPlayingInfo = nil
return
}
var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()
let image: UIImage
if let placeholderLocalURL = video.placeholderLocalURL, let placeholderImage = UIImage(contentsOfFile: placeholderLocalURL.path) {
image = placeholderImage
} else {
image = UIImage()
}
let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { _ -> UIImage in
return image
})
nowPlayingInfo[MPMediaItemPropertyTitle] = video.title
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = video.creator?.name ?? " "
nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = Float(video.duration)
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = Float(currentTime) // CMTimeGetSeconds(player.currentItem!.currentTime())
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
nowPlayingInfo[MPNowPlayingInfoPropertyDefaultPlaybackRate] = player.rate
nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
if player.rate == 0.0 {
state = .paused
} else {
state = .playing
}
}
With KVO, when the player's rate changes, I call this function:
// MARK: - Key-Value Observing Method
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &assetPlaybackManagerKVOContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
} else if keyPath == #keyPath(AVPlayer.rate) {
updateMPNowPlayingInforCenterMetadata()
}
}
Any thoughts?
UPDATE
I found a solution though but not perfect in my case. So in my app I have 2 view controller's. Let's call them FeedVC and PlayerVC. So FeedVC has AVPlayer's that are always playing but are muted. If you click on one of them, then the PlayerVC is created and plays the full video. If I pause the AVPlayer's in FeedVC before going to PlayerVC then the "play/pause" button in the NowPlayingInfoCenter works perfectly!
Is there a way to make this work without having to pause the videos in the FeedVC?
Another issue is that the elapsed time keeps counting if I don't pause the players in the FeedVC. It seems that if multiple players are playing, the play/pause button and elapsed time are incorrect.
