Я реализую приложение, использующее AudioKit, которое позволяет воспроизводить большое количество аудиофайлов и переключаться между ними в любое время. Кроме того, нам необходим один аудиофайл для воспроизведения на l oop для фонового шума.
Как правильно динамически менять проигрыватели на выходе AudioKit? Или как правильно реализовать это поведение?
AudioKit требует, чтобы вы установили его output
, который может быть AKPlayer
, который воспроизводит один аудиофайл, или AKMixer
с массивом AKPlayer
s для пример. Вы не можете изменить output
после запуска AudioKit , как я видел ранее . Поэтому в настоящее время мой подход заключается в использовании AKMixer
для воспроизведения двух AKPlayer
с - одного для текущего файла и одного для фонового шума. Когда пользователь нажимает кнопку «Далее» I stop()
AudioKit, воссоздайте AKMixer
с новым проигрывателем для аудиофайла следующей песни и проигрывателем окружающего шума, назначьте его на output
, start()
AudioKit и начните воспроизведение. оба игрока. Это приводит к нежелательному поведению, потому что воспроизведение окружающего шума останавливается при переключении песен, что приводит к короткой паузе.
Если это правильный подход, как мы можем обновить вывод, не останавливая AudioKit? Я задавался вопросом, можете ли вы инициализировать микшер с массивом игроков, который является сильным свойством, и просто добавлять / удалять игроков в массиве. Но это не работает - запуск нового плеера выдает ошибку player started when in a disconnected state
, потому что этот узел не подключен к выходу.
Я создал пример проекта , чтобы продемонстрировать это поведение , При запуске приложение воспроизводит барабаны как окружающий шум и волны для текущей дорожки. Когда вы нажимаете Next, он переключается на следующую дорожку (которая в этом демонстрационном коде является тем же самым аудиофайлом), и вы можете услышать, как барабаны остановились, а затем возобновили, что нежелательно. Я включил код проекта ниже:
final class Maestro: NSObject {
static let shared = Maestro()
private var audioPlayer: AKPlayer?
private var ambientPlayer: AKPlayer = {
let player = AKPlayer(url: Bundle.main.url(forResource: "drums", withExtension: "wav")!)!
player.isLooping = true
return player
}()
private var mixer: AKMixer?
private let audioFileURL = Bundle.main.url(forResource: "waves", withExtension: "mp3")!
func play() {
playNewPlayer(fileURL: audioFileURL)
}
func next() {
//In the real app we'd play the next audio file in the playlist but for the demo we'll just play the same file
playNewPlayer(fileURL: audioFileURL)
}
private func playNewPlayer(fileURL: URL) {
audioPlayer?.stop()
audioPlayer = nil
do {
try AudioKit.stop()
} catch {
print("Maestro AudioKit.stop error: \(error)")
}
audioPlayer = AKPlayer(url: fileURL)!
mixer = AKMixer([audioPlayer!, ambientPlayer])
AudioKit.output = mixer
do {
try AudioKit.start()
} catch {
print("Maestro AudioKit.start error: \(error)")
}
if ambientPlayer.isPlaying {
//need to resume playback from current position
let pos = ambientPlayer.currentTime
ambientPlayer.stop()
ambientPlayer.play(from: pos)
} else {
ambientPlayer.play()
}
audioPlayer?.play()
}
}