WWDC Quick Look 💓 By SwiftGGTeam
Create a more responsive camera experience

Create a more responsive camera experience

观看原视频

Highlight

iOS 17 为 AVCapturePhotoOutput 引入了延迟照片处理、零快门延迟和响应式拍摄三大 API,让相机应用在保持 Deep Fusion 最高画质的同时,实现更快的连拍速度和更短的快门延迟。

核心内容

拍照时最扫兴的事,莫过于按下快门后等待处理完成才能拍下一张。Deep Fusion 带来的细节提升有目共睹,羽毛纹理、胡须细节都清晰锐利。但这个处理过程是同步的,必须完成后才能开始下一次拍摄。

01:43)在 iOS 17 之前,开发者只能在画质和速度之间做取舍。选择 quality 优先级获得最佳画质, shot-to-shot 时间就会变长。选择 balancedspeed 则牺牲画质换取速度。

Apple 今年给出的方案是:把处理推迟到相机会话结束后进行。

延迟照片处理

01:43)延迟照片处理(Deferred Photo Processing)的核心思路是:拍摄时先返回一个轻量级的代理照片(proxy photo),让用户可以继续拍摄;真正的 Deep Fusion 处理在后台完成,等用户退出相机应用后再执行。

这个代理照片被存入照片库作为占位符。当用户之后查看或分享时,系统要么按需完成处理,要么在设备空闲时在后台自动完成。

零快门延迟

16:03)另一个常见痛点是快门延迟。你按下快门时取景框里是一个画面,拍出来的却是之后的画面。在 30fps 下每帧只显示 33 毫秒,但这就足以错过最佳瞬间。

零快门延迟(Zero Shutter Lag)利用环形缓冲区保存过去的帧数据。按下快门时,相机会”回溯时间”,从缓冲区中提取按下快门那一刻的帧来合成照片。

响应式拍摄

19:44)响应式拍摄(Responsive Capture)允许拍摄阶段和处理阶段重叠。当第一张照片还在处理时,第二张照片的拍摄请求就可以开始执行。这大幅提升了连拍速度。

配合快速拍摄优先级(Fast Capture Prioritization),当检测到用户快速连拍时,系统会自动将画质从最高降至平衡档,保持稳定的 shot-to-shot 时间。

视频特效与手势反应

27:07)macOS Sonoma 将视频特效从控制中心移到了独立菜单。Portrait 和 Studio Light 效果现在可以调节强度。新增的反应特效(Reactions)支持手势触发:竖拇指、倒拇指、爱心、胜利手势等,会在视频上渲染气球、烟花、激光等动画效果。

详细内容

启用延迟照片处理

05:46)在配置 AVCapturePhotoOutput 时,检查并启用延迟处理:

// 检查是否支持延迟照片处理
if photoOutput.isAutoDeferredPhotoDeliverySupported {
    photoOutput.isAutoDeferredPhotoDeliveryEnabled = true
}

关键点:

  • isAutoDeferredPhotoDeliverySupported 检查当前设备是否支持
  • isAutoDeferredPhotoDeliveryEnabled 开启后,相机会自动判断哪些照片适合延迟处理
  • 不需要逐张设置,系统会自动处理

保存代理照片到照片库

07:42)拍摄完成后,使用新的代理回调保存照片:

func photoOutput(_ output: AVCapturePhotoOutput,
                 didFinishCapturingDeferredPhotoProxy deferredPhotoProxy: AVCaptureDeferredPhotoProxy?,
                 error: Error?) {
    guard error == nil, let proxy = deferredPhotoProxy else { return }
    
    PHPhotoLibrary.shared().performChanges {
        let request = PHAssetCreationRequest.forAsset()
        request.addResource(with: .photoProxy,
                           data: proxy.fileDataRepresentation()!,
                           options: nil)
    } completionHandler: { success, error in
        // 处理完成回调
    }
}

关键点:

  • 使用 didFinishCapturingDeferredPhotoProxy 回调接收代理照片
  • PHAssetResourceType.photoProxy 告诉 PhotoKit 这是需要延迟处理的照片
  • 必须尽快将代理数据存入照片库,避免应用被挂起后数据丢失

请求处理中的照片

09:43)当用户查看正在处理中的照片时,可以启用二次降级图像:

let options = PHImageRequestOptions()
options.allowSecondaryDegradedImage = true

PHImageManager.default().requestImage(for: asset,
                                       targetSize: targetSize,
                                       contentMode: .aspectFit,
                                       options: options) { image, info in
    if let info = info {
        if info[PHImageResultIsDegradedKey] as? Bool == true {
            // 显示中间质量的图像
        } else {
            // 显示最终图像
        }
    }
}

关键点:

  • allowSecondaryDegradedImage 会在低质量占位图和最终图之间提供一个中等质量的图像
  • 两个降级图像都会标记 PHImageResultIsDegradedKey
  • 最终图像不会有这个标记

零快门延迟

18:24)零快门延迟在 iOS 17 上默认启用,链接 iOS 17 SDK 的应用自动获得支持。如需关闭:

// 检查支持情况
if photoOutput.isZeroShutterLagSupported {
    photoOutput.isZeroShutterLagEnabled = false // 默认 true
}

关键点:

  • 仅当 isHighestPhotoQualitySupported 为 true 的 preset/format 上支持
  • 闪光灯、手动曝光、包围曝光、多摄像头同步拍摄不支持零快门延迟
  • 从点击事件到调用 capturePhoto 之间的延迟要尽量短

响应式拍摄与就绪协调器

21:31)启用响应式拍摄:

// 必须先启用零快门延迟
if photoOutput.isResponsiveCaptureSupported {
    photoOutput.isResponsiveCaptureEnabled = true
}

// 快速拍摄优先级
if photoOutput.isFastCapturePrioritizationSupported {
    photoOutput.isFastCapturePrioritizationEnabled = true
}

使用就绪协调器管理快门按钮状态:

let readinessCoordinator = AVCapturePhotoOutputReadinessCoordinator(photoOutput: photoOutput)
readinessCoordinator.delegate = self

// 拍摄前告知协调器
readinessCoordinator.startTrackingCaptureRequest(using: photoSettings)
photoOutput.capturePhoto(with: photoSettings, delegate: self)

// 实现委托方法
func readinessCoordinator(_ coordinator: AVCapturePhotoOutputReadinessCoordinator,
                         captureReadinessDidChange captureReadiness: AVCapturePhotoOutput.CaptureReadiness) {
    switch captureReadiness {
    case .ready:
        shutterButton.isEnabled = true
    case .notReadyMomentarily:
        shutterButton.isEnabled = false
    case .notReadyWaitingForCapture:
        shutterButton.isEnabled = false // 闪光灯充电中
    case .notReadyWaitingForProcessing:
        shutterButton.isEnabled = false // 处理中
    default:
        break
    }
}

关键点:

  • AVCapturePhotoOutputReadinessCoordinator 监听拍摄就绪状态变化
  • .notReadyWaitingForCapture 表示还在等待从传感器获取帧(如闪光灯场景)
  • .notReadyWaitingForProcessing 表示正在处理中
  • 即使不使用响应式拍摄,也可以使用就绪协调器

视频反应特效

29:59)在 iOS 上,应用需要通过 Info.plist 声明支持反应特效:

<key>NSCameraReactionEffectsEnabled</key>
<true/>

或者声明 VoIP 后台模式:

<key>UIBackgroundModes</key>
<array>
    <string>voip</string>
</array>

触发反应特效:

// 检查设备是否支持反应特效
if device.activeFormat.reactionEffectsSupported {
    // 触发特效
    device.performEffect(for: .thumbsUp)
}

// 获取系统图标
let imageName = AVCaptureReactionType.thumbsUp.systemImageName
let image = UIImage(systemName: imageName)

// 监听特效进行中状态
// reactionEffectsInProgress 返回 AVCaptureReactionEffectStatus 数组

关键点:

  • AVCaptureReactionType 包含 thumbsUp、thumbsDown、balloons、heart、fireworks、rain、confetti、lasers
  • systemImageName 提供对应的系统图标
  • 手势触发的特效位置可能与程序触发不同
  • 特效进行时帧率可能从 60fps 降至 30fps

核心启发

1. 为相机应用添加”专业连拍模式”

做什么:在相机应用中实现一个高速连拍模式,利用响应式拍摄 API 实现每秒 4-5 张的连拍速度。

为什么值得做:传统相机应用受限于 Deep Fusion 处理时间,连拍速度受限。响应式拍摄让处理阶段和拍摄阶段重叠,用户不再错过动作瞬间。

怎么开始:启用 isResponsiveCaptureEnabledisFastCapturePrioritizationEnabled,使用 AVCapturePhotoOutputReadinessCoordinator 管理快门按钮状态,给用户提供清晰的拍摄反馈。

2. 构建一个”零等待”相机应用

做什么:结合延迟照片处理和零快门延迟,打造一个按下快门立刻就能拍下一张的相机应用。

为什么值得做:Deep Fusion 的画质和快速连拍不再矛盾。代理照片立即可用,最终处理在后台完成。

怎么开始:在 AVCapturePhotoOutput 上启用 isAutoDeferredPhotoDeliveryEnabled,处理 didFinishCapturingDeferredPhotoProxy 回调,将代理数据存入照片库。同时零快门延迟默认开启,无需额外配置。

3. 为视频通话应用添加反应特效面板

做什么:在视频通话或直播应用中增加一个反应特效按钮面板,让用户可以发送爱心、烟花等特效。

为什么值得做:反应特效是系统级功能,无需自行实现计算机视觉和动画渲染。用户可以用手势触发,也可以通过应用内的按钮触发。

怎么开始:在 Info.plist 中声明 NSCameraReactionEffectsEnabled,使用 AVCaptureReactionType.systemImageName 获取按钮图标,调用 performEffect(for:) 触发特效。通过 KVO 监听 reactionEffectsInProgress 在远程端显示特效图标。

4. 实现智能画质自适应

做什么:根据用户的拍摄行为动态调整画质优先级。检测到快速连拍时自动降低画质保持速度,单张拍摄时保持最高画质。

为什么值得做:isFastCapturePrioritizationEnabled 已经内置了这个逻辑,但你可以在 UI 层给用户更多控制权。

怎么开始:观察 AVCapturePhotoOutputReadinessCoordinator 的状态变化,结合用户的拍摄频率,在设置中提供”速度优先”和”画质优先”选项。

关联 Session

评论

GitHub Issues · utterances