iOS 视频播放性能模拟器与设备
Posted
技术标签:
【中文标题】iOS 视频播放性能模拟器与设备【英文标题】:iOS Video Playback Performance Simulator vs. Device 【发布时间】: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 创建数组来简单地对此进行测试,并查看分配了多少内存以及性能如何,除非您找到答案在那里。但是,最好总是测试自己:)
【参考方案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 上是否仍然适用于您?我处于类似情况,在模拟器和设备上看到这个黑框。以上是关于iOS 视频播放性能模拟器与设备的主要内容,如果未能解决你的问题,请参考以下文章
AVPlayer 无法在 iOS8 上播放 NSDocuments 目录中的视频