Ios 为什么Swift AVAudioPlayer在MPRemoteCommandCenter播放命令后不更改状态?

Ios 为什么Swift AVAudioPlayer在MPRemoteCommandCenter播放命令后不更改状态?,ios,swift,avaudioplayer,mpremotecommandcenter,Ios,Swift,Avaudioplayer,Mpremotecommandcenter,这方面的环境是iOS 13.6和Swift 5。我有一个非常简单的应用程序,可以在前台或后台成功地播放MP3文件。我添加了MPRemoteCommandCenter播放和暂停命令处理程序。我在前台播放声音文件,然后暂停 当我从锁屏点击播放按钮时,我的代码调用audioPlayer.play(),它返回true。我听到声音再次开始播放,但播放机的当前时间没有提前。之后,锁定屏幕上的播放和暂停按钮将不起任何作用。当我再次将应用程序置于前台时,“播放”按钮将从我进入锁定屏幕之前的位置播放 这是我的Au

这方面的环境是iOS 13.6和Swift 5。我有一个非常简单的应用程序,可以在前台或后台成功地播放MP3文件。我添加了MPRemoteCommandCenter播放和暂停命令处理程序。我在前台播放声音文件,然后暂停

当我从锁屏点击播放按钮时,我的代码调用audioPlayer.play(),它返回true。我听到声音再次开始播放,但播放机的当前时间没有提前。之后,锁定屏幕上的播放和暂停按钮将不起任何作用。当我再次将应用程序置于前台时,“播放”按钮将从我进入锁定屏幕之前的位置播放

这是我的AudioPlayer课程:

import AVFoundation
import MediaPlayer

class AudioPlayer: RemoteAudioCommandDelegate {
    
    var audioPlayer = AVAudioPlayer()
    
    let remoteCommandHandler = RemoteAudioCommandHandler()
    
    var timer:Timer!

    func play(title: String) {
        let path = Bundle.main.path(forResource: title, ofType: "mp3")!
        let url = URL(fileURLWithPath: path)
            
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
            try AVAudioSession.sharedInstance().setActive(true)

            audioPlayer =  try AVAudioPlayer(contentsOf: url)
            
            remoteCommandHandler.delegate = self
            remoteCommandHandler.enableDisableRemoteCommands(true)
            
            timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateNowPlayingInfo), userInfo: nil, repeats: true)
        } catch let error as NSError {
            print("error = \(error)")
        }
    }
    
    func play() {
        print ("audioPlayer.play() returned \(audioPlayer.play())")
    }
    
    func pause() {
        audioPlayer.pause()
    }
    
    func stop() {
        audioPlayer.stop()
    }
    
    func currentTime() -> TimeInterval {
        return audioPlayer.currentTime
    }
    
    func setCurrentTime(_ time:TimeInterval) {
        audioPlayer.currentTime = time
    }

    @objc func updateNowPlayingInfo() {
        // Hard-code the nowPlayingInfo since this is a simple test app

        var nowPlayingDict =
            [MPMediaItemPropertyTitle: "Tin Man",
             MPMediaItemPropertyAlbumTitle: "The Complete Greatest Hits",
             MPMediaItemPropertyAlbumTrackNumber: NSNumber(value: UInt(10) as UInt),
             MPMediaItemPropertyArtist: "America",
             MPMediaItemPropertyPlaybackDuration: 208,
             MPNowPlayingInfoPropertyPlaybackRate: NSNumber(value: 1.0 as Float)] as [String : Any]
        
            nowPlayingDict[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: audioPlayer.currentTime as Double)
        
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingDict
    }
}
以下是我的RemoteCommandHandler类:

import Foundation
import MediaPlayer

protocol RemoteAudioCommandDelegate: class {
    func play()
    func pause()
}

class RemoteAudioCommandHandler: NSObject {
    weak var delegate: RemoteAudioCommandDelegate?
    
    var remoteCommandCenter = MPRemoteCommandCenter.shared()

    var playTarget: Any? = nil
    var pauseTarget: Any? = nil
    
    func enableDisableRemoteCommands(_ enabled: Bool) {
        print("Called with enabled = \(enabled)")
        
        remoteCommandCenter.playCommand.isEnabled = enabled
        remoteCommandCenter.pauseCommand.isEnabled = enabled
        
        if enabled {
            addRemoteCommandHandlers()
        } else {
            removeRemoteCommandHandlers()
        }
    }
    
    fileprivate func addRemoteCommandHandlers() {
        print( "Entered")
        
        if playTarget == nil {
            print( "Adding playTarget")
            playTarget = remoteCommandCenter.playCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
                print("addRemoteCommandHandlers calling delegate play")
                self.delegate?.play()
                return .success
            }
        }
        
        if pauseTarget == nil {
            print( "Adding pauseTarget")
            pauseTarget = remoteCommandCenter.pauseCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
                print("addRemoteCommandHandlers calling delegate pause")
                self.delegate?.pause()
                return .success
            }
        }

    }
    
    fileprivate func removeRemoteCommandHandlers() {
        print( "Entered")
        
        if playTarget != nil {
            print( "Removing playTarget")
            remoteCommandCenter.playCommand.removeTarget(playTarget)
            playTarget = nil
        }
        
        if pauseTarget != nil {
            print( "Removing pauseTarget")
            remoteCommandCenter.pauseCommand.removeTarget(pauseTarget)
            pauseTarget = nil
        }
    }

}
我很乐意提供更多需要的信息,因为我不明白为什么这个相对简单的代码(在我看来)不起作用


非常感谢您的帮助

在进一步调试之后,我发现AVAudioPlayer开始播放锁屏上的声音,但不久又停止了

我通过添加一个计时器来缓解这个问题。计时器检查用户的最后一个命令是否已播放,但声音未播放。当用户选择暂停或歌曲在自然结束时停止播放时,我也会更改状态


我仍然无法找到解决此问题的实际方法。

经过进一步调试后,我发现AVAudioPlayer开始播放锁屏上的声音,但不久又停止播放

我通过添加一个计时器来缓解这个问题。计时器检查用户的最后一个命令是否已播放,但声音未播放。当用户选择暂停或歌曲在自然结束时停止播放时,我也会更改状态

我仍然无法找到解决这个问题的实际方法