0

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

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

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

声音的-

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 中设置

4

1 回答 1

0

我按照这个答案说你必须将它添加到任何暂停/播放/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
}
于 2021-12-06T01:36:15.357 回答