Support the Center Stage front camera in your iOS app
Graphics, Games & Media 进阶 17m

让你的 iOS App 支持 Center Stage 前置摄像头

Support the Center Stage front camera in your iOS app

2026年6月10日

在 Apple 官方观看视频

一句话判断

前置摄像头换成方形传感器后,dynamicAspectRatio 让相机 App 终于能在不中断预览的情况下,无缝且无裁切地切换横竖屏构图了。

这场 Session 讲了什么

以前用前置摄像头拍合照或视频,最怕的就是画幅不够。老款 iPhone 的前置传感器是 4:3 的矩形,横屏和竖屏切换时,要么画面被严重裁切,要么得重建 AVCaptureSession 导致预览黑屏卡顿。而且视野角不够大,人稍微动一下就出画了。

iPhone 17 系列(包括 iPhone Air)直接换了硬件,上了一块 95 度超广角的正方形图像传感器 (square image sensor)。配合 iOS 26 新增的 dynamicAspectRatio 属性,App 现在可以直接在 1:1、4:3、16:9 等 5 种比例间丝滑切换,底层直接从正方形传感器里裁切,完全不需要重启 Session。

这对第三方相机 App 和视频会议软件是巨大的利好。你不用再自己写复杂的人脸追踪和画面裁切逻辑,直接接入 AVCaptureSmartFramingMonitor,系统就会把基于人脸和视线检测的构图建议(长宽比+缩放因子)喂给你。视频通话场景也能直接调用系统级的 Center Stage (人物居中) 能力,还能开启低延迟防抖。

值得深挖的点

正方形传感器与 dynamicAspectRatio 的降维打击

Apple 这次在硬件上把前置摄像头从矩形换成正方形,是个非常聪明的“力大砖飞”策略。软件层面再怎么优化裁切,也突破不了物理传感器的边界。正方形传感器意味着无论手机怎么转,物理可用画幅都是一样的。

反映在 API 上,就是 dynamicAspectRatio。以前切换长宽比,开发者得去 AVCaptureDevice.formats 里找对应的分辨率,然后重新配置 AVCaptureSession,这会导致预览流中断。现在只要设置 camera.dynamicAspectRatio = .ratio16x9,底层直接改变 crop region,预览无缝过渡。

不过这里有个 Trade-off 需要留意:最高分辨率(4032)的照片格式只支持 3:4 和 4:3。如果你想要 16:9 或 1:1,最高只能用到较低的分辨率。在写 UI 逻辑时,如果用户切到 16:9,记得动态调整最高可用分辨率的预期,别硬拿 4032 去套导致崩溃或降级。

把 Center Stage 的控制权交还给 App

以前系统的 Center Stage 是个黑盒,App 只能选择“开”或“关”,画面怎么裁切、怎么平移,全由系统接管,App 拿不到中间状态。这次推出的 AVCaptureSmartFramingMonitor 彻底改变了这个局面。

它不直接修改画面,而是通过 KVO (Key-Value Observing) 吐出 recommendedFraming(包含建议的 aspect ratio 和 zoom factor)。App 拿到这些建议后,可以自己决定是平滑过渡、加个动画,还是结合自家的 UI 做二次处理。这种“系统做苦力(人脸/视线检测),App 做决策”的设计,比直接丢一个处理好的黑盒视频流灵活太多。对于想做差异化相机 UI 的团队来说,这个 API 是真正的杀手锏。

代码片段

1. 无缝切换长宽比

场景:用户点击“旋转”按钮,在不中断预览的情况下从 4:3 切换到 16:9。

// 查找支持动态长宽比的 Center Stage 前置摄像头
let discovery = AVCaptureDevice.DiscoverySession(
    deviceTypes: [.builtInUltraWideCamera], 
    mediaType: .video, 
    position: .front
)
guard let camera = discovery.devices.first else { return }

// 找到支持 16:9 的格式并激活
for format in camera.formats {
    if format.supportedDynamicAspectRatios.contains(.ratio16x9) {
        try? camera.lockForConfiguration()
        camera.activeFormat = format
        // 直接修改 dynamicAspectRatio,无需重启 session
        camera.dynamicAspectRatio = .ratio16x9 
        camera.unlockForConfiguration()
        break
    }
}

坑:修改 dynamicAspectRatio 会返回一个时间戳,代表变更生效的时机。如果是做严格的音视频同步,得用这个时间戳去对齐,别直接假设它瞬间生效。

2. 监听系统智能构图建议

场景:开启自动构图,当画面中人数变化时,根据系统建议自动调整缩放和画幅。

// 确保当前 format 支持智能构图
guard let format = camera.formats.first(where: { $0.isSmartFramingSupported }) else { return }
try? camera.lockForConfiguration()
camera.activeFormat = format

let monitor = camera.smartFramingMonitor!
// 开启所有支持的构图模式
monitor.enabledFramings = monitor.supportedFramings
camera.unlockForConfiguration()

// 监听构图建议
observation = monitor.observe(\.recommendedFraming, options: .new) { monitor, _ in
    guard let recommendation = monitor.recommendedFraming else { return }
    try? camera.lockForConfiguration()
    // 先改长宽比,再改缩放,保证过渡平滑
    camera.dynamicAspectRatio = recommendation.aspectRatio
    camera.videoZoomFactor = recommendation.zoomFactor
    camera.unlockForConfiguration()
}

坑:应用建议时,一定要先设置 aspectRatio 再设置 videoZoomFactor,顺序反了会导致预览画面出现奇怪的跳变。

最佳实践

老项目迁移时,最容易被坑的是传感器方向补偿 (Sensor orientation compensation)。iPhone 17 的前置传感器物理安装方向变成了竖屏 (portrait),而老款 iPhone 是横屏左 (landscape left)。如果你以前的代码硬编码了旋转角度,拍出来的照片会是歪的。

好消息是,AVCapturePhotoOutput 默认开启了 cameraSensorOrientationCompensationEnabled,会自动把照片转回横屏左并修改 EXIF,对 JPEG 和 HEIC 完全透明。但如果你拍的是 Bayer RAW 或 Apple ProRAW,系统不会自动补偿。处理 RAW 格式时,必须自己用 AVCaptureRotationCoordinator 去处理旋转。

新项目建议直接拥抱 AVCaptureSmartFramingMonitor。不要自己去跑 Vision 框架做人脸检测然后算裁切框了,不仅耗电,而且延迟比系统底层的 Center Stage 高得多。把算力省下来做滤镜或 UI 交互。

还有什么值得关注

  • 视频通话的 Cooperative 模式AVCaptureDevice.centerStageControlMode = .cooperative 允许你的 App 和系统的 Center Stage 协同工作,而不是互相抢占控制权。
  • 低延迟防抖 (Low-latency stabilization):针对视频会议场景新增的防抖模式,牺牲了一点点裁切边距,换取了更低的画面延迟,非常适合实时通话。
  • 物理居中的镜头:新硬件把前置摄像头移到了屏幕正上方居中,这解决了以前横屏视频通话时“眼神偏离”的问题,App 不需要再做软件层面的眼神接触补偿了。
AVFoundation Center Stage Camera iOS 26