swiftavplayermpremotecommandcenter

MPRemoteCommandCenter play/pause Flashing when touched


i'm working on music player app that written in Swift, audio streams with AVPlayer and everything is fine

but when i tried to add MPRemoteCommandCenter to my app there was a lot of bug that i dont know even why this happend

link to video that describes my problem

AVPlayer Implemented like:

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
}

and for command center,

MPRemoteCommandCenter Implemented like:

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()
}

Solution

  • In addition to the code you've presented you might also have called the following somewhere in your app delegate:

    UIApplication.shared.beginReceivingRemoteControlEvents()
    

    Doing this in addition to using MPRemoteCommandCenter.shared() seems to cause a race condition.

    According to 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.

    Remove that method from your app delegate and you should be fine.