MPRemoteCommandCenter проигрывает трек одновременно несколько раз

У меня есть TableViewController и AudioPlayerViewController. У меня проблема с использованием MPRemoteCommandCenter. Например: в TableViewController я нажимаю на ячейку и перехожу к AudioPlayerViewController, затем блокирую устройство и управляю музыкой с помощью MPRemoteCommandCenter - все работает нормально. Но если я дальше разблокирую устройство, сначала вернусь в TableViewController, а потом снова перейду к AudioPlayerViewController и заблокирую устройства чтобы управлять музыкой на заблокированном экране и нажму кнопку воспроизведения/паузы, моя музыка будет воспроизводиться два раза одновременно. Если я повторю действие, моя музыка одновременно будет воспроизводиться три раза. И т.д ... Как это исправить?

код:

import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController, AVAudioPlayerDelegate, UIAlertViewDelegate {
    
    var audioPlayer: AVAudioPlayer!
    let musicOperation = OperationQueue()
    var timer: Timer?
    
    @IBOutlet weak var playButton: UIButton!
    @IBOutlet var timeElapsed: UILabel!
    @IBOutlet var timeDuration: UILabel!
    @IBOutlet weak var logo: UIImageView!
    @IBOutlet weak var slider: UISlider!
    @IBOutlet weak var volumeView: UIView!
    
    var index = 0
    var buttonIndex = 0
    
    var endOfChapterSleepTimer = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Table View Index
        buttonIndex = masterIndex
        
        musicOperation.maxConcurrentOperationCount = 1
        
        try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        
        UserDefaults.standard.set(index, forKey: "index")
        
        if index > 0 {

            let fileManager = FileManager.default
            let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
            
            if let documentDirectoryURL: NSURL = urls.first as NSURL? {
                
                let soundURL = documentDirectoryURL.appendingPathComponent("/\(masterIndex)/\(index).mp3")
                
                UserDefaults.standard.set(index, forKey: "\(masterIndex)")
                
                do {
                    
                    audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
                    audioPlayer.delegate = self
                    audioPlayer.prepareToPlay()
                    play(sender:AnyObject.self as AnyObject)
                    restorePlayerCurrentTime()
                    
                    setupMediaPlayerNotificationView()
                    lockScreen()
                    
                } catch {
                    
                }
            }
            
        } else {
            
            let url = Bundle.main.url(forResource: "\(masterIndex)0", withExtension: "m4a")!
            
            do {
                
                audioPlayer = try AVAudioPlayer(contentsOf: url)
                audioPlayer.delegate = self
                audioPlayer.prepareToPlay()
                play(sender:AnyObject.self as AnyObject)
                
                setupMediaPlayerNotificationView()
                lockScreen()
                
            } catch {
                
            }
        }
        
    }
    
    // MARK: - Audio player controller
    
    @IBAction func play(sender: AnyObject) {
        if !audioPlayer.isPlaying{
            audioPlayer.play()
            slider.maximumValue = Float(audioPlayer.duration)
            timer = Timer(timeInterval: 0.1, target: self, selector: #selector(self.updateTime), userInfo: nil, repeats: true)
            RunLoop.main.add(timer!, forMode: .commonModes)
            restorePlayerCurrentTime()
            playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
        } else {
            audioPlayer.pause()
            playButton.setImage(UIImage(named: "play.png"), for: UIControlState.normal)
            timer?.invalidate()
        }
    }
    
    @IBAction func fastForward(sender: AnyObject) {
        var time: TimeInterval = audioPlayer.currentTime
        time += 15.0 // Go Forward by 15 Seconds
        if time > audioPlayer.duration {
            audioPlayerDidFinishPlaying(audioPlayer, successfully: true)
        } else {
            audioPlayer.currentTime = time
            updateTime()
        }
    }
    
    @IBAction func fastBackward(sender: AnyObject) {
        var time: TimeInterval = audioPlayer.currentTime
        time -= 15.0 // Go Back by 15 Seconds
        if time < 0 {
            audioPlayer.currentTime = 0
            updateTime()
        } else {
            audioPlayer.currentTime = time
            updateTime()
        }
    }
    
    // MARK: - Audio player time
    
    private func restorePlayerCurrentTime() {
        let currentTimeFromUserDefaults : Double? = UserDefaults.standard.value(forKey: "currentTime\(masterIndex)\(index)") as! Double?
        if let currentTimeFromUserDefaultsValue = currentTimeFromUserDefaults {
            audioPlayer.currentTime = currentTimeFromUserDefaultsValue
            slider.value = Float.init(audioPlayer.currentTime)
        }
    }
    
    @objc func updateTime() {
        let currentTime = Int(audioPlayer.currentTime)
        let minutes = currentTime/60
        let seconds = currentTime - minutes * 60
        
        let durationTime = Int(audioPlayer.duration) - Int(audioPlayer.currentTime)
        let minutes1 = durationTime/60
        let seconds1 = durationTime - minutes1 * 60
        
        timeElapsed.text = NSString(format: "%02d:%02d", minutes,seconds) as String
        timeDuration.text = NSString(format: "-%02d:%02d", minutes1,seconds1) as String
        
        UserDefaults.standard.set(currentTime, forKey: "currentTime\(masterIndex)\(index)")
        UserDefaults.standard.set(durationTime, forKey: "durationTime\(masterIndex)\(index)")
        
        slider.value = Float.init(audioPlayer.currentTime)
    }
    
    func audioPlayerDidFinishPlaying(_ audioPlayer: AVAudioPlayer, successfully flag: Bool) {
        
        playButton.setImage(UIImage(named: "play.png"), for: UIControlState.normal)
        
        let currentTime = 0
        let durationTime = 0.1
        UserDefaults.standard.set(currentTime, forKey: "currentTime\(masterIndex)\(index)")
        UserDefaults.standard.set(durationTime, forKey: "durationTime\(masterIndex)\(index)")
        slider.value = Float.init(audioPlayer.currentTime)
        timer?.invalidate()
        
        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        let destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/\(masterIndex)/\(index+1).mp3"))
        
        if fileManager.fileExists(atPath: destinationURLForFile.path){
            
        
        index = index + 1
        viewDidLoad()
            
        } else {
            
        }
    }
    
    // MARK: - Audio player lock screen
    
    func lockScreen() {
        
        var albumArtwork : MPMediaItemArtwork!
        let image:UIImage = UIImage(named: "infoImage")!
        
        albumArtwork = MPMediaItemArtwork.init(boundsSize: image.size, requestHandler: { (size) -> UIImage in
            return image
        })
        
        let infotitle = "title"
        
        MPNowPlayingInfoCenter.default().nowPlayingInfo = [
            MPMediaItemPropertyArtist : "",
            MPMediaItemPropertyTitle : infotitle,
            MPMediaItemPropertyArtwork : albumArtwork,
            MPMediaItemPropertyAlbumTitle : "",
            MPNowPlayingInfoPropertyElapsedPlaybackTime : Int(audioPlayer.currentTime),
            MPMediaItemPropertyPlaybackDuration: Int(audioPlayer.duration)]
        
    }
    
    func setupMediaPlayerNotificationView()  {
        
        let commandCenter = MPRemoteCommandCenter.shared()
        
        commandCenter.playCommand.addTarget { event in
            self.audioPlayer.play()
            self.lockScreen()
            self.playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
            print("play")
            return .success
        }
        
        commandCenter.pauseCommand.addTarget { event in
            self.audioPlayer.pause()
            self.lockScreen()
            self.playButton.setImage(UIImage(named: "play.png"), for: UIControlState.normal)
            print("pause")
            return .success
        }
        
        commandCenter.skipBackwardCommand.preferredIntervals = [15]
        commandCenter.skipBackwardCommand.addTarget { event in
            self.fastBackward(sender: self)
            self.lockScreen()
            print("fastBackward")
            return .success
        }
        
        commandCenter.skipForwardCommand.preferredIntervals = [15]
        commandCenter.skipForwardCommand.addTarget { event in
            self.fastForward(sender: self)
            self.lockScreen()
            print("fastForward")
            return .success
        }
        
        commandCenter.changePlaybackPositionCommand.addTarget(self, action: #selector(self.changedThumbSlider(_:)))
        
    @objc func changedThumbSlider(_ event: MPChangePlaybackPositionCommandEvent) -> MPRemoteCommandHandlerStatus {
        let time = event.positionTime
        audioPlayer.currentTime = TimeInterval(time)
        self.lockScreen()
        return .success
    }
    
    // MARK: - Audio player slider
    
    @IBAction func slide(_ slider: UISlider) {
        musicOperation.cancelAllOperations()
        let operation = BlockOperation()
        audioPlayer.currentTime = TimeInterval(slider.value)
        self.lockScreen()
        musicOperation.addOperation(operation)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        audioPlayer.pause()
        timer?.invalidate()
        musicOperation.cancelAllOperations()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIView.setAnimationsEnabled(true)
        
        // Navigation Bar
        
        self.navigationController?.navigationBar.prefersLargeTitles = true
        self.navigationItem.largeTitleDisplayMode = .always
        self.navigationController?.navigationBar.shadowImage = UIImage()
        self.navigationController?.navigationBar.barTintColor = UIColor(red: 55/255, green: 60/255, blue: 65/255, alpha: 1.0)
        self.navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.navigationBar.tintColor = .white
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}

Ответы (0 шт):