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

Posted

技术标签:

【中文标题】使用 MPRemoteCommandCenter 为 AVPlayer 和 AVAudioPlayer 添加当前时间和持续时间的位置【英文标题】:Where to Add Current Time and Duration Time For AVPlayer and AVAudioPlayer using MPRemoteCommandCenter 【发布时间】:2022-01-10 12:04:44 【问题描述】:

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

我的 MPRemoteCommandCenter 在使用暂停/播放/ff/倒带时都可以正常工作。问题是我无法在锁定屏幕上显示当前时间或持续时间。我试过this,但没有说明将代码放在哪里。

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

音频-

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 一起在 viewDidLoad 中设置

【问题讨论】:

【参考方案1】:

我关注了这个answer,它说你必须将它添加到任何暂停/播放/ff/倒带按钮、滑块和任何监听播放器播放/停止的观察者。这是我的做法。这在锁定屏幕上对我来说很好。

这里是我为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

【讨论】:

以上是关于使用 MPRemoteCommandCenter 为 AVPlayer 和 AVAudioPlayer 添加当前时间和持续时间的位置的主要内容,如果未能解决你的问题,请参考以下文章

使用 MPRemoteCommandCenter 时未调用播放/暂停回调

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

在范围内找不到 MPRemoteCommandCenter

如何从 MPRemoteCommandCenter 禁用所有 MPRemoteCommand 对象

iOS 13+ 应用程序的 AVAudioPlayer AVPlayer AVQueuePlayer MPMusicPlayerController MPRemoteCommandCenter MPN

是否可以检测音乐控件