使用MPRemoteCommandCenter为AVPlayer和AVAudioPlayer添加当前时间和持续时间的位置



在我的应用程序的屏幕上,我有一个用于音乐的AVAudioPlayer和一个用于视频的AVPlayer。用户可以交换不同的歌曲和视频,但一次只能播放一首。他们可以在avPlayer上播放audioPlayer或观看视频。

我有MPRemoteCommandCenter,当使用暂停/播放/关闭/倒带时,它对两者都很好。问题是我无法在锁定屏幕上显示当前时间或持续时间。我试过了,但没有说明代码应该放在哪里。

这就是我所尝试的,这样每次用户切换歌曲或视频时,我都有新项目的所有可用数据:

音频-

do {        
audioPlayer = try AVAudioPlayer(contentsOf: audioTrack)
audioPlayer?.delegate = self
audioPlayer?.prepareToPlay()
audioPlayer?.play()

setupNowPlayingForAudio()

} catch { 
}
func setupNowPlayingForAudio() {
guard let audioPlayer = audioplayer else { return }

var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = "My App Name"

nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = Float(audioPlayer.currentTime)
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = Float(audioPlayer.duration)
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = audioPlayer.rate
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

视频-

playerStatusObserver = player?.observe(.currentItem?.status, options: [.new, .old]) {
switch (player.status) {
case .readyToPlay:
player?.play() 
setupNowPlayingForVideo()
}
}
func setupNowPlayingForVideo() {
guard let player = player, let playerItem = player.currentItem else { return }

var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = "My App Name"

nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = playerItem.currentTime().seconds
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = playerItem.asset.duration.seconds
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

MPRemoteCommandCenter与AVAudioSession 一起设置在视图DidLoad中

我遵循了这个答案,它说你必须将它添加到任何暂停/播放/关闭/倒带按钮、滑块和任何听播放器播放/停止的观察者中。这是我做这件事的方法。这在锁屏上对我来说很好。

以下是我为AudioPlayer-使用的函数

do {        
audioPlayer = try AVAudioPlayer(contentsOf: audioTrack)
// ... 
audioPlayer?.play()
setupNowPlaying(musicPlayer: audioPlayer)

} catch { }
func audioPlayerPausePlayButton() {
// ...
setupNowPlaying(musicPlayer: audioPlayer)
}
func audioPlayerFastFowardAndRewindButton() {
// ... ff or rewind functions
setupNowPlaying(musicPlayer: audioPlayer)
}

以下是我为AVPlayer-使用的函数

playerStatusObserver = player?.observe(.currentItem?.status, options: [.new, .old]) { // ...
switch (player.status) {
case .readyToPlay:
// ... this should occur on the MainQueue
self?.player?.play()
self?.setupNowPlaying(videoPlayer: self?.player)
}
}
// .. I also added it to any other observers that listen to the player stopping
func videoPlayerPausePlayButton() {
// ...
setupNowPlaying(videoPlayer: player)         
}
func videoPlayerFastFowardAndRewindButton() {
// ...
player?.seek(to: whateverSeekTime) { [weak self](_) in
self?.setupNowPlaying(videoPlayer: self?.player)
}
}

CommandCenter的字典值显示在锁定屏幕上

func setupNowPlaying(musicPlayer: AVAudioPlayer? = nil, videoPlayer: AVPlayer? = nil) {

var nowPlayingInfo = [String : Any]()

// audio
if let musicPlayer = musicPlayer, let musicUrl = musicPlayer.url {

nowPlayingInfo[MPNowPlayingInfoPropertyAssetURL] = musicUrl
nowPlayingInfo[MPMediaItemPropertyTitle] = musicUrl.lastPathComponent
nowPlayingInfo[MPNowPlayingInfoPropertyMediaType] = MPNowPlayingInfoMediaType.audio.rawValue

let currentTime: TimeInterval = musicPlayer.currentTime
let musicCurrentTimeCMTime = CMTime(seconds: currentTime, preferredTimescale: 1000)
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(musicCurrentTimeCMTime)

let musicDuration: TimeInterval = musicPlayer.duration
let musicDurationCMTime = CMTime(seconds: musicDuration, preferredTimescale: 1000)
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds(musicDurationCMTime)

if musicPlayer.isPlaying {
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1
} else {
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 0
}
}

// video
if let videoPlayer = videoPlayer, let currentItem = videoPlayer.currentItem {

if let videoAsset = currentItem.asset as? AVURLAsset {
let videoUrl = videoAsset.url
nowPlayingInfo[MPNowPlayingInfoPropertyAssetURL] = videoUrl
nowPlayingInfo[MPMediaItemPropertyTitle] = videoUrl.lastPathComponent
nowPlayingInfo[MPNowPlayingInfoPropertyMediaType] = MPNowPlayingInfoMediaType.video.rawValue
}

if let videoDuration: CMTime = videoPlayer.currentItem?.duration {
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds(videoDuration)
}

let videoCurrentTime: CMTime = videoPlayer.currentTime()
let videoCurrentTimeAsSecs = CMTimeGetSeconds(videoCurrentTime)
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = videoCurrentTimeAsSecs

print("videoCurrentTimeAsSecs: ", videoCurrentTimeAsSecs)

if videoPlayer.isPlaying {
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1
} else {
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 0
}
}

nowPlayingInfo[MPMediaItemPropertyTitle] = "Your App Name"
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = false

MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

最新更新