Я использую несколько AVAudioPlayerNode
в AVAudioEngine
для микширования аудиофайлов для воспроизведения. Как только вся настройка завершена (движок подготовлен, запущен, запланированы сегменты аудиофайлов), я вызываю метод play()
на каждом узле проигрывателя, чтобы начать воспроизведение.
Поскольку для перебора всех узлов проигрывателя требуется время, я делаю снимок значения 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:)
на каждом узле проигрывателя после того, как запланировал аудиоданные.
Итак, мой вопрос: является ли наблюдаемая мной задержка проблемой буферизации? (Я имею в виду, например, должен ли я планировать более короткие сегменты), есть ли способ точно вычислить это значение, чтобы я мог настроить текущее вычисление времени воспроизведения?
Когда я устанавливаю ответвительный блок на один AVAudioPlayerNode
, блок вызывается с буфером длины 4410
, а частота дискретизации равна 44100 Hz
, это означает 0,1 с аудиоданных. Должен ли я полагаться на это при вычислении задержки?
Мне интересно, могу ли я доверять длине буфера, который я получаю в блоке ответвлений. В качестве альтернативы я пытаюсь вычислить общую задержку для своего аудиографа. Может ли кто-нибудь дать представление о том, как точно определить это значение?