iOS – 创建多个延时的实时相机预览视图

我做了大量的研究,但由于很多原因,我们还没有找到可行的解决方案,我将在下面概述。


问题

在我的iOS应用程序中,我想要三个视图无限期地显示设备相机的延迟实时预览。

例如,视图1将显示摄像机视图,延迟5秒,视图2将显示相同的摄像机视图,延迟20秒,视图3将显示相同的摄像机视图,延迟30秒。

这将用于记录自己进行某种活动,例如锻炼锻炼,然后在几秒钟后观察自己,以完善您的锻炼forms。

尝试解决方案

我尝试并研究了几种不同的解决方案,但都有问题。

1.使用AVFoundationAVCaptureMovieFileOutput

  • 使用AVCaptureSessionAVCaptureMovieFileOutput将短片段录制到设备存储。 短片是必需的,因为您无法从URL播放video,并同时写入同一URL。
  • 有3个AVPlayerAVPlayerLayer实例,所有实例都按照所需的时间延迟播放短片。
  • 问题:
    1. 使用AVPlayer.replaceCurrentItem(_:)切换剪辑时,剪辑之间会有非常明显的延迟。 这需要平稳过渡。
    2. 虽然陈旧,但此处的评论建议不要因设备限制而创建多个AVPlayer实例。 我无法找到确认或否认此声明的信息。 E:来自Jake G的评论 – 对于iPhone 5及更新版本,10个AVPlayer实例是可以的。

2.使用AVFoundationAVCaptureVideoDataOutput

  • 使用AVCaptureSessionAVCaptureVideoDataOutput使用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存储空间。

  1. 有谁知道实现我想要的有效方法?
  2. 我怎样才能解决我已经尝试过的解决方案中的一些问题?

  1. 在iOS AVCaptureMovieFileOutput切换文件时丢帧。 在osx上,这不会发生。 在头文件中有关于此的讨论,请参阅captureOutputShouldProvideSampleAccurateRecordingStart

你和你的2.和3的组合应该有效。 您需要使用AVCaptureVideoDataOutputAVAssetWriter而不是AVCaptureMovieFileOutput以块的forms编写video文件,这样您就不会丢帧。 添加3个具有足够存储空间的环形缓冲区以跟上播放,使用GLES或金属显示缓冲区(使用YUV而不是RGBA使用4 / 1.5倍的内存)。

在强大的iPhone 4s和iPad 2的时代,我尝试了一个更适度的版本。它显示(我认为)现在和过去的10s。 我估计,因为你可以在3倍实时编码30fps,我应该能够编码块并使用仅2/3的硬件容量读取之前的块。 遗憾的是,无论是我的想法是错误还是硬件都存在非线性,或者代码错误而且编码器一直落后。