Получение прогресса воспроизведения / времени для нескольких узлов AVAudioPlayerNode - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь создать приложение, которое воспроизводит несколько аудио (wav) файлов в разное время. Эти wav-файлы могут иметь разную длину, время начала и окончания. Я хочу получить прогресс воспроизведения во время воспроизведения звука.

Из всех различных учебных пособий и руководств, которые я видел, это довольно просто, когда вы просто проигрываете один аудиофайл, поскольку вы можете просто получить lastRenderTime из этого AVAudioPlayerNode, но в моем случае, Мне нужно иметь возможность поддерживать клипы 1+, начинающиеся и заканчивающиеся в разное (скорее всего, одновременное) время, поэтому я не могу использовать один AVAudioPlayerNode для получения lastRenderTime, поэтому мне нужно получить lastRenderTime от отличается AVAudioNode как выходной узел двигателя по умолчанию.

Я пытался это сделать, но в 1011 * lastRenderTime.

нет ясного 0 времени.

Я также пытался установить переменную класса / экземпляра на engine.outputNode.lastRenderTime непосредственно перед игрой, а затем использовать ее как своего рода опорную точку, чтобы определить, как долго что-то проигрывалось, но нет ясного времени 0 в outputNode lastRenderTime, так что это выглядит несколько неточно.

var engine = AVAudioEngine()
var mixer = AVAudioMixerNode()
var playerNodes = [AVAudioPlayerNode]()

func prepare() {
    engine.attach(mixer)
    engine.connect(mixer, to: engine.outputNode, format: nil)

    // Create playernode and add to playerNodes

    for node in playerNodes {
        engine.attach(node)
        engine.connect(node, to: mixer, format: nil)
    }

    try! engine.start()
}

func play() {
    for node in playerNodes {
        // schedule file/segment/buffer
        node.play(at: startTimeForNode)
    }
}

Если у меня есть 3 двухсекундных аудиофайла, которые начинаются через одну секунду после предыдущего (и воспроизводятся вместе), когда я нажимаю кнопку воспроизведения, я ожидаю точную выборку или миллисекунду с точным временем воспроизведения в целом, а не для каждого аудио файл. Я не уверен, где взять lastRenderTime или как использовать AVAudioTime таким образом, чтобы я мог получить время воспроизведения в реальном времени, пока воспроизводятся все клипы, но не для каждого клипа отдельно.

1 Ответ

0 голосов
/ 23 января 2019

Вы пробовали использовать таймер? Например (используя ваши узлы):

timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {[unowned self] timer in
                for node in playerNodes {
                    let nodeTime = node.lastRenderTime!
                    let playerTime = node.playerTime(forNodeTime: nodeTime)!
                    let secs = Double(playerTime.sampleTime) / playerTime.sampleRate
                    print(secs)
                }

Вот рабочее решение: https://gist.github.com/standinga/f79232adb15e1f867ad1637f47c61003

...