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 目录中的视频

视频不在设备上播放,但在播放 ov 模拟器

从 iOS 设备播放视频文件

如何确定 iOS 设备的视频播放能力?

我无法在某些 ios 设备(ipad 和 iphone)上播放 HTML5 视频

视频无法在 iOS 设备上播放