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): здесь

Другие вопросы по тегам