Swift: 如何在中断时停止调用 scheduleBuffer 完成处理程序?
Swift: How to stop scheduleBuffer completion handler being called when interrupted?
我有一个 AVAudioPlayerNode,我正在使用以下内容安排大量缓冲区:
node.scheduleBuffer(buffer, at: nil, options: .interrupts, completionHandler: completeFunc)
但我遇到了一点问题。如果我播放另一个缓冲区中断当前正在播放的缓冲区,则缓冲区中断的完成处理程序仍在调用。我想这是有道理的,但我似乎无法找到一种方法来检查文件是否真正完成播放或是否被中断。我有办法做到这一点吗?
任何答案都会有所帮助!
您将需要一个在完成处理程序中引用并由中断代码切换的中断状态变量。下面是一些 shorthand 代码,它们对您如何循环缓冲区进行了一些假设:
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
}
我有一个 AVAudioPlayerNode,我正在使用以下内容安排大量缓冲区:
node.scheduleBuffer(buffer, at: nil, options: .interrupts, completionHandler: completeFunc)
但我遇到了一点问题。如果我播放另一个缓冲区中断当前正在播放的缓冲区,则缓冲区中断的完成处理程序仍在调用。我想这是有道理的,但我似乎无法找到一种方法来检查文件是否真正完成播放或是否被中断。我有办法做到这一点吗?
任何答案都会有所帮助!
您将需要一个在完成处理程序中引用并由中断代码切换的中断状态变量。下面是一些 shorthand 代码,它们对您如何循环缓冲区进行了一些假设:
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
}