MPRemoteCommandCenter暂停/播放按钮创建更多AVAudioPlayer的sharedInstance?

问题描述 投票:0回答:1

[我的应用是使用AVAudioPlayer并具有Singleton模式和背景模式的音乐播放器。一切进展顺利,但是在我添加了用于锁定屏幕控制的命令中心后,发现了一种奇怪的行为。

当我在锁定屏幕上使用暂停/播放按钮时,有时可能会在后台创建额外的audioPlay共享实例,因为我发现重复打印的次数不止一次,例如在我的commandCenter.pauseCommand代码中。并且音频已暂停或继续播放,但是接下来在应用程序的VC中单击命令中心按钮和播放/暂停按钮均无效。这是一个多线程问题,我在Swift中是一个新手,非常感谢您提供有关如何查找/解决此问题的帮助或提示。

/ / /命令中心和MPMediaItemProperty的代码

func setUpLockedScreenControl() {
        // add control panel on locked screen
        let commandCenter = MPRemoteCommandCenter.shared()
        commandCenter.pauseCommand.isEnabled = true
        commandCenter.playCommand.isEnabled = true
        commandCenter.nextTrackCommand.isEnabled = true
        commandCenter.previousTrackCommand.isEnabled = true

        commandCenter.pauseCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            SongData.isPlaying = false
            AudioManager.sharedInstance.pauseMusic()

            self.updateLockedScreenPlayingInfo()
            print("pause music in command center")
            self.playOrPauseButton.setImage(UIImage(named: "Play"), for: .normal)
            self.playOrPauseButton.imageView?.contentMode = .scaleAspectFit

            return .success
        }

        commandCenter.playCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            SongData.isPlaying = true
            AudioManager.sharedInstance.playMusic()

            self.updateLockedScreenPlayingInfo()
            print("play music in command center")
            // add to continue update playing progress
            self.playOrPauseButton.setImage(UIImage(named: "Pause"), for: .normal)
            self.playOrPauseButton.imageView?.contentMode = .scaleAspectFit
            return .success
        }

        commandCenter.nextTrackCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            self.goNextSong()
            self.updateLockedScreenPlayingInfo()
            return .success
        }

        commandCenter.previousTrackCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            self.goPreviousSong()
            self.updateLockedScreenPlayingInfo()
            return .success
        }
    }

    func updateLockedScreenPlayingInfo() {

        var info  = Dictionary<String, Any>()
        info[MPMediaItemPropertyTitle] = SongData.songList[SongData.currentTrack].songName
        info[MPMediaItemPropertyAlbumTitle] = SongData.songList[SongData.currentTrack].albumName
        info[MPMediaItemPropertyArtist] = SongData.songList[SongData.currentTrack].artistName

        let image = SongData.songList[SongData.currentTrack].albumArtwork
        let artwork = MPMediaItemArtwork.init(boundsSize: image.size, requestHandler: { (size) -> UIImage in
                return image
        })

        info[MPMediaItemPropertyArtwork] = artwork
        info[MPMediaItemPropertyPlaybackDuration] = AudioManager.sharedInstance.audioPlayer.duration

        if SongData.isPlaying == true {
            let time = AudioManager.sharedInstance.audioPlayer.currentTime
            info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = time
            info[MPMediaItemPropertyPlaybackDuration] = AudioManager.sharedInstance.audioPlayer.duration
            info[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
            print("SongData.isPlaying == true, current time is:", time)
        } else {
            let time = AudioManager.sharedInstance.audioPlayer.currentTime
            info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = time
            info[MPMediaItemPropertyPlaybackDuration] = AudioManager.sharedInstance.audioPlayer.duration
            info[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
            print("SongData.isPlaying == false, current time is:", time)
        }

        MPNowPlayingInfoCenter.default().nowPlayingInfo = info
    }

/ / /这是发生错误时的控制台信息,在这种情况下,两次打印commandCenter.playCommand代码

Playback OK
Session is Active
2019-10-23 11:38:06.331882+0800 LocalMusicPlayer[12366:853141] Can't end BackgroundTask: no background task exists with identifier 22 (0x16), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.
SongData.isPlaying == true, current time is: 5.15344671201814
play music in command center
SongData.isPlaying == true, current time is: 5.155759637188209
play music in command center

/ / /在appDelegate中设置的背景模式,Can't end BackgroundTask仅在iOS 13上出现,我认为这可能是苹果方面的问题。

func applicationWillResignActive(_ application: UIApplication) {

    do {
        // set options as empty [] could show control panel in locked screen.
        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
        print("Playback OK")
        try AVAudioSession.sharedInstance().setActive(true)
        print("Session is Active")
     } catch {
        print(error)
     }
}

/ / / AudioPlayer控件的Audio Manager.swift

class AudioManager: NSObject, AVAudioPlayerDelegate {
    // use Singleton pattern keep the music continuing when user move through the App.
    static let sharedInstance = AudioManager()

    var audioPlayer: AVAudioPlayer!
    var playingSong: SongData?

    private override init() {
        super.init()  
    }
... ... 
}
swift avaudioplayer mpremotecommandcenter
1个回答
0
投票

问题很可能是您的setUpLockedScreenControl被意外调用了两次。因此,您将目标添加了两次,并且在锁定屏幕中的点击两次发送了它的消息。

© www.soinside.com 2019 - 2024. All rights reserved.