使用AVAudioEngine重复播放音频文件

5

我正在使用Swift和Xcode 6开发iOS应用程序。我想使用AVAudioEngine播放音频文件,到目前为止一切都很好。但是如何在不停止的情况下播放它?我的意思是当它播放结束后立即重新开始。

这是我的代码:

/*==================== CONFIGURATES THE AVAUDIOENGINE ===========*/
    audioEngine.reset() //Resets any previous configuration on AudioEngine

    let audioPlayerNode = AVAudioPlayerNode() //The node that will play the actual sound
    audioEngine.attachNode(audioPlayerNode) //Attachs the node to the audioengine

    audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil) //Connects the applause playback node to the sound output
    audioPlayerNode.scheduleFile(applause.applauseFile, atTime: nil, completionHandler: nil)

    audioEngine.startAndReturnError(nil)
    audioPlayerNode.play() //Plays the sound

在告诉我应该使用AVAudioPlayer之前,请注意,我不能这样做,因为后面我必须使用一些效果并同时重复播放三个音频文件。

2个回答

9

我在另一个问题中找到了解决方案,该问题由@CarveDrone提出并自动回答,因此我只是复制了他使用的代码:

class aboutViewController: UIViewController {


    var audioEngine: AVAudioEngine = AVAudioEngine()
    var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    override func viewDidLoad() {
        super.viewDidLoad()

        let filePath: String = NSBundle.mainBundle().pathForResource("chimes", ofType: "wav")!
        println("\(filePath)")
        let fileURL: NSURL = NSURL(fileURLWithPath: filePath)!
        let audioFile = AVAudioFile(forReading: fileURL, error: nil)
        let audioFormat = audioFile.processingFormat
        let audioFrameCount = UInt32(audioFile.length)
        let audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: audioFrameCount)
        audioFile.readIntoBuffer(audioFileBuffer, error: nil)

        var mainMixer = audioEngine.mainMixerNode
        audioEngine.attachNode(audioFilePlayer)
        audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer.format)
        audioEngine.startAndReturnError(nil)

        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(audioFileBuffer, atTime: nil, options:.Loops, completionHandler: nil)
    }

你需要改变的唯一事项是filePath常量。这里是原始答案的链接:Having AVAudioEngine repeat a sound


请注意,将长文件读入缓冲区需要很长时间才能加载。scheduleFile方法可以高效地将文件流式传输到播放器中,并立即开始播放。不幸的是,它不能循环播放。 - iamjustaprogrammer
嗯,我刚把这段代码翻译成了Swift 5,但是控制台却没有任何输出,而且出现了几个“kAudioUnitErr_TooManyFramesToProcess”的错误提示... - Nicolas Miari

6

Swift 5, thanks at @Guillermo Barreiro

    var audioEngine: AVAudioEngine = AVAudioEngine()
    var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    override func viewDidLoad() {
        super. viewDidLoad()

        guard let filePath: String = Bundle.main.path(forResource: "chimes", ofType: "wav") else{ return }
        print("\(filePath)")
        let fileURL: URL = URL(fileURLWithPath: filePath)
        guard let audioFile = try? AVAudioFile(forReading: fileURL) else{ return }

        let audioFormat = audioFile.processingFormat
        let audioFrameCount = UInt32(audioFile.length)
        guard let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount)  else{ return }
        do{
            try audioFile.read(into: audioFileBuffer)
        } catch{
            print("over")
        }
        let mainMixer = audioEngine.mainMixerNode
        audioEngine.attach(audioFilePlayer)
        audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer.format)
        try? audioEngine.start()
        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(audioFileBuffer, at: nil, options:AVAudioPlayerNodeBufferOptions.loops)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接