【问题标题】:iOS Video Playback Performance Simulator vs. DeviceiOS 视频播放性能模拟器与设备
【发布时间】:2017-02-08 00:45:59
【问题描述】:

我目前正在开发一个自助服务终端应用程序。此功能的核心是单个电影播放器​​视图控制器。该应用程序将循环播放各种电影文件,并根据当前正在播放的电影显示不同位置的 UI 元素。

这里是我设置视图控制器的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")上运行时,每次我提前播放新的视频资产时,屏幕上都会出现黑色闪烁。

有人知道为什么会出现黑色闪烁吗?

【问题讨论】:

  • 我不确定是什么导致了黑色闪烁,但是,我可以告诉你的是 avPlayer.replaceCurrentItem(with: avPlayerItem) 会在一小段时间内阻止 UI,并且没有办法解决它。不知道这是否是问题,但只是一个提示。
  • @Sneak 好的,这确实有道理。是否有另一种(更好的)方法来切换项目?
  • 不幸的是,没有其他方法可以解决这个问题,我什至为此提供了一个赏金自动取款机。但是,由于您的文件是本地的,如果您没有那么多电影要循环播放,您可以尝试设置一个 AVQueuePlayer ,然后“预加载”所有 playerItems 并将它们排队,根据需要循环播放它们你想不想玩。我没有测试过它的性能,但如果你有办法循环播放许多视频,你不应该这样做是合乎逻辑的。
  • @Sneak 有道理,谢谢!你知道AVQueuePlayer可以预加载多少个视频有上限吗?
  • 我认为文档没有说明任何内容,但是,您可以通过使用 AVPlayerItems 创建数组来简单地对此进行测试,并查看分配了多少内存以及性能如何,除非您找到答案在那里。但是,最好总是测试自己:)

标签: ios avplayer avplayeritem avplayerlayer


【解决方案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

【讨论】:

  • 此解决方案在 iOS 12 上是否仍然适用于您?我处于类似情况,在模拟器和设备上看到这个黑框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多