iOS – 创建多个延时的实时相机预览视图
我做了大量的研究,但由于很多原因,我们还没有找到可行的解决方案,我将在下面概述。
问题
在我的iOS应用程序中,我想要三个视图无限期地显示设备相机的延迟实时预览。
例如,视图1将显示摄像机视图,延迟5秒,视图2将显示相同的摄像机视图,延迟20秒,视图3将显示相同的摄像机视图,延迟30秒。
这将用于记录自己进行某种活动,例如锻炼锻炼,然后在几秒钟后观察自己,以完善您的锻炼forms。
尝试解决方案
我尝试并研究了几种不同的解决方案,但都有问题。
1.使用AVFoundation
和AVCaptureMovieFileOutput
:
- 使用
AVCaptureSession
和AVCaptureMovieFileOutput
将短片段录制到设备存储。 短片是必需的,因为您无法从URL播放video,并同时写入同一URL。 - 有3个
AVPlayer
和AVPlayerLayer
实例,所有实例都按照所需的时间延迟播放短片。 - 问题:
- 使用
AVPlayer.replaceCurrentItem(_:)
切换剪辑时,剪辑之间会有非常明显的延迟。 这需要平稳过渡。 - 虽然陈旧,但此处的评论建议不要因设备限制而创建多个
AVPlayer
实例。 我无法找到确认或否认此声明的信息。 E:来自Jake G的评论 – 对于iPhone 5及更新版本,10个AVPlayer
实例是可以的。
- 使用
2.使用AVFoundation
和AVCaptureVideoDataOutput
:
- 使用
AVCaptureSession
和AVCaptureVideoDataOutput
使用didOutputSampleBuffer
委托方法流式传输和处理摄像机源的每个帧。 - 在OpenGL视图上绘制每个帧(例如
GLKViewWithBounds
)。 这解决了Solution 1.
中多个AVPlayer
实例的问题。 - 问题:存储每个帧以便以后显示它们需要大量内存(在iOS设备上不可行)或磁盘空间。 如果我想以每秒30帧的速度存储2分钟的video,那么这是3600帧,如果直接从
didOutputSampleBuffer
复制,则总计超过12GB。 也许有一种方法可以压缩每个帧x1000而不会丢失质量,这样我就可以将这些数据保存在内存中。 如果存在这样的方法,我一直无法找到它。
第三种解决方案
如果有办法同时读取和写入文件,我相信以下解决方案将是理想的。
- 将video录制为循环流。 例如,对于2分钟的video缓冲区,我将创建一个文件输出流,它将写入帧两分钟。 一旦达到2分钟标记,流将从头重新开始,覆盖原始帧。
- 随着这个文件输出流不断运行,我将在同一个录制的video文件上有3个输入流。 每个流将指向流中的不同帧(在写入流后面有效X秒)。 然后每个帧将显示在输入流上各自的
UIView
。
当然,这仍然存在存储空间问题。 事件如果帧被存储为压缩的JPEG图像,我们谈论的是低质量,2分钟video所需的多GB存储空间。
题
- 有谁知道实现我想要的有效方法?
- 我怎样才能解决我已经尝试过的解决方案中的一些问题?
- 在iOS
AVCaptureMovieFileOutput
切换文件时丢帧。 在osx上,这不会发生。 在头文件中有关于此的讨论,请参阅captureOutputShouldProvideSampleAccurateRecordingStart
。
你和你的2.和3的组合应该有效。 您需要使用AVCaptureVideoDataOutput
和AVAssetWriter
而不是AVCaptureMovieFileOutput
以块的forms编写video文件,这样您就不会丢帧。 添加3个具有足够存储空间的环形缓冲区以跟上播放,使用GLES或金属显示缓冲区(使用YUV而不是RGBA使用4 / 1.5倍的内存)。
在强大的iPhone 4s和iPad 2的时代,我尝试了一个更适度的版本。它显示(我认为)现在和过去的10s。 我估计,因为你可以在3倍实时编码30fps,我应该能够编码块并使用仅2/3的硬件容量读取之前的块。 遗憾的是,无论是我的想法是错误还是硬件都存在非线性,或者代码错误而且编码器一直落后。