我有一个可以从iOS命令中心和锁定屏幕播放的视频播放器。当我在我的应用程序中切换播放/暂停按钮时,它应该通过更新MPRemoteCommandCenter
(nowPlayingInfo
)来更新命令中心(MPNowPlayingInfoCenter
)中的播放/暂停按钮。我不确定为什么它没有更新。
例如,如果我在我的应用程序中使用自定义按钮暂停视频,则命令中心仍会显示暂停按钮(意味着视频仍在播放,这是错误的。)
这是我更新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
发生变化时,我会调用此函数:
// 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()
}
}
有什么想法吗?
我找到了一个解决方案,但在我的情况下并不完美。所以在我的应用程序中我有2个视图控制器。我们称他们为FeedVC
和PlayerVC
。因此,FeedVC
有AVPlayer
个始终在播放但已静音的PlayerVC
。如果您点击其中一个,则会创建AVPlayer
并播放完整视频。 如果我在转到FeedVC
之前暂停PlayerVC
中的FeedVC
,那么"播放/暂停" NowPlayingInfoCenter中的按钮完美运行!
有没有办法让这项工作无需暂停elapsed time
中的视频?
另一个问题是FeedVC
如果我暂停"/text/text/text/" stripPrefix "/" stripSuffix "/"
中的玩家,则会继续计算。似乎如果正在播放多个播放器,则播放/暂停按钮和已用时间不正确。
答案 0 :(得分:7)
为nowPlayingInfo
设置词典时,您需要适当设置MPNowPlayingInfoPropertyPlaybackRate
值。 MPNowPlayingInfoCenter
期待1.0
(播放)或0.0
(不播放)值作为Double
对象中包含的NSNumber
。您可以在下面找到我在项目中设置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
。每当用户选择播放或暂停时,我都会调用setNowPlayingMediaWith(song:currentTime:)
来更新设备的控制台。
我会跟踪currentTime
(Double
)作为播放器的属性。如果传递currentTime
表示我们打算播放,那么请将MPNowPlayingInfoPropertyPlaybackRate
设置为1.0
并将MPNowPlayingInfoPropertyElapsedPlaybackTime
设置为currentTime
。这将设置当前开始在设备控制台中自动播放的时间。
同样,如果没有currentTime
通过,那么我们已停止或暂停。在这种情况下,我们将MPNowPlayingInfoPropertyPlaybackRate
设置为0.0
,我们不会包含MPNowPlayingInfoPropertyElapsedPlaybackTime
。
Download我的应用可以看到这一点。
编辑(回复评论)
“有没有办法让这项工作无需暂停FeedVC中的视频”
如果没有看到您的代码,很难给出明确的答案。在启动PlayerVC
媒体之前暂停任何正在进行的媒体是有意义的。
“经过的时间不断计算”
经过的时间将根据NSTimer
上的NowPlayingInfoCenter
属性倒计时。只有当计时器值达到您在MPMediaItemPropertyPlaybackDuration
中设置的值或更新MPNowPlayingInfoPropertyElapsedPlaybackTime
时,此计时器才会停止。
我的建议是写一个“清除”NowPlayingInfoCenter
的方法。此方法应设置将所有键值分别设置为0.0或nil。在PlayerVC
播放媒体之前,每次都要调用此“清除”方法。然后,一旦您从PlayerVC
进行游戏,请设置NowPlayingInfoCenter
键值,就像我在答案中粘贴的方法一样,为新播放媒体设置新值。