重要的! 从 iOS 8 开始,您可以使用 VTCompressionSession 并直接访问 NAL 单元,而不必挖掘容器。
幸运的是你可以做到这一点,我会告诉你怎么做,但你将不得不用 MP4 或 MOV 容器弄脏你的手。一个有用的资源(虽然,更特定于 MOV)是 Apple 的 Quicktime 文件格式介绍手册
http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html#//apple_ref /doc/uid/TP40000939-CH202-TPXREF101
首先,您将无法在录制结束前 30 秒从任意点开始保存的电影,您必须在大约 30 秒时使用一些 I-Frame。根据您的关键帧间隔,它可能在 30 秒标记之前或之后几秒钟。您可以使用所有 I 帧并从任意点开始,但之后您可能需要重新编码视频,因为它会非常大。
所以知道这一点,让我们继续前进。
第一步是设置 AVAssetWriter 时,您需要将其 AVAssetWriterInput 的 expectsMediaDataInRealTime 属性设置为 YES。
在 captureOutput 回调中,您将能够从您正在写入的文件中执行 fread。第一个 fread 将为您提供一点 MP4/MOV(无论您使用什么格式)标题(即“ftyp”原子、“wide”原子和“mdat”原子的开头)。您想要“mdat”部分中的内容。因此,您将开始保存数据的偏移量将是 36 左右。
每次读取都会获得 0 个或更多 AVC NAL 单元。您可以从 ISO/IEC 14496-10 表 7-1 中找到 NAL 单元类型列表。它们的格式与附件 B 中指定的格式略有不同,但没关系。此外,MP4/MOV 文件中只有 IDR 切片和非 IDR 切片。IDR 将是您想要使用的 I-Frame。
MP4/MOV容器中的NAL单元格式如下:
4 bytes - Size
[Size] bytes - NALU Data
data[0] & 0x1F - NALU Type
所以现在你有了你正在寻找的数据。当你去保存这个文件时,你必须用正确的长度、样本数更新 MPV/MOV 容器,你必须用每个样本的正确大小更新“stsz”原子,以及更新具有正确电影持续时间的媒体标题和轨道标题等。我可能会建议做的是在第一次运行时创建一个示例容器,您可以或多或少地使用该特定电影的适当数据覆盖/增强它。您需要这样做,因为各种 iDevice 上的编码器并不都具有相同的设置,并且“avcC”原子包含编码器信息。
在这种情况下,您实际上并不需要对 AVC 流有太多了解,因此您可能希望将您的试验集中在更新您正确选择的容器格式上。祝你好运。