Highlight
iOS 15.4 和 iOS 16 为 AVFoundation 相机捕获带来四项核心改进:LiDAR Scanner 深度数据可通过 AVFoundation 直接访问;人脸驱动的自动对焦和自动曝光默认启用;支持同时配置多个 AVCaptureVideoDataOutput 分别优化预览和录制;iPad 多任务模式下相机不再被强制中断。
核心内容
LiDAR 深度相机进入 AVFoundation
以前想用 LiDAR Scanner 的深度数据,只能通过 ARKit。ARKit 适合 AR 应用,但分辨率只有 256x192,且面向场景几何和物体放置等 AR 场景设计。
iOS 15.4 新增了 .builtInLiDARDepthCamera 设备类型,让 AVFoundation 也能直接访问 LiDAR。这对摄影和视频类应用意义重大:深度分辨率提升到 768x576(是 ARKit 的两倍以上),还能嵌入高分辨率照片中。
LiDAR Depth Camera 的工作原理是:LiDAR 发射光线到环境,收集反射光,通过测量光的飞行时间计算深度。同时,系统会把 LiDAR 的稀疏输出与广角摄像头的彩色图像通过机器学习模型融合,生成密集的深度图。
人脸驱动的对焦和曝光
专业相机都有人脸追踪对焦功能。iOS 15.4 把这个能力带到了所有应用,而且默认开启。
没有这个功能时,相机可能对焦在背景上,人脸模糊。开启后,人脸会保持清晰,转身离开时相机自动切换到背景对焦。逆光场景下,曝光系统会优先保证人脸亮度,即使背景过曝。
多视频输出优化预览与录制
一个常见的矛盾:预览需要低延迟、小尺寸;录制需要高分辨率、高质量效果。以前只有一个 AVCaptureVideoDataOutput,不得不折中。
iOS 16 支持同时添加多个 AVCaptureVideoDataOutput,每个可以独立配置分辨率、防抖、方向和像素格式。预览用一个低分辨率、无防抖的输出;录制用 4K、带电影级防抖的输出。
iPad 多任务不再中断相机
以前 iPad 进入分屏或 Slide Over 时,相机会被系统强制中断。iOS 16 开始,AVCaptureSession 可以在多任务模式下继续使用相机。
系统会在检测到多任务录制完成后弹出一个一次性提示,告知用户视频质量可能降低。应用也可以通过 isMultitaskingCameraAccessEnabled 属性检查和控制这个行为。
详细内容
LiDAR Depth Camera 的设备配置
(02:21)
import AVFoundation
// 发现 LiDAR Depth Camera
guard let device = AVCaptureDevice.default(.builtInLiDARDepthCamera, for: .video, position: .back) else {
// 设备不支持 LiDAR Depth Camera
return
}
// 创建输入和会话
let input = try AVCaptureDeviceInput(device: device)
let session = AVCaptureSession()
session.addInput(input)
// 添加深度数据输出
let depthOutput = AVCaptureDepthDataOutput()
depthOutput.setDelegate(self, callbackQueue: DispatchQueue(label: "depthQueue"))
session.addOutput(depthOutput)
// 添加照片输出(带深度)
let photoOutput = AVCapturePhotoOutput()
session.addOutput(photoOutput)
关键点:
.builtInLiDARDepthCamera在 iPhone 12 Pro、iPhone 13 Pro 和第 5 代 iPad Pro 上可用- 该设备使用后置广角摄像头提供视频,LiDAR 提供深度
- 所有格式都支持深度数据交付
- 长焦和超广角摄像头可以通过
AVCaptureMultiCamSession同时使用
深度数据的过滤控制
(05:25)
// 深度数据默认是过滤的(减少噪声、填充空洞)
// 适合摄影和视频应用
// 计算机视觉应用需要原始数据,关闭过滤
depthOutput.isFilteringEnabled = false
// 在委托回调中接收深度数据
func depthDataOutput(_ output: AVCaptureDepthDataOutput,
didOutput depthData: AVDepthData,
timestamp: CMTime,
connection: AVCaptureConnection) {
// depthData.depthDataType 描述深度数据类型
// depthData.depthDataAccuracy 描述精度(absolute 或 relative)
// depthData.isDepthDataFiltered 描述是否经过过滤
let pixelBuffer = depthData.depthDataMap
// 处理深度像素缓冲
}
关键点:
- 过滤默认开启,适合渲染特效
- 关闭过滤后,LiDAR Depth Camera 会排除低置信度点
- 计算机视觉任务(如测量)应该用非过滤数据
- 深度数据类型包括绝对深度(LiDAR)和相对视差深度(TrueDepth/Dual Camera)
人脸驱动对焦和曝光的控制
(09:04)
guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
return
}
do {
try device.lockForConfiguration()
// 关闭自动调整,才能手动控制
device.automaticallyAdjustsFaceDrivenAutoFocusEnabled = false
device.automaticallyAdjustsFaceDrivenAutoExposureEnabled = false
// 手动开启或关闭
device.isFaceDrivenAutoFocusEnabled = true
device.isFaceDrivenAutoExposureEnabled = true
device.unlockForConfiguration()
} catch {
print("Could not lock device: \(error)")
}
关键点:
- iOS 15.4 及以上、且应用链接到 iOS 15.4 SDK 时,默认开启
- 必须先关闭
automaticallyAdjusts...才能修改isEnabled状态 - 适合摄影应用和视频通话应用(如 FaceTime)
- 如果应用需要手动控制对焦/曝光,应该关闭此功能
多视频输出的配置
(11:07)
let session = AVCaptureSession()
// 预览输出:小尺寸、低延迟
let previewOutput = AVCaptureVideoDataOutput()
previewOutput.setSampleBufferDelegate(self, queue: previewQueue)
previewOutput.automaticallyConfiguresOutputBufferDimensions = false
previewOutput.deliversPreviewSizedOutputBuffers = true // 预览尺寸
session.addOutput(previewOutput)
// 录制输出:全尺寸 4K
let recordOutput = AVCaptureVideoDataOutput()
recordOutput.setSampleBufferDelegate(self, queue: recordQueue)
// 默认就是全尺寸,无需额外配置
session.addOutput(recordOutput)
// 为录制输出配置电影级防抖
if let connection = recordOutput.connection(with: .video) {
connection.preferredVideoStabilizationMode = .cinematicExtended
}
// 配置像素格式(10-bit 无损 YUV)
recordOutput.videoSettings = [
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
]
关键点:
automaticallyConfiguresOutputBufferDimensions = false是配置自定义分辨率的前提deliversPreviewSizedOutputBuffers = true输出预览尺寸(默认在 Photo preset 下已启用)- 自定义分辨率时,宽高比必须与设备 activeFormat 的宽高比一致
- 不同输出可以配置不同的防抖模式:预览用
off降低延迟,录制用cinematicExtended
多任务相机访问的配置
(15:33)
let session = AVCaptureSession()
// 检查多任务相机访问是否受支持
if session.isMultitaskingCameraAccessSupported {
session.isMultitaskingCameraAccessEnabled = true
}
// 启用后,相机不会因为多任务而被中断
// 之前会收到 "video device not available with multiple foreground apps" 的中断
关键点:
isMultitaskingCameraAccessSupported检查设备是否支持- 启用后,Split View、Slide Over、Stage Manager 模式下相机继续工作
- 系统会在多任务录制完成后显示一次性质量提示
- ARKit 不支持多任务相机访问
- 应用应该监控系统压力通知,在资源紧张时降低帧率或切换到低分辨率格式
视频通话的画中画支持
(17:23)
iOS 15 引入了视频通话画中画 API,让用户在 iPad 多任务时继续视频通话:
import AVKit
// 设置视频通话的画中画控制器
let pipController = AVPictureInPictureController(contentSource: contentSource)
pipController.canStartPictureInPictureAutomaticallyFromInline = true
关键点:
- 使用
AVPictureInPictureVideoCallViewController自定义画中画窗口内容 - 适合视频通话和视频会议应用
- 用户可以在画中画窗口中看到远程参与者,同时操作其他应用
核心启发
-
LiDAR 实时测量工具:利用 LiDAR Depth Camera 的绝对深度能力,做一个实时测量应用。用户对准物体,屏幕上直接显示距离数值。入口 API:
AVCaptureDevice.default(.builtInLiDARDepthCamera, for: .video, position: .back)+AVDepthData。 -
智能人像打光:结合 LiDAR 深度图和 RealityKit,做一个拍照时自动给人物面部补光的相机应用。深度图识别人脸位置,RealityKit 在对应位置渲染虚拟光源。入口 API:LiDAR Depth Camera +
RealityKit.PointLight。 -
专业视频录制器:同时配置两个 AVCaptureVideoDataOutput,预览用 720p 无防抖保证低延迟,录制用 4K 电影级防抖保证画质。预览时应用轻量级滤镜,录制时应用高质量特效。入口 API:
AVCaptureSession+ 多个AVCaptureVideoDataOutput。 -
iPad 多任务扫描仪:文档扫描应用支持在 Split View 模式下运行,用户一边看参考文档一边扫描。利用多任务相机访问,扫描过程不会因为切换应用而中断。入口 API:
isMultitaskingCameraAccessEnabled = true。 -
视频通话 + 笔记:视频会议应用集成画中画,用户在 iPad 上参与会议的同时可以在 Notes 中记录要点。画中画窗口始终显示远程参与者画面。入口 API:
AVPictureInPictureController+AVPictureInPictureVideoCallViewController。
关联 Session
- Explore ARKit 4 — ARKit 中的 LiDAR Scanner API 介绍
- Capturing Depth in iPhone Photography — 使用 AVFoundation 捕获深度数据的详细指南
- Adopting Picture in Picture for Video Calls — 在视频通话应用中实现画中画功能
- Accessing the camera while multitasking — 多任务场景下使用相机的最佳实践
评论
GitHub Issues · utterances