首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何监控AVAudioPlayerNode完成播放

如何监控AVAudioPlayerNode完成播放
EN

Stack Overflow用户
提问于 2021-08-31 17:49:04
回答 1查看 545关注 0票数 2

哦,嘿!我一直在努力弄清楚如何让我的AVAudioPlayerNode()在到达SwiftUI项目中的文件末尾时自动停止播放。正如您在下面看到的,我的音频文件不是通过AVAudioEngine,而是AVAudioPlayer有一个audioPlayerDidFinishPlaying函数,这很好。但是,对于使用play函数遍历引擎的音频文件,没有类似的内容,我也不知道如何使它的行为类似。

我试过建造这样的东西

代码语言:javascript
复制
    func audioPlayerDidFinishPlaying2(_ player: AVAudioPlayerNode, successfully flag: Bool) {
        if flag {
            isPlaying = false
            print("Playback Engine Stopped")
        }
    }

但这看上去什么都没做。

通过调用stopPlayback2()手动停止引擎的回放很好。

我打电话给引擎播放器

代码语言:javascript
复制
do {
    try self.audioPlayer.play(self.audioURL)
  }
    catch let error as NSError {
      print(error.localizedDescription)
  }

我看过其他的,所以这里和这里的帖子,但这两个解决方案都不适合我。如果您有任何建议,我将非常感谢您的意见!谢谢!!

AudioPlayer.swift

代码语言:javascript
复制
class AudioPlayer: NSObject, ObservableObject, AVAudioPlayerDelegate {
    
    let objectWillChange = PassthroughSubject<AudioPlayer, Never>()
    var isPlaying = false {
        didSet {
            objectWillChange.send(self)
        }
    }

    
    var audioPlayer: AVAudioPlayer!
    
    func startPlayback (audio: URL) {

        let playbackSession = AVAudioSession.sharedInstance()
        
        do {
            try playbackSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
        } catch {
            print("Playing over the device's speakers failed")
        }
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: audio)
            audioPlayer.delegate = self
            audioPlayer.play()
            isPlaying = true
        } catch {
            print("Playback failed.")
        }
    }
    
    func stopPlayback() {
        
        audioPlayer.stop()
        isPlaying = false
        
    }
    
    func stopPlayback2() {
        engine.stop()
        isPlaying = false
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if flag {
            isPlaying = false
            print("Playback Stopped")
        }
    }

    let engine = AVAudioEngine()
    let speedControl = AVAudioUnitVarispeed()
    let pitchControl = AVAudioUnitTimePitch()
    
    func play(_ url: URL) throws {
        let file = try! AVAudioFile(forReading: url)

        let avPlayer = AVAudioPlayerNode()

        engine.attach(avPlayer)
        engine.attach(pitchControl)
        engine.attach(speedControl)

        engine.connect(avPlayer, to: speedControl, format: nil)
        engine.connect(speedControl, to: pitchControl, format: nil)
        engine.connect(pitchControl, to: engine.mainMixerNode, format: nil)

        avPlayer.scheduleFile(file, at: nil)

        isPlaying = true
        try engine.start()
        avPlayer.play()
    }
    ```


  [1]: https://stackoverflow.com/questions/34238432/avaudioengine-avaudioplayernode-didfinish-method-like-avaudioplayer
  [2]: https://stackoverflow.com/questions/59080708/calling-stop-on-avaudioplayernode-after-finished-playing-causes-crash
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-31 17:54:18

与其使用avPlayer.scheduleFile(file, at: nil),不如使用带有完成处理程序的方法的形式:

代码语言:javascript
复制
avPlayer.scheduleFile(file, at: nil) {
    //call your completion function here
    print("Done playing")
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69003265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档