AVAudioEngine ищет время песни

Я играю песню с помощью AVAudioPlayerNode и пытаюсь контролировать ее время с помощью UISlider, но не могу понять, как искать время с помощью AVAUdioEngine.


person luciansvnc    schedule 29.04.2015    source источник
comment
Я ждал ответа на этот вопрос несколько месяцев и все откладывал. Я знаю, что это включает в себя получение lastRenderTime вашего узла игрока и вычитание или добавление времени из этого. Однако заставить его воспроизвести из того времени - сложная часть.   -  person Paul Lehn    schedule 06.05.2015


Ответы (2)


После МНОГО проб и ошибок я думаю, что наконец понял это.

Сначала вам нужно рассчитать частоту дискретизации вашего файла. Для этого получите время последнего рендеринга вашего AudioNode:

var nodetime: AVAudioTime  = self.playerNode.lastRenderTime
var playerTime: AVAudioTime = self.playerNode.playerTimeForNodeTime(nodetime)
var sampleRate = playerTime.sampleRate

Затем умножьте частоту дискретизации на новое время в секундах. Это даст вам точный кадр песни, с которого вы хотите запустить проигрыватель:

var newsampletime = AVAudioFramePosition(sampleRate * Double(Slider.value))

Далее вы захотите подсчитать количество кадров, оставшихся в аудиофайле:

var length = Float(songDuration!) - Slider.value
var framestoplay = AVAudioFrameCount(Float(playerTime.sampleRate) * length)

Наконец, остановите свой узел, запланируйте новый сегмент аудио и снова запустите свой узел!

playerNode.stop()

if framestoplay > 1000 {
   playerNode.scheduleSegment(audioFile, startingFrame: newsampletime, frameCount: framestoplay, atTime: nil,completionHandler: nil)
}

playerNode.play()

Если вам нужны дополнительные пояснения, я написал краткое руководство здесь: http://swiftexplained.com/?p=9

person Paul Lehn    schedule 07.05.2015

Для будущих читателей, вероятно, лучше получить частоту дискретизации как:

playerNode.outputFormat(forBus: 0).sampleRate

Также будьте осторожны при преобразовании в AVAudioFramePosition, так как это целое число, а частота дискретизации — двойная. Без округления результата вы можете получить нежелательные результаты.

P.S. Приведенный выше ответ предполагает, что воспроизводимый файл имеет ту же частоту дискретизации, что и выходной формат проигрывателя, что может быть правдой, а может и нет.

person hhanesand    schedule 27.10.2017
comment
Я попробовал приведенный выше ответ, и он не работает для меня. Я печатаю currentTime до и после функции, и это показывает, что что-то не так. Могу ли я получить вашу помощь? вот мой [вопрос] (stackoverflow.com/questions/56355698/) - person mahdi; 30.05.2019
comment
МОЙ БОГ! Я часами возился с этим кодом и не мог заставить его работать. Я ввел так много распечаток, чтобы убедиться, что числа верны, и рвал на себе волосы! Наконец-то я заставил его работать, потому что независимо от того, играет ли у вас playerNode или нет, вы ДОЛЖНЫ вызывать метод playerNode.stop() ПЕРЕД вызовом метода playerNode.scheduleSegment(), и тогда он воспроизводится. Я пропустил вызов playerNode.stop(), потому что хотел запустить звуковую дорожку в указанное время. Вау! Какое фиаско с моей стороны! Спасибо за пример кода! - person SouthernYankee65; 13.09.2020