iOS平台是否有方法保存视频对应的AVDepthData深度数据?
解决方案:将RGB视频与深度数据同步保存为MP4(兼容ARKit SceneDepth)
核心实现逻辑
MP4容器本身支持多轨道存储,你可以把深度数据作为独立的辅助元数据轨道和视频轨道一同写入,不需要改动原RGB视频的编码逻辑,同时能保证后续读取时帧数据完全对齐。
步骤1:初始化AVAssetWriter双轨道配置
你需要创建两个独立的AVAssetWriterInput分别处理RGB帧和深度数据:
- 常规视频轨道:和普通视频录制配置完全一致,媒体类型设置为
AVMediaTypeVideo,按需求配置H.264/HEVC编码参数 - 深度数据轨道:媒体类型设置为
AVMediaTypeMetadata,参考配置代码如下:
// 可根据实际深度数据格式调整为kCVPixelFormatType_DepthFloat16 let depthPixelFormat = kCVPixelFormatType_DepthFloat32 let depthOutputSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.hevc, AVVideoWidthKey: depthMapWidth, AVVideoHeightKey: depthMapHeight, kCVPixelBufferPixelFormatTypeKey as String: depthPixelFormat ] let depthInput = AVAssetWriterInput(mediaType: .metadata, outputSettings: depthOutputSettings) // 实时录制场景必须开启,非实时离线转码可以关闭 depthInput.expectsMediaDataInRealTime = true assetWriter.add(depthInput)
注意:如果是存储ARKit输出的SceneDepth数据,直接使用ARKit返回的原生像素格式即可,不需要额外做格式转换,避免深度精度损失。
步骤2:同步写入帧数据
必须保证每一组RGB帧和对应深度帧的presentationTimeStamp完全一致,避免后续读取时出现帧错位问题:
// 写入RGB帧的同时写入对应深度帧 if videoInput.isReadyForMoreMediaData { videoInput.append(rgbSampleBuffer) } if depthInput.isReadyForMoreMediaData { // 将AVDepthData的pixelBuffer封装为CMSampleBuffer,时间戳和对应RGB帧完全相同 let depthSampleBuffer = generateSampleBuffer(from: depthData.pixelBuffer, timeStamp: rgbFrameTime) depthInput.append(depthSampleBuffer) }
步骤3:ARKit SceneDepth扩展适配注意事项
- ARKit输出的SceneDepth默认是
kCVPixelFormatType_DepthFloat16格式,直接用原格式写入即可,比Float32格式占用空间减少一半 - 相机内参、时间戳偏移等附加信息不需要写入深度轨道,可以单独存为文件自定义元数据,或新增独立的元数据项写入
- 读取数据时,用
AVAssetReader分别读取视频轨道和深度轨道,按时间戳匹配即可拿到对应帧的RGB和深度数据
常见踩坑点
- 不要尝试把深度数据嵌入到视频的Alpha通道,会丢失浮点精度,也不符合标准格式规范
- 深度轨道编码不能用H.264,H.264不支持浮点像素格式,必须使用HEVC编码
- 如果出现深度帧写入失败,优先检查像素格式是否和输出配置匹配,以及写入的时间戳是否单调递增
内容的提问来源于stack exchange,提问作者Anonymous Panda
相关产品推荐
相关产品推荐

