WWDC Quick Look 💓 By SwiftGGTeam
Discover advancements in iOS camera capture: Depth, focus, and multitasking

Discover advancements in iOS camera capture: Depth, focus, and multitasking

观看原视频

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

评论

GitHub Issues · utterances