Почему не работает AVPlayer Boundary Time Observer?

Я пытаюсь наблюдать время на временной шкале моего AVPlayer.

Я попробовал это в основной очереди; что не сработало. Затем я переключился на фоновую очередь, как советовал эта запись о переполнении стека< /а>; чего не было ни с тем, ни с другим. Ищете рабочее решение или объяснение, почему это не работает.

//add boundary time notification to global queue
avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.main){

                        self.avLayer.player!.pause()
                    }


//add boundary time notification to background queue                
avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.global(qos: .userInteractive)){

                        self.avLayer.player!.pause()
                    }

Обновление: после сохранения строгой ссылки на возвращаемое значение наблюдателя я установил точку останова в обратном вызове. Это все еще не работает.

 //add boundary time notification
                    boundaryTimeObserver = avLayer.player!.addBoundaryTimeObserver(forTimes: [NSValue(time: avLayer.player!.currentItem!.duration)], queue: DispatchQueue.main){

                        self.avLayer.player!.pause()
                    }

person wizeOnes    schedule 19.01.2019    source источник


Ответы (2)


Проблем может быть две:

  1. #P2# <блочная цитата> #P3# #P4#
  2. Убедитесь, что время, которое вы регистрируете для наблюдения, действительно имеет правильное значение:

    • playerItem.duration may be indefinite (see documentation of this property)
    • даже продолжительность asset playerItem может быть неизвестной или неточной оценкой, в зависимости от типа актива и состояния загрузки (опять же, см. документацию AVAsset.duration об этом).

    Как следствие, время, которое вы регистрируете для наблюдения, может никогда не наступить (обратите внимание, что время можно легко проверить, вставив CMTimeShow(duration))

Подходы к решению этой проблемы:

  • если вы просто хотите остановить плеер, когда достигнут конец playerItem, может быть достаточно установить player.actionAtItemEnd на pause

  • если вам нужно выполнить некоторую пользовательскую логику при достижении конца элемента, зарегистрируйте наблюдателя для уведомлений AVPlayerItemDidPlayToEndTime с playerItem в качестве объекта. Этот механизм не зависит от, возможно, неточной длительности и поэтому, надеюсь, более надежен.

person NoHalfBits    schedule 20.01.2019
comment
Я сохранил ссылку, но наблюдатель все еще не вызывается. Пожалуйста, смотрите обновление. - person wizeOnes; 17.02.2019

2019 простой пример..

var player = AVPlayer()
var token: Any?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let u = "https... "
    
    let playerItem = AVPlayerItem(url: URL(string: u)!)
    player = AVPlayer(playerItem: playerItem)
    player.play()

    token = player.addBoundaryTimeObserver(
       forTimes: [0.5 as NSValue],
       queue: DispatchQueue.main) { [weak self] in
         self?.spinner.stopAnimating()
         print("The audio is in fact beginning about now...")
    }
}

Работает отлично.

Важно .. не найдет 0

Используйте небольшое значение, чтобы найти начало в качестве быстрого решения.

person Fattie    schedule 25.07.2019
comment
определенно ценю добавленную заметку о том, что не нашел 0 - person wizeOnes; 26.07.2019