0

我有一个不断播放的主要 AVAudioPlayerNode。当主要玩家到达某个点时,还有其他玩家被放入队列并播放。这些 AVAudioPlayerNode 应该同步到毫秒。有时一次可以开始 4-10 件。

它是如何工作的 - 我lastRenderTime在需要启动所有预定播放器时存储主要播放器,然后启动所有需要的播放器 player.start(at: lastRenderTime)

通常,它运行良好,声音之间没有任何延迟。

但是,我在这种情况下得到了一些延迟:

  1. 在旧设备上运行(iPad 2、iPhone 5 等)
  2. 仅当应用程序启动后第一次有许多播放器时(例如在 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)
            }
        }
    }
}
4

0 回答 0