AVPlayer не запускает воспроизведениеBufferEmpty, но также не воспроизводит

Я использую AVPlayer для воспроизведения потокового аудио через Интернет. Мне нравится восстанавливать воспроизведение, если оно было приостановлено более чем на 1 минуту.

Я призываю player.rate = 1.0 возобновить работу. Однако, если поток был приостановлен более чем на 1 минуту, он больше не воспроизводится. В этом случае мне нужно воссоздать AVPlayerItem, чтобы он снова заработал.

Итак, как мне поймать этот случай, чтобы я знал, что воспроизведение не восстановилось?

  • КВО пробовал на player.rate. Однако он остается на уровне 1.0. Плеер не играет!
  • КВО пробовал на currentItem.playbackBufferEmpty. Однако в данном случае он не вызывается.
  • currentItem.status не переключается на .Failed. Это вообще не меняется.

Кажется, что AVPlayer в этом случае ничего не делает. Любые идеи?

Я создаю код для игровой площадки, чтобы продемонстрировать проблему:

import UIKit
import AVFoundation

// keep it running forever so it plays audio
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(true)

class AVPlayerTest {

    let player = AVPlayer()
    let streamurl = NSURL(string: "http://detektor.fm/stream/mp3/musik/")!

    func startTest() {
        let item = AVPlayerItem(URL: streamurl)
        player.replaceCurrentItemWithPlayerItem(item)
        player.play()

        // give it some start time to build a buffer
        NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(timerTickedToPause), userInfo: nil, repeats: false)
    }

    @objc func timerTickedToPause(timer: NSTimer) {
        player.pause()
        // pause now for some time. 90s is not enough.
        NSTimer.scheduledTimerWithTimeInterval(120, target: self, selector: #selector(timerTickedToPlay), userInfo: nil, repeats: false)
    }

    @objc func timerTickedToPlay(timer: NSTimer) {
        // try to resume playback

        print(player.rate)

        player.play()

        print(player.rate)

        // check in some seconds if it recovered
        NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: #selector(timerTickedCheck), userInfo: nil, repeats: false)
    }

    @objc func timerTickedCheck(timer: NSTimer) {

        // it reports rate = 1.0 but is not playing here though!
        // there is no way to know for me it did not recover here!?
        print(player.rate)

        // recover by creating a new item works
        let item = AVPlayerItem(URL: streamurl)
        player.replaceCurrentItemWithPlayerItem(item)
        player.play()
    }
}

let test = AVPlayerTest()
test.startTest()

person funkenstrahlen    schedule 26.04.2016    source источник
comment
Это похоже на тот же вопрос: stackoverflow.com/questions/36617232/   -  person funkenstrahlen    schedule 26.04.2016
comment
да, точно так же, он работает с фиксированными (не в прямом эфире) видео, но в прямом эфире он не работает, я всегда повторно инициализирую проигрыватель с помощью item: / Если этот вопрос дает решение, отправьте его и мне.   -  person turushan    schedule 26.04.2016
comment
Я вполне могу воссоздать AVPlayerItem. Однако мне нужно знать, если это не удалось.   -  person funkenstrahlen    schedule 26.04.2016
comment
У меня нет времени попробовать, но есть предложение, можете ли вы попробовать player.pause (), затем player.play () и после этого проверить, равен ли рейтинг 1   -  person turushan    schedule 26.04.2016
comment
Я уже делал это в отладчике. player.pause() и player.play() - это то же самое, что установить player.rate на 0 или 1, как указано в документации Apple. После вызова player.rate = 1 он не воспроизводится, но rate остается на 1.   -  person funkenstrahlen    schedule 26.04.2016
comment
См. Мой ответ здесь - stackoverflow.com/a/38120330/4249825   -  person Mugurel    schedule 30.06.2016
comment
Похоже, что многие из этих проблем были исправлены Apple в iOS 10.   -  person funkenstrahlen    schedule 01.07.2016
comment
Здесь та же проблема. Вы нашли решение?   -  person Patrick Bodet    schedule 24.03.2017
comment
У меня работает с avplayer iOS 10.   -  person funkenstrahlen    schedule 24.03.2017
comment
Что работает. Для чего ты делал? Я использую iOS 10 и AVPlayer для потоковой передачи URL-адреса ресурса, yp. shoutcast.com/sbin/tunein-station.pls?id=1577011 (например), и я столкнулся с той же проблемой, которую вы описали.   -  person Patrick Bodet    schedule 24.03.2017


Ответы (1)


Используйте timeControlStatus экземпляра AVPlayer, который «указывает, выполняется ли воспроизведение в данный момент, приостановлено на неопределенное время или приостановлено в ожидании соответствующих сетевых условий».

let status = player.timeControlStatus

switch status {
case .paused:
    print("timeControlStatus.paused")

case .playing:
    print("timeControlStatus.playing")

case .waitingToPlayAtSpecifiedRate:
    print("timeControlStatus.waitingToPlayAtSpecifiedRate")
    if let reason = player.reasonForWaitingToPlay {

        switch reason {
        case .evaluatingBufferingRate:
            print("reasonForWaitingToPlay.evaluatingBufferingRate")

        case .toMinimizeStalls:
            print("reasonForWaitingToPlay.toMinimizeStalls")

        case .noItemToPlay:
            print("reasonForWaitingToPlay.noItemToPlay")

        default:
            print("Unknown \(reason)")
        }
    }

}

У меня такая же проблема, но в моем случае она возникает, если я перехожу в фоновый режим в приостановленном состоянии. Когда я возвращаюсь на forground .play () не работает. Он застревает в режиме waitToPlayAtSpecifiedRate.evaluatingBufferingRate. В этот момент экземпляр AVPlayerItem.status называется readToPlay.

На этом этапе написания всякий раз, когда принимается startCommand, я перезагружаю AVplayer, чтобы быть уверенным. Но это кажется неуклюжим. Ищу более плавное решение.

person David Mayes    schedule 27.03.2018
comment
не знал о timeControlStatus, но, похоже, работает как шарм, отличный ответ! - person Benjamin Jimenez; 12.09.2018
comment
Я был вынужден перезагрузить ассет в AVPlayer по той же причине. Хотя это должно быть что-то о свойствах потока. Я проигрываю аудиопотоки от одного провайдера - они нормально проигрываются после прерывания. Потоки от другого провайдера никогда не могут воспроизводиться после прерывания (это реклама VAST, если кто-то сочтет эту информацию актуальной). - person thedazed; 24.02.2020