Воспроизведение видеоплейлиста и отдельного видеоклипа из плейлиста в Loop, AVQueuePlayer iOS Swift

Я пытаюсь воспроизвести список воспроизведения видео в цикле, а также воспроизвести отдельный видеоклип из списка воспроизведения в цикле в AVQueuePlayer с помощью AVPlayerItem, но я не могу найти решение для того же, что и код, который я пробовал до сих пор.

Общий

var player : AVQueuePlayer?
var playerLayer: AVPlayerLayer?
var playerItem: [AVPlayerItem] = []

func playAtIndex(index:Int){
        for i in index ..< playerItem.count {
            let obj = playerItem[i]
            if (self.player?.canInsert(obj, after: nil))! {
                obj.seek(to: .zero, completionHandler: nil)
                self.player?.insert(obj, after: nil)
                }
        }
    }

Инициализировать видеоплеер

self.player = AVQueuePlayer.init(items: self.playerItem)
self.playerLayer = AVPlayerLayer(player: self.player)
self.playerLayer?.frame = self.view!.bounds
self.playerLayer?.videoGravity = AVLayerVideoGravity.resizeAspect
self.view!.layer.addSublayer(self.playerLayer!)
self.player?.play()

код, сделанный до сих пор для зацикливания списка воспроизведения, это работает, но некоторые видео из цикла иногда не воспроизводятся.

self.playAtIndex(index: 0)

код сделан для зацикливания отдельного видеоклипа в плейлисте, но не работает

let playerItem: AVPlayerItem = note.object as! AVPlayerItem // here we get current item 
playerItem.seek(to: CMTime.zero, completionHandler: nil)
self.player?.play()

Любая помощь будет здорово.!!


person Zღk    schedule 27.05.2019    source источник


Ответы (1)


Чтобы зациклить playerItems в AVQueuePlayer, вам нужно добавить observer к notification - AVPlayerItemDidPlayToEndTimeNotification

Уведомление, которое публикуется, когда элемент воспроизводится до времени окончания.

NotificationCenter.default.addObserver(self, selector: #selector(playerEndedPlaying), name: Notification.Name("AVPlayerItemDidPlayToEndTimeNotification"), object: nil)

Метод playerEndedPlaying(_:) будет вызываться всякий раз, когда запускается notification.

@objc func playerEndedPlaying(_ notification: Notification) {
    DispatchQueue.main.async {[weak self] in
        if let playerItem = notification.object as? AVPlayerItem {
            self?.player?.remove(playerItem)
            playerItem.seek(to: .zero, completionHandler: nil)
            self?.player?.insert(playerItem, after: nil)
            if playerItem == self?.playerItems?.last {
                self?.pauseVideo()
            }
        }
    }
}

Вышеупомянутый метод будет вызываться каждый раз, когда заканчивается воспроизведение playerItem в AVQueuePlayer.

  1. AVQueuePlayer's insert(_:after:) вызывается, когда каждый playerItem добавляется к queue.

послеэлемент

Элемент игрока, за которым в очереди должен следовать вновь вставленный элемент игрока. Передайте nil, чтобы добавить элемент в очередь.

  1. Цикл идентифицируется с помощью playerItem == self?.playerItems?.last. Здесь вы можете добавить свою собственную обработку. У меня paused player один раз все videos заканчиваются воспроизведением.
person PGDev    schedule 27.05.2019
comment
спасибо за краткое, но это не ответ на мой вопрос. - person Zღk; 27.05.2019
comment
он не воспроизводит плейлист в цикле - person Zღk; 27.05.2019
comment
Попробуйте удалить строку self?.pauseVideo() в приведенном выше коде. - person PGDev; 27.05.2019
comment
он воспроизводит только последнее видео в цикле - person Zღk; 28.05.2019
comment
Возможно, AVPlayerLooper.loopingPlayerItems? developer.apple.com/documentation/avfoundation/avplayerlooper/ - person AmitaiB; 20.05.2020