ios - 带有 AVPlayer 的多个视频

我正在为 iPad 开发一个 iOS 应用,它需要在屏幕的某些部分播放视频。我有几个视频文件需要按照编译时未给出的顺序依次播放。它必须看起来好像只是一个视频播放。当从一个视频切换到下一个视频时,这两个视频的最后一帧或第一帧会显示一些延迟,这很好,但不应该出现没有内容的闪烁或白屏。视频不包含音频。重要的是要考虑内存使用情况。这些视频具有非常高的分辨率,可以同时播放多个不同的视频序列。

为了实现这一点,我已经尝试了一些解决方案。它们在下面列出:

1。带有 AVComposition 的 AVPlayer,其中包含所有视频

在这个解决方案中,我有一个 AVPlayer,它将仅在使用 AVComposition 制作的 AVPlayerItem 上使用,该 AVComposition 包含彼此相邻放置的所有视频。当转到特定视频时,我会寻找下一个视频开始的合成时间。这个解决方案的问题是,在寻找播放器时,它会快速显示它正在寻找的一些帧,这是 Not Acceptable 。似乎没有办法直接跳转到构图中的特定时间。我尝试通过制作刚刚完成的视频中最后一帧的图像来解决这个问题,然后在搜索时将其显示在 AVPLayer 前面,最后在搜索完成后将其删除。我正在使用 AVAssetImageGenerator 制作图像,但由于某种原因,图像的质量与视频不同,因此在视频上显示和隐藏图像时会有显着变化。 另一个问题是 AVPlayer 使用大量内存,因为单个 AVPlayerItem 包含所有视频。

2。具有多个 AVPlayerItems 的 AVPlayer

此解决方案为每个视频使用 AVPlayerItem,并在切换到新视频时替换 AVPlayer 的项目。这样做的问题是,当切换 AVPlayer 的项目时,它会在加载新项目时短暂显示白屏。要解决此问题,可以使用在加载时将图像放在最后一帧前面的解决方案,但仍然存在图像和视频质量不同且显着的问题。

3。两个 AVPlayer 相互叠放轮流播放 AVPlayerItem

我尝试的下一个解决方案是让两个 AVPlayer 相互叠加,轮流播放 AVPlayerItems。因此,当播放器完成播放时,它将停留在视频的最后一帧。另一个 AVPlayer 将被带到前面(其项目设置为 nil,因此它是透明的),并且下一个 AVPlayerItem 将插入到该 AVPlayer 中。一旦加载它就会开始播放,并且两个视频之间的流畅交易的错觉将完好无损。此解决方案的问题是内存使用情况。在某些情况下,我需要同时在屏幕上播放两个视频,这将导致 4 个 AVPlayer 同时加载一个 AVPlayerItem。这简直是​​太多的内存,因为视频可以是非常高的分辨率。


是否有人对上面发布的整体问题和经过尝试的解决方案有一些想法、建议、意见或其他内容。

最佳答案

因此,该项目现已在 App Store 中上线,是时候回到这个帖子并分享我的发现并揭示我最终做了什么。

什么不起作用

我在包含所有视频的大型 AVComposition 上使用的第一个选项不够好,因为没有办法在没有小的擦洗故障的情况下跳转到合成中的特定时间。此外,由于 API 无法为暂停提供帧保证,因此我在组合中的两个视频之间准确暂停视频时遇到了问题。

第三个有两个 AVPlayer 并让他们轮流在实践中效果很好。特别是在 iPad 4 或 iPhone 5 上。RAM 量较低的设备是一个问题,因为同时在内存中存储多个视频会消耗太多内存。特别是因为我必须处理非常高分辨率的视频。

我最终做了什么

好吧,左边是选项 2。在需要时为视频创建一个 AVPlayerItem 并将其提供给 AVPlayer。这个解决方案的好处是内存消耗。通过懒惰地创建 AVPlayerItems 并在不再需要它们时将它们丢弃可以将内存消耗保持在最低限度,这对于支持 RAM 有限的旧设备非常重要。这个解决方案的问题是,当从一个视频转到下一个视频时,在下一个视频加载到内存中时,会出现一个空白屏幕。我解决此问题的想法是在 AVPlayer 后面放置一个图像,该图像将在播放器缓冲时显示。我知道我需要与视频完全像素到像素完美的图像,所以我捕获的图像是视频最后一帧和第一帧的精确副本。这个解决方案在实践中效果很好。

这个解决方案的问题

如果视频/图像不是其 native 大小或模块 4 缩放,则我遇到了问题,即 UIImageView 内的图像位置与 AVPlayer 内视频的位置不同。换句话说,我对如何使用 UIImageView 和 AVPlayer 处理半像素有疑问。好像不是这样。

我是如何解决的

我尝试了很多东西,因为我的应用程序以交互方式使用不同尺寸的视频。我尝试更改 AVPlayerLayer 和 CALayer 的 magnificationfilter 和 minificationFilter 以使用相同的算法,但并没有真正改变任何东西。最后,我创建了一个 iPad 应用程序,它可以自动截取我需要的所有大小的视频,然后在视频缩放到特定大小时使用正确的图像。这提供了在我展示特定视频的所有尺寸中像素完美的图像。不是一个完美的工具链,但结果是完美的。

最终反射(reflection)

这个位置问题对我来说非常明显(因此解决非常重要)的主要原因是因为我的应用正在播放的视频内容是绘制动画,其中很多内容处于固定位置,并且只有一个图片的一部分在移动。如果所有内容仅移动一个像素,则会产生非常明显且丑陋的故障。在今年的 WWDC 上,我与一位是 AVFoundation 专家的 Apple 工程师讨论了这个问题。当我向他介绍这个问题时,他的建议基本上是选择选项 3,但我向他解释说这是不可能的,因为内存消耗,而且我已经尝试了该解决方案。鉴于此,他说我选择了正确的解决方案,并要求我在视频缩放时为 UIImage/AVPlayer 定位提交错误报告。

https://stackoverflow.com/questions/14646235/

相关文章:

objective-c - 如何在 Objective-C 中命名常量?

c++ - UInt8 和 uint8_t 有什么区别

objective-c - 使用 JSON (iOS) 的 Cocoa 错误 3840

iphone - Objective-C 实现文件中方法名后的分号

ios - UIImagePickerController 相机 View 在 iOS 8 上奇怪地

objective-c - 为什么不鼓励使用伞式框架?

objective-c - 处理由于 iOS 通讯录 API 中的链接卡导致的重复联系人

ios - scaledValueForValue : called on a font that

ios - 在从 UIViewController 调用的非保留完成中引用 self 时,weakS

objective-c - 在子类中覆盖初始化