Симулятор производительности воспроизведения видео iOS в сравнении с устройством

В настоящее время я работаю над киоск-приложением. Ядром этой функциональности является единый контроллер представления проигрывателя фильмов. Приложение будет циклически просматривать различные файлы фильмов, а также отображать элементы пользовательского интерфейса в различных местах в зависимости от того, какой фильм воспроизводится в данный момент.

Здесь я настроил avPlayer контроллера представления:

func initPlayer() {


setAvPlayerItem()

avPlayerItem = AVPlayerItem(asset: avAsset)
avPlayer = AVPlayer(playerItem: avPlayerItem)

avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
avPlayerLayer.frame = UIScreen.main.bounds
movieView.layer.addSublayer(avPlayerLayer)

notificationCenter.removeObserver(self,
                                  name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                  object: avPlayer.currentItem)
notificationCenter.addObserver(self,
                               selector: #selector(avPlayerDidPlayToEndTime),
                               name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                               object: avPlayer.currentItem)

avPlayer.seek(to: kCMTimeZero)
avPlayer.volume = 0.0
avPlayer.play()
}

Вот где я играю текущий фильм:

func playCurrentMovie() {
setAvPlayerItem()

avPlayer.replaceCurrentItem(with: avPlayerItem)

notificationCenter.removeObserver(self,
                                  name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                  object: avPlayer.currentItem)

notificationCenter.addObserver(self,
                               selector: #selector(avPlayerDidPlayToEndTime),
                               name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                               object: avPlayer.currentItem)

avPlayer.seek(to: kCMTimeZero)
avPlayer.volume = 0.0
avPlayer.play()
}

... и здесь я устанавливаю, какой avPlayerAsset следует использовать:

func setAvPlayerItem()  {


let resource = moviesCollection[currentMovie]["Movie"] as! String?

guard let moviePath = Bundle.main.path(forResource: resource,
                                       ofType:"mp4") else {
    debugPrint("video not found")
    return
}

movieURL = URL(fileURLWithPath: moviePath)
avAsset = AVAsset(url: movieURL)

avPlayerItem = AVPlayerItem(asset: avAsset)
}

Это отлично работает на Симуляторе. При работе на устройстве (iPad Pro 12,9") каждый раз, когда я перехожу к воспроизведению нового видеоресурса, на экране появляется черное мерцание.

Кто-нибудь знает, почему может происходить это черное мерцание?


person narner    schedule 08.02.2017    source источник
comment
Я не уверен, что вызывает черное мерцание, однако я могу вам сказать, что avPlayer.replaceCurrentItem(with: avPlayerItem) блокирует пользовательский интерфейс на небольшое количество времени, и нет никакого способа обойти это. не уверен, что это проблема, но только подсказка.   -  person    schedule 08.02.2017
comment
@Sneak Хорошо, это имеет смысл. Есть ли другой (лучший) способ переключения предметов?   -  person narner    schedule 08.02.2017
comment
К сожалению, нет другого способа обойти это, у меня даже есть банкомат для этого. Однако, поскольку ваши файлы являются локальными, если у вас не так много фильмов для циклического просмотра, вы можете попробовать настроить AVQueuePlayer и предварительно загрузить все playerItems и поставить их в очередь, циклически перебирая их в соответствии с тем, что вы хотите воспроизвести. Я не проверял производительность этого, но логично, что вам не следует этого делать, если у вас есть возможность просмотреть много видео.   -  person    schedule 08.02.2017
comment
@Sneak Это имеет смысл, спасибо! Знаете ли вы, существует ли какой-либо верхний предел количества видео, которые AVQueuePlayer может предварительно загрузить?   -  person narner    schedule 08.02.2017
comment
документация ничего не говорит об этом, я думаю, однако, вы можете просто проверить это, создав массив с AVPlayerItems и посмотреть, сколько памяти выделено и какова производительность, если вы не найдете ответ там. Однако всегда лучше проверить себя :)   -  person    schedule 08.02.2017
comment
Кстати, вы также должны проверить, чтобы реализовать асинхронную загрузку AVAsset KVO, что может уменьшить некоторые задержки при загрузке ресурсов. Посмотрите этот пример Apple, чтобы узнать, как это сделать: разработчик. apple.com/library/content/samplecode/   -  person    schedule 08.02.2017


Ответы (1)


Я много пытался предотвратить это черное мерцание, но безуспешно. Однако я придумал способ скрыть это от пользователя.

Сначала я сделал очень простое представление, которое обертывает AVPlayerLayer под названием videoView в этом примере. Затем я добавил это представление в качестве подвида моего представления видеоплеера. Затем всякий раз, когда я загружаю новое видео, я делаю:

if let snapshotView = playerView.snapshotView(afterScreenUpdates: false) {
    insertSubview(snapshotView, belowSubview: videoView)
    snapshotView.frame = videoView.bounds
}

let item: AVPlayerItem = ...
player.replaceCurrentItem(with: item)
// The rest of your loading like normal

Просто не забудьте удалить snapshotView, если вы поддерживаете очистку вашего видео или что-то еще.

person jamone    schedule 19.10.2018
comment
Это решение все еще работает для вас на iOS 12? Я в похожей ситуации и вижу эту черную рамку на симуляторе и устройстве. - person Jumhyn; 05.08.2019