MPRemoteCommandCenter play/pause 触摸时闪烁

MPRemoteCommandCenter play/pause Flashing when touched

我正在开发用 Swift 编写的音乐播放器应用程序,音频流 AVPlayer 一切正常

但是当我尝试将 MPRemoteCommandCenter 添加到我的应用程序时出现了很多错误,我什至不知道为什么会这样

link to video that describes my problem

AVPlayer 实现如下:

func setupPlayer() {
    let item = AVPlayerItem(url: musicURL)
    self.player = AVPlayer.init(playerItem: item)
    self.player.play()
    self.player.volume = 1
    self.player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.main, using: { (time) in
        if self.player.currentItem?.status == .readyToPlay {
            self.reloadNowPlayingInfo()
            let currentTime = self.player.currentTime().seconds
            self.playingTime.text = currentTime.getTimeString()
            self.playerSlider.value = currentTime/duration
        }
    })
}

func reloadNowPlayingInfo() {
    var info = [String : Any]()
    info[MPMediaItemPropertyTitle] = self.titleText
    info[MPMediaItemPropertyArtwork] = MPMediaItemArtwork.init("some image")
    info[MPMediaItemPropertyPlaybackDuration] = seconds
    info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentSecs
    info[MPMediaItemPropertyArtist] = "Artist name"
    MPNowPlayingInfoCenter.default().nowPlayingInfo = info
}

对于指挥中心,

MPRemoteCommandCenter 实现方式如下:

func setupCommandCenter() {
    let commandCenter = MPRemoteCommandCenter.shared()
    commandCenter.playCommand.isEnabled = true
    commandCenter.pauseCommand.isEnabled = true
    commandCenter.playCommand.addTarget(self, action: #selector(self.playCommand(_:)))
    commandCenter.pauseCommand.addTarget(self, action: #selector(self.pauseCommand(_:)))
}


@objc func playCenter(_ action: MPRemoteCommandEvent) {
    self.state = .play
    self.playBtn.setBackgroundImage("some image"), for: .normal)
    self.player.play()
    self.fetchTracks()
}
@objc func pauseCenter(_ action: MPRemoteCommandEvent) {
    self.state = .pause
    self.playBtn.setBackgroundImage("some image"), for: .normal)
    self.player.pause()
    self.fetchTracks()
}

除了您提供的代码之外,您可能还在应用程序委托中的某处调用了以下代码:

UIApplication.shared.beginReceivingRemoteControlEvents()

除了使用 MPRemoteCommandCenter.shared() 之外还执行此操作似乎会导致竞争条件。

根据Apple's documentation

In iOS 7.1 and later, use the shared MPRemoteCommandCenter object to register for remote control events. You do not need to call this method when using the shared command center object.

This method starts the delivery of remote control events using the responder chain.

从您的应用委托中删除该方法,您应该没问题。

如果您在代码中添加 2 个观察者以接收玩家通知。您可能会在播放器锁定屏幕中看到滞后或跳转。

避免添加观察者和一次目标。

commandCenter.playCommand.addTarget(self, action: #selector(self.playCommand(_:)))

只有一次。当你不想要时删除它