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

时间:2018-02-20 18:53:53

标签: ios camera avfoundation video-capture video-processing

我做了 ton 的研究,但由于种种原因,我们还未能找到可行的解决方案,我将在下面概述。

问题

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

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

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

尝试解决方案

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

1。使用AVFoundationAVCaptureMovieFileOutput

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

2。使用AVFoundationAVCaptureVideoDataOutput

  • 使用AVCaptureSessionAVCaptureVideoDataOutput使用didOutputSampleBuffer委托方法流式传输和处理相机Feed的每一帧。
  • 在OpenGL视图上绘制每个帧(例如GLKViewWithBounds)。这解决了来自AVPlayer的多个Solution 1.实例的问题。
  • 问题:存储每个帧以便以后显示它们需要大量内存(在iOS设备上不可行)或磁盘空间。如果我想以每秒30帧的速度存储2分钟的视频,那么这是3600帧,如果直接从didOutputSampleBuffer复制,则总计超过12GB。也许有一种方法可以压缩每个帧x1000而不会丢失质量,这样我就可以将这些数据保存在内存中。如果存在这样的方法,我就无法找到它。

可能的第三种解决方案

如果有办法同时读取和写入文件,我相信以下解决方案是理想的。

  • 将视频录制为循环流。例如,对于2分钟的视频缓冲区,我将创建一个文件输出流,它将写入帧两分钟。一旦达到2分钟标记,流将从头开始重新启动,覆盖原始帧。
  • 随着此文件输出流不断运行,我将在同一个录制的视频文件上有3个输入流。每个流将指向流中的不同帧(在写入流后面有效X秒)。然后每个帧将显示在相应UIView的输入流上。

当然,这仍然存在存储空间问题。事件如果帧被存储为压缩的JPEG图像,我们谈论的是质量较低的2分钟视频所需的多GB存储空间。

问题

  1. 有没有人知道实现我想要的有效方法?
  2. 如何解决我已经尝试过的解决方案中的一些问题?

2 个答案:

答案 0 :(得分:2)

自接受答案以来,情况发生了变化。现在有一个分段 AVCaptureMovieFileOutput 的替代方案,当您创建新分段时,它不会在 iOS 上丢帧,而该替代方案是 AVAssetWriter

从 iOS 14 开始,AVAssetWriter 可以创建碎片化的 MPEG4,它们本质上是内存中的 mpeg 4 文件。然而,它专为 HLS 流媒体应用程序设计,也是一种非常方便的视频和音频内容缓存方法。

此新功能由 Takayuki Mizuno 在 WWDC 2020 会议 Author fragmented MPEG-4 content with AVAssetWriter 中描述。

手头有一个碎片化的 mp4 AVAssetWriter,通过将 mp4 段写入磁盘并使用多个 AVQueuePlayer 以所需的时间偏移量播放它们来解决这个问题并不难{1}} 秒。

因此这将是第四种解决方案:使用 AVAssetWriter.mpeg4AppleHLS 输出配置文件捕获相机流并将其作为碎片 mp4 写入磁盘,并使用 {{1} 以不同的延迟播放视频}} 和 AVQueuePlayer

如果您需要支持 iOS 13 及以下版本,则必须替换分段的 AVPlayerLayers,这很快就会变得技术化,尤其是在您还想编写音频时。谢谢,水野孝之!

AVAssetWriter

结果如下

4 clocks visible, 1 in background, 3 on ipad, with delays of 5, 20 and 30 seconds between them

而且性能合理:我的 2019 年 iPod 的 CPU 占用率为 10-14%,内存为 38MB。

答案 1 :(得分:1)

    iOS上的
  1. AVCaptureMovieFileOutput在切换文件时丢帧。在osx上,这不会发生。在标题文件中对此进行了讨论,请参阅captureOutputShouldProvideSampleAccurateRecordingStart
  2. 你的2.和3的组合应该有用。您需要使用AVCaptureVideoDataOutputAVAssetWriter代替AVCaptureMovieFileOutput以块的形式编写视频文件,这样您就不会删除帧。添加3个具有足够存储空间的环形缓冲区以跟上播放,使用GLES或金属显示缓冲区(使用YUV而不是RGBA使用4 / 1.5倍的内存)。

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