首页 > 解决方案 > 关闭音频播放?

问题描述

AVPlayer用来播放来自URL. 一切正常,但我不知道如何在不同的地方停止当前的音频播放我ViewController不想打电话player.pause()viewWillDisappear()因为我想在特定情况下停止它,但我仍然想在应用程序处于非活动状态时的背景。

当应用程序处于非活动状态时,我在 Xcode 应用程序设置中为后台播放打开了这个在此处输入图像描述

第二个问题:我可以改进这门课还是一切都好?

protocol AVPlayerServiceDelegate {
    func playerDidUpdateCurrentPlayingTime(_ time: CMTime)

}

class AVPlayerService {
    static let instance = AVPlayerService()

    private var audioPlayer: AVPlayer!
    public weak var delegate: AVPlayerServiceDelegate?

    func setupPlayer(forURL url: URL) {
        let playerItem: AVPlayerItem = AVPlayerItem(url: url)
        audioPlayer = AVPlayer(playerItem: playerItem)
        audioPlayer.play()

        audioPlayer.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.main) { (CMTime) -> Void in
            if self.audioPlayer.currentItem?.status == .readyToPlay {
                self.delegate?.playerDidUpdateCurrentPlayingTime(self.audioPlayer.currentTime())
            }
        }
    }

    var isPlaying: Bool {
        return audioPlayer.isPlaying
    }

    var isPaused: Bool {
        return audioPlayer.isPaused
    }

    var rate: Float {
        return audioPlayer.rate
    }

    func seek(to time: CMTime) {
        audioPlayer.seek(to: time)
    }

    func seekToBeginning() {
        audioPlayer.seek(to: CMTimeMake(value: 0, timescale: 1))
    }

    func replay() {
        audioPlayer.seek(to: CMTimeMake(value: 0, timescale: 1))
        audioPlayer.play()
    }

    func pause() {
        if let audioPlayer = audioPlayer {
            audioPlayer.pause()
        }
    }

    func play() {
        audioPlayer.play()
    }

    func freshInstance() {
        audioPlayer = AVPlayer()
    }

    var assetDuration: CMTime {
        get {
            return audioPlayer.currentItem!.asset.duration
        }
    }
    }

标签: iosiphonexcodeavfoundationswift4.2

解决方案


您需要一种机制来与player对象对话以便对其执行操作。
有很多方法可以解决它。

就个人而言,我会为播放器创建一个专门的类来处理实例化它、加载音频资源、播放、暂停等。
然后我要么让这个类成为一个单例,这样我就可以从任何地方访问它,或者注入它并将它传递给将使用它的其他类。

基本示例:

class MyAudioPlayer {
    static let shared = MyAudioPlayer()
    
    private var player: AVAudioPlayer?
    
    func load(_ url: URL) {
        player = try? AVAudioPlayer(contentsOf: url)
    }

    func play(url: URL) {
        load(url: url)
        player?.play()
    }

    func pause() {
        player?.pause()
    }

    func stop() {
        player?.stop()
    }     
}

从应用程序内的任何位置发送操作:

MyAudioPlayer.shared.play(someURL)
MyAudioPlayer.shared.pause()

至于在后台播放,即使应用程序未处于活动状态也需要(也许在AppDelegate

try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, 
                                                 with: .duckOthers)
try? AVAudioSession.sharedInstance().setActive(true)
UIApplication.shared.beginReceivingRemoteControlEvents()

推荐阅读