ios - 使用 AVPlayer 时保持良好的滚动性能

标签 ios video avfoundation avplayer

我正在开发一个应用程序,其中有一个 Collection View , Collection View 的单元格可以包含视频。现在我正在使用 AVPlayerAVPlayerLayer 显示视频。不幸的是,滚动性能很糟糕。似乎 AVPlayerAVPlayerItemAVPlayerLayer 在主线程上做了很多工作。他们不断地取出锁、等待信号量等,这会阻塞主线程并导致严重的帧丢失。

有没有办法告诉 AVPlayer 停止在主线程上做这么多事情?到目前为止,我尝试过的任何事情都无法解决问题。

我还尝试使用 AVSampleBufferDisplayLayer 构建一个简单的视频播放器。使用它我可以确保一切都发生在主线程之外,并且我可以在滚动和播放视频时达到 ~60fps。不幸的是,该方法的级别要低得多,并且它不提供开箱即用的音频播放和时间擦洗等功能。有什么方法可以用 AVPlayer 获得类似的性能吗?我更愿意使用它。

编辑: 进一步研究后,使用 AVPlayer 似乎无法获得良好的滚动性能。创建一个 AVPlayer 并与一个 AVPlayerItem 实例关联会启动一堆工作,这些工作会跳到主线程上,然后等待信号量并尝试获取一堆锁.随着 ScrollView 中视频数量的增加,主线程停顿的时间会急剧增加。

AVPlayer dealloc 似乎也是一个大问题。 Dealloc'ing 一个 AVPlayer 也会尝试同步一堆东西。同样,当您创建更多玩家时,情况会变得非常糟糕。

这非常令人沮丧,它使 AVPlayer 几乎无法用于我正在尝试做的事情。像这样阻塞主线程是一件非常业余的事情,所以很难相信 Apple 工程师会犯这种错误。不管怎样,希望他们能尽快解决这个问题。

最佳答案

尽可能在后台队列中构建您的 AVPlayerItem(您必须在主线程上执行一些操作,但您可以执行设置操作并等待视频属性加载到后台队列中 -仔细阅读文档)。这涉及与 KVO 的巫毒舞,真的不好玩。

AVPlayer 正在等待 AVPlayerItem 的状态变为 AVPlayerItemStatusReadyToPlay 时出现问题。为了减少你想要做的打嗝的长度,你可以在将 AVPlayerItem 分配给 AVPlayer 之前在后台线程上将它更接近 AVPlayerItemStatusReadyToPlay

自从我真正实现这个已经有一段时间了,但是 IIRC 导致主线程阻塞是因为底层 AVURLAsset 的属性是延迟加载的,如果你不自己加载它们,当 AVPlayer 想要播放时,它们会忙于加载主线程。

查看 AVAsset 文档,尤其是关于 AVAsynchronousKeyValueLoading 的内容。我认为我们需要在 AVPlayer 上使用 Assets 之前加载 durationtracks 的值,以最小化主线程 block 。有可能我们还必须遍历每个轨道并对每个段执行 AVAsynchronousKeyValueLoading,但我不记得 100%。

关于ios - 使用 AVPlayer 时保持良好的滚动性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30363502/

相关文章:

ios - iOS 9 中的 NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9802)

ios - 如何将2个UIpickerView添加到一个UIview中?

c# - 使用C#从我的youtube视频 channel 中搜索上传的youtube视频

ios - 为什么 AVAssetWriter 创建的文件大小为 0?

ios - 在 Swift 3 中使用 AVFoundation 设置图片方向

ios - 使用 AVFoundation 随机播放 mp3

ios - 无法识别的选择器发送到实例 tableview swift

iphone - 在 iOS 中存储图像的最佳方式

python - ffmpeg 原始视频和音频标准输入

c++ - openGL视频显示