AVAudioPlayer продолжает «играть» после паузы с помощью командного центра - PullRequest
0 голосов
/ 08 апреля 2020

Я настраиваю свое приложение iOS для воспроизведения файлов .mp3 и разрешаю управление из командного центра. Тем не менее, я столкнулся с очень странной проблемой с моим AVAudioPlayer. Я установил обработчик для события переключения воспроизведения / паузы, но когда я приостанавливаю проигрыватель, кажется, что он продолжает «играть» в фоновом режиме. Если я подожду несколько секунд, а затем нажму кнопку воспроизведения, он будет перемещаться вперед по дорожке, как если бы он молча воспроизводился во время паузы.

Кроме того, я настроил функцию поиска, которая устанавливает currentTime игрок, но когда я нажимаю паузу, он возвращается к тому месту, где он был изначально в файле.

Я полностью теряюсь в том, почему это происходит в любом случае. Единственное, что я подозреваю, это то, что я неправильно настраиваю ни свой плеер, ни пульты управления транспортом.

Я настроил свой проект так, чтобы одноэлементный SoundManager обрабатывал аудиофайлы, которые в данный момент находятся в очереди, и предоставляет функции для управления аудио. Когда вызывается playTrack, он устанавливает новый экземпляр AVAudioPlayer с файлом в заданной позиции, а затем начинает воспроизведение.

Код ниже (без удаления ненужных методов):


import Foundation
import AVFoundation
import MediaPlayer

open class SoundManager {
    private var session = AVAudioSession.sharedInstance()
    private var player: AVAudioPlayer?
    private var trackList: [String]
    private var currentPosition: Int

    static let shared = SoundManager()

    private init() {
        try? session.setCategory(.playback)
        trackList = [String]()
        currentPosition = 0
        setupRemoteTransportControls() // This method hooks into the MPRemoteCommandCenter and adds targets
    }

    func setupRemoteTransportControls() {
        // Get the shared MPRemoteCommandCenter
        let commandCenter = MPRemoteCommandCenter.shared()


        // Add handler for Play Command
        commandCenter.playCommand.addTarget { [unowned self] event in
            if let player = self.player {
                if !player.isPlaying {
                    self.player?.play()
                    return .success
                }
                return .commandFailed
            }
            else{
                return .commandFailed
            }
        }

        // Add handler for Pause Command
        commandCenter.togglePlayPauseCommand.addTarget { [unowned self] event in
            if let player = self.player {
                if player.isPlaying {
                    self.player?.pause()
                    return .success
                }

                return .commandFailed
            }
            else {
                return .commandFailed
            }
        }


        // Seek
        commandCenter.changePlaybackPositionCommand.addTarget{ [unowned self] event in
            if let changePlaybackPositionCommandEvent = event as? MPChangePlaybackPositionCommandEvent {
                let time = changePlaybackPositionCommandEvent.positionTime
                self.seek(to: time)

                return .success
            }

            return .commandFailed
        }
    }

    func playTrack(atPosition: Int = 0){
        self.player?.delegate = nil
        self.player?.stop()

        let fileName = trackList[atPosition]
        let path = Bundle.main.path(forResource: fileName, ofType: "mp3")!
        let url = URL(fileURLWithPath: path)

        try? session.setActive(true)
        self.player = try? AVAudioPlayer(contentsOf: url)
        self.player?.prepareToPlay()
        self.player?.play()

        refreshNowPlaying()
    }

    func refreshNowPlaying() {
        // Code removed, this just updates metadata on the lock screen
    }

    func addToTrackList(files: [String]) {
        trackList.append(contentsOf: files)
    }
}

...