SeekToTime в AVPlayer останавливает воспроизведение потокового аудио, когда вперед
Я транслирую аудио с помощью AVPlayer. Работает хорошо. Но теперь мне нужно сделать слайдер для перемещения звука вперед и назад, как в обычном музыкальном плеере. Я использовал функцию seekToTime
который прекрасно работает с локальным аудиофайлом. Но когда я транслирую песню с веб-адреса, функция останавливает звук, когда я пересылаю слайдер с большим диапазоном.
Я предполагаю, что песня загружается, и если я перемещаю ползунок вперед с большим диапазоном, возможно, система не загрузила пакеты данных песни в течение этого времени, поэтому он останавливает проигрыватель.
Допустим, я просто нажал кнопку для потоковой передачи песни, но теперь я перемещаю ползунок сразу на 0-100-й секунде. В этом случае система не работает и останавливает игрока. Из-за отсутствия пакетов данных на то время.
Кто-нибудь знает, как преодолеть эту проблему, или есть другой подход. Я использую SWIFT для разработки. Я собираюсь использовать любую библиотеку, если она будет работать быстро. Это моя функция:
func forward () {
timeGap = slider.value
let preferredTimeScale : Int32 = 1
let targetTime : CMTime = CMTimeMake(timeGap, preferredTimeScale)
player.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}
Заранее спасибо.
1 ответ
Этот ответ в значительной степени основан на этом: /questions/5701968/potok-triggera-ios-avplayer-nahoditsya-vne-bufera/5701972#5701972. Любой и все кредит должен идти туда, так как это просто перевод, чтобы быстро.
Вы правы, предполагая, что при поиске далеко вперед к части, которая еще не была буферизована, игрок останавливается. Дело в том, что он все еще буферизует данные, но не запускается автоматически, когда он будет готов. Итак, перефразируем связанный ответ в swift:
Чтобы настроить ваших наблюдателей:
player.currentItem?.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil)
player.currentItem?.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil)
Обратите внимание, что для того, чтобы иметь возможность наблюдать значения, переданные self
должен наследовать от NSObject
,
И справиться с ними:
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
guard keyPath != nil else { // a safety precaution
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
return
}
switch keyPath! {
case "playbackBufferEmpty" :
if player.currentItem!.playbackBufferEmpty {
print("no buffer")
// do something here to inform the user that the file is buffering
}
case "playbackLikelyToKeepUp" :
if player.currentItem!.playbackLikelyToKeepUp {
self.player.play()
// remove the buffering inidcator if you added it
}
}
}
Вы также можете получить информацию о доступных временных диапазонах из текущей игры AVPlayerItem
(вы можете получить к нему доступ через player.currentItem
если вы не создали это сами). Это позволяет указать пользователю, какие части файла готовы к работе.
Как всегда вы можете прочитать еще в документации: AVPlayerItem и AVPlayer
Чтобы узнать больше о наблюдении значения ключа (KVO): здесь