3

我有一个 AVAudioPlayerNode ,我正在使用以下内容安排大量缓冲区:

node.scheduleBuffer(buffer, at: nil, options: .interrupts, completionHandler: completeFunc)

但我有一点问题。如果我播放另一个缓冲区以中断当前正在播放的缓冲区,则仍在调用缓冲区被中断的完成处理程序。我想这是有道理的,但我似乎无法找到一种方法来检查文件是否真正完成播放或是否被中断。有没有办法我可以做到这一点?

任何答案都会有所帮助!

4

1 回答 1

2

您将需要一个在完成处理程序中引用并由中断代码切换的中断状态变量。这是一些速记代码,它们对您如何循环缓冲区进行了一些假设:

var node: AVAudioPlayerNode!
var loopingBuffers: [AVAudioPCMBuffer] = [buffer1, buffer2, buffer3]
var interruptBuffers = false // state variable to handle the interruption

func scheduleNextBuffer() {
    /* code to find the next buffer in the loopingBuffers queue */

    // assuming you have instantiated an AVAudioPlayerNode elsewhere
    node.scheduleBuffer(nextBuffer, completionHandler: bufferCompletion)
}

func bufferCompletion() {
    // check the state variable to make certain the completionHandler isn't being triggered by a scheduling interruption
    guard !interruptBuffers else { return }
    scheduleNextBuffer()
}

func interruptBuffers() {
    let newBuffers: [AVAudioPCMBuffer] = [buffer4, buffer5, buffer6]

    interruptBuffers = true

    node.scheduleBuffer(buffer4, at: nil, options: .interrupts, completionHandler: bufferCompletion)

    // cleanup your state and queue up your new buffers
    interruptBuffers = false
    loopingBuffers = newBuffers
}
于 2016-11-04T05:40:44.483 回答