我有一个不断播放的主要 AVAudioPlayerNode。当主要玩家到达某个点时,还有其他玩家被放入队列并播放。这些 AVAudioPlayerNode 应该同步到毫秒。有时一次可以开始 4-10 件。
它是如何工作的 - 我lastRenderTime
在需要启动所有预定播放器时存储主要播放器,然后启动所有需要的播放器
player.start(at: lastRenderTime)
通常,它运行良好,声音之间没有任何延迟。
但是,我在这种情况下得到了一些延迟:
- 在旧设备上运行(iPad 2、iPhone 5 等)
- 仅当应用程序启动后第一次有许多播放器时(例如在 iPhone 7 上,我在应用程序运行后同时运行 8 个播放器并且我听到声音之间的不同步),但所有播放器都在同一
player.start(at: lastRenderTime)
时间运行。
我与自定义并发队列异步运行的所有玩家操作。
花 3 天时间尝试解决此问题。我想要任何建议。
一些代码:这是我开始主要播放器的方式 -
self.scheduleBuffer(audioFileBuffer, at: nil, options: [], completionHandler: {
lastRenderTime = lastRenderTime + audioBufferLength //Schematic showing logic that after each loop I calculate current render time value.
if self.isStopPressed == false { //Run fileEndCompletion only when player seek to end.
fileEndCompletionHandler() //here is callback that running all scheduled players.
if loop { // Recursive play this file again.
self.playAudioBuffer(audioFileBuffer: audioFileBuffer, loop: loop, fileEndCompletionHandler: fileEndCompletionHandler)
}
}
})
运行所有预定播放器的代码示例。
AudioEnginePlayer.sharedInstance.audioQueue.async {
if !self.isPlaying {
self.volume = 1.0
self.audioFile.framePosition = frameCount.startingFrame
self.prepare(withFrameCount: frameCount.frameCount)
self.play(at: AudioEnginePlayer.sharedInstance.loopMsLastStartRenderTime) //Calculated lastRenderTime
}
self.scheduleSegment(self.audioFile, startingFrame: frameCount.startingFrame, frameCount: frameCount.frameCount, at: nil) {
//WARNING: COMPLETION HANDLER RUNNING EARLY THEN FILE IS COMPLETED
if self.isStopPressed == false { //Run fileEndCompletion only when player seek to end.
fileEndCompletionHandler()
if loop {
self.playAudioFile(loop: loop, startTime: 0, fileEndCompletionHandler: fileEndCompletionHandler)
}
}
}
}