在iOS命令中心中播放/暂停和已用时间没有正确更新

我有一个video播放器,可以从iOS的指挥中心和locking屏幕播放。 当我在我的应用中切换播放/暂停button时,它应该通过更新nowPlayingInfoMPNowPlayingInfoCenter )来更新命令中心( MPRemoteCommandCenter )中的播放/暂停button。 我不知道为什么它没有更新。

例如,如果我在应用程序中使用自定义button暂停video,则命令中心仍显示暂停button(表示video仍在播放,这是错误的)。

在这里输入图像说明

这是我如何更新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 } } 

使用KVO,当玩家的rate变化时,我称之为这个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() } } 

有什么想法吗?

UPDATE

我发现一个解决scheme,但在我的情况并不完美。 所以在我的应用程序,我有2视图控制器。 我们称之为FeedVCPlayerVC 。 所以FeedVCAVPlayer总是在播放,但是被静音。 如果您点击其中一个,则会创buildPlayerVC并播放完整的video。 如果在FeedVC之前暂停了FeedVCAVPlayer ,那么NowPlayingInfoCenter中的“播放/暂停”button就完美了!

有没有办法让这个工作,而不必暂停FeedVC的video?

另一个问题是,如果我不暂停FeedVC的播放器,那么elapsed time会继续计数。 看起来,如果多个玩家正在玩,播放/暂停button和经过的时间是不正确的。

当您为nowPlayingInfo设置字典时,您将需要适当地设置MPNowPlayingInfoPropertyPlaybackRate值。 MPNowPlayingInfoCenter期望1.0 (播放)或0.0 (不播放)作为包装在NSNumber对象中的Double 。 下面你会find我在我的项目中设置nowPlayingInfo的代码。

 func setNowPlayingMediaWith(song: SUSong, currentTime: Double?) { var playingInfo:[String: Any] = [:] if let title = song.title { playingInfo[MPMediaItemPropertyTitle] = title } if let songID = song.id { playingInfo[MPMediaItemPropertyPersistentID] = songID } if let artist = song.artist, let artistName = artist.name { playingInfo[MPMediaItemPropertyArtist] = artistName } if let album = song.album, let albumTitle = album.title { var artwork:MPMediaItemArtwork? = nil if let album = song.album, let artworkData = album.artwork { artwork = MPMediaItemArtwork(boundsSize: Constants.Library.Albums.thumbSize, requestHandler: { (size) -> UIImage in return UIImage(data: artworkData as Data)! }) } if artwork != nil { playingInfo[MPMediaItemPropertyArtwork] = artwork! } playingInfo[MPMediaItemPropertyAlbumTitle] = albumTitle } var rate:Double = 0.0 if let time = currentTime { playingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = time playingInfo[MPMediaItemPropertyPlaybackDuration] = song.duration rate = 1.0 } playingInfo[MPNowPlayingInfoPropertyPlaybackRate] = NSNumber(value: rate) playingInfo[MPNowPlayingInfoPropertyMediaType] = NSNumber(value: MPNowPlayingInfoMediaType.audio.rawValue) MPNowPlayingInfoCenter.default().nowPlayingInfo = playingInfo } 

在这个方法中,我传递了我的播放器目前已加载的song 。 每当用户select播放或暂停时,我都会调用setNowPlayingMediaWith(song:currentTime:)来更新设备的控制台。

我跟踪当前时间( Double )作为我的球员属性。 如果有一个currentTime意味着要播放,那么将MPNowPlayingInfoPropertyPlaybackRate设置为1.0 ,并将MPNowPlayingInfoPropertyElapsedPlaybackTime设置为currentTime 。 这将设置当前时间开始在设备的控制台中自动播放。

同样,如果没有currentTime通过,那么我们已经停止或暂停。 在这种情况下,我们将MPNowPlayingInfoPropertyPlaybackRate设置为0.0 ,我们不包括MPNowPlayingInfoPropertyElapsedPlaybackTime

下载我的应用程序,看看这个在行动。


编辑 (回答评论)

“有没有办法做到这一点,而不必暂停FeedVC中的video”

没有看到你的代码,很难给你一个明确的答案。 在启动您的PlayerVC媒体之前暂停任何正在进行的媒体是PlayerVC的。


“stream逝的时间不断”

经过的时间将根据NowPlayingInfoCenter上的NSTimer属性倒计时所用的时间。 只有在定时器值达到您在MPMediaItemPropertyPlaybackDuration设置的值时,或者在更新MPNowPlayingInfoPropertyElapsedPlaybackTime时,此定时器才会停止。

我的build议是写一个“清除” NowPlayingInfoCenter 。 这种方法应该设置将所有的键值分别设置为0.0或零。 在PlayerVC播放媒体之前,请每次调用此“清除”方法。 然后,一旦你从PlayerVC播放,设置NowPlayingInfoCenter键值就像你在我粘贴在我的答案的方法,以设置新的播放媒体的新值。