Я использую несколько AVAudioPlayerNode
в AVAudioEngine
для смешивания аудиофайлов для воспроизведения.
После того, как все настройки выполнены (двигатель подготовлен, запущен, сегменты аудиофайлов запланированы), я вызываю play()
для каждого проигрывателя node, чтобы начать воспроизведение.
Поскольку для прохождения всех узлов проигрывателя требуется время, я беру снимок первого значения узлов lastRenderTime
и использую его для вычисления времени начала для метода узлов play(at:)
, чтобы синхронизировать воспроизведение между узлами:
let delay = 0.0
let startSampleTime = time.sampleTime // time is the snapshot value
let sampleRate = player.outputFormat(forBus: 0).sampleRate
let startTime = AVAudioTime(
sampleTime: startSampleTime + AVAudioFramePosition(delay * sampleRate),
atRate: sampleRate)
player.play(at: startTime)
Проблема заключается в текущем времени воспроизведения. Я использую это вычисление для получения значения, где seekTime
- это значение, которое я отслеживаю в случае, если мы ищем игрока. Он 0.0
в начале:
private var _currentTime: TimeInterval {
guard player.engine != nil,
let lastRenderTime = player.lastRenderTime,
lastRenderTime.isSampleTimeValid,
lastRenderTime.isHostTimeValid else {
return seekTime
}
let sampleRate = player.outputFormat(forBus: 0).sampleRate
let sampleTime = player.playerTime(forNodeTime: lastRenderTime)?.sampleTime ?? 0
if sampleTime > 0 && sampleRate != 0 {
return seekTime + (Double(sampleTime) / sampleRate)
}
return seekTime
}
Пока это дает относительно правильное значение, я могу слышать задержку между временем, в которое я играю, и первым звуком, который слышу. Поскольку lastRenderTime
сразу начинает продвигаться, как только я вызываю play(at:)
, и должно быть какое-то смещение времени обработки/буферизации.
Заметная задержка составляет около 100 мс, что очень велико, и мне нужно точное значение текущего времени для визуального рендеринга параллельно.
Это, вероятно, не имеет значения, но каждый аудиофайл является аудио AAC, и я планирую сегменты из них в игровых узлах, я не использую буферы напрямую.
Длина сегментов может варьироваться. Я также звоню prepare(withFrameCount:)
на каждом проигрывателе node после того, как у меня есть запланированные аудиоданные.
Итак, мой вопрос заключается в задержке, которую я наблюдаю, это проблема буферизации? (Я имею в виду, если бы я планировал более короткие сегменты, например), есть ли способ вычислить именно это значение, чтобы я мог настроить текущее время вычисления времени?
Когда я устанавливаю блок ответвлений на один AVAudioPlayerNode
, блок вызывается с буфером длины 4410
, а частота дискретизации 44100 Hz
, это означает 0,1 с аудиоданных. Должен ли я полагаться на это, чтобы вычислить задержку?
Мне интересно, могу ли я доверять длине буфера, который я получаю в блоке крана. В качестве альтернативы, я пытаюсь вычислить общую задержку для моего звукового графика. Может ли кто-нибудь дать представление о том, как точно определить это значение?