WWDC Quick Look 💓 By SwiftGGTeam
Integrate with motorized iPhone stands using DockKit

Integrate with motorized iPhone stands using DockKit

观看原视频

Highlight

DockKit 让 iPhone 成为电动相机支架的中央计算单元,任何使用 iOS 相机 API 的 App 开箱即用即可获得 360 度水平旋转和 90 度俯仰的自动主体追踪能力。开发者还可以通过 DockKit API 自定义构图对齐、指定感兴趣区域、直接控制电机,或用 Vision 框架提供自定义推理模型追踪任意物体。

核心内容

开箱即用的系统级追踪

DockKit 支架将 iPhone 相机的视野扩展到 360 度水平旋转(Yaw)和 90 度俯仰(Pitch)。用户配对手机与支架后,所有功能都在 iPhone 的系统服务中完成。

关键设计:电机控制和主体追踪在系统层处理,任何调用 iOS 相机 API 的 App 自动获得 DockKit 能力。系统相机、FiLMiC Pro 等第三方 App 无需修改代码即可使用。

支架上有简单的电源按钮、追踪开关和 LED 指示灯。LED 闪烁表示追踪活跃且主体在画面中。

01:18

系统追踪器的工作原理

DockKit 系统追踪器运行在相机处理管线中:

  • 相机帧通过 ISP 推理以 30fps 分析
  • Visual Understanding Framework 生成人脸和身体边界框
  • 多模型系统追踪器为每个人或物体生成追踪轨道
  • EKF(扩展卡尔曼滤波器)平滑推理中的间隙和错误
  • 追踪估计结合电机位置/速度反馈和手机 IMU 数据,生成最终轨迹和驱动指令

多人场景下,默认追踪主主体(绿色边界框标记)。即使有其他成员遮挡或交叉路径,统计追踪器也能纠正错误并持续追踪。

03:52

自定义构图控制

App 可以通过 DockKit API 控制视频裁剪方式。

对齐模式:选择左、中、右对齐。适合有固定 UI 叠加层(如 logo)的场景,避免主体被 artwork 遮挡。

感兴趣区域(ROI):用归一化坐标指定裁剪区域。适合视频会议等需要特定宽高比的场景,确保主体不被切掉。

07:29

自定义推理与电机控制

开发者可以:

  • 禁用系统追踪后直接用速度向量控制电机
  • 使用 Vision 框架或自定义 ML 模型提供推理结果
  • 从推理输出构建 Observation(归一化坐标的边界框)喂给 DockKit 追踪器
  • 触发内置动画(Yes、No、Wakeup、Kapow)或创建自定义动画

10:45

详细内容

注册支架状态变化

06:43

import DockKit

// 监听支架连接/断开状态
DockAccessoryManager.shared.stateEvents
    .sink { state in
        switch state {
        case .docked:
            print("iPhone 已连接到支架")
        case .undocked:
            print("iPhone 已从支架移除")
        }
    }
    .store(in: &cancellables)

关键点:

  • DockAccessoryManager.shared 是管理 DockKit 配件的单例
  • stateEvents 发布支架的连接状态变化
  • .docked 表示 iPhone 已通过 DockKit 协议连接到支架
  • 状态监听是修改追踪行为的前提条件

控制构图对齐

08:23

// 获取当前连接的支架配件
guard let accessory = DockAccessoryManager.shared.connectedAccessory else { return }

// 将主体对齐到画面右侧,为左侧的 logo 留出空间
accessory.framingMode = .right

关键点:

  • connectedAccessory 返回当前连接的 DockKit 配件
  • framingMode 有三个选项:.left.center.right
  • 默认是 .center,主体始终位于画面中央
  • 对齐模式适合有固定 UI 叠加层的场景

指定感兴趣区域

09:02

// 定义一个居中的正方形 ROI(归一化坐标,原点在左上角)
let roi = CGRect(x: 0.25, y: 0.25, width: 0.5, height: 0.5)
accessory.regionOfInterest = roi

关键点:

  • ROI 使用归一化坐标,范围 0.0 到 1.0
  • 原点在 iPhone 显示的左上角
  • 适合需要特定宽高比的场景,如视频会议的方形裁剪
  • 设置后 DockKit 会确保主体在 ROI 内正确构图

直接控制电机

10:12

// 禁用系统追踪,准备手动控制
accessory.isSystemTrackingEnabled = false

// 定义速度向量:Yaw 向右 0.2 rad/s,Pitch 向下 0.1 rad/s
let velocity = DockAccessoryVelocity(
    angularVelocity: .init(yaw: 0.2, pitch: -0.1)
)
accessory.move(withVelocity: velocity)

// 持续 2 秒
try? await Task.sleep(for: .seconds(2))

// 反向运动:向左 0.2 rad/s,向上 0.1 rad/s
let reverseVelocity = DockAccessoryVelocity(
    angularVelocity: .init(yaw: -0.2, pitch: 0.1)
)
accessory.move(withVelocity: reverseVelocity)

关键点:

  • 必须先设置 isSystemTrackingEnabled = false 才能手动控制电机
  • Yaw 控制水平旋转(左右),Pitch 控制俯仰(上下)
  • 速度单位是弧度/秒
  • move(withVelocity:) 持续运动直到收到新指令或停止命令

自定义推理:用手势追踪替代人脸追踪

13:17

import Vision

// 创建手部姿态检测请求
let handPoseRequest = VNDetectHumanHandPoseRequest()
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer)

try? handler.perform([handPoseRequest])

// 从检测结果构建 DockKit Observation
var observations: [DockKit.Observation] = []

if let results = handPoseRequest.results?.first,
   let thumbTip = try? results.recognizedPoint(.thumbTip) {
    
    // 用拇指尖位置构建边界框
    let boundingBox = CGRect(
        x: thumbTip.location.x - 0.1,
        y: thumbTip.location.y - 0.1,
        width: 0.2,
        height: 0.2
    )
    
    let observation = DockKit.Observation(
        boundingBox: boundingBox,
        type: .object
    )
    observations.append(observation)
}

// 获取相机信息并传递给 DockKit
let cameraInfo = DockKit.CameraInformation(orientation: .corrected)
accessivity.track(observations: observations, cameraInfo: cameraInfo)

关键点:

  • VNDetectHumanHandPoseRequest 检测手部关键点
  • Observation 的边界框使用归一化坐标,原点在左下角
  • type: .humanFace 会启用系统级多人追踪优化
  • type: .object 用于自定义物体追踪
  • Vision 框架的坐标系与 DockKit 一致,无需转换
  • orientation: .corrected 表示坐标已相对于屏幕左下角校正

触发内置动画

15:53

// 禁用系统追踪
accessory.isSystemTrackingEnabled = false

// 触发 Kapow 动画
accessory.animate(.kapow)

// 动画异步执行,完成后重新启用系统追踪
Task {
    try? await Task.sleep(for: .seconds(3))
    accessory.isSystemTrackingEnabled = true
}

关键点:

  • 内置动画有四种:.yes.no.wakeup.kapow
  • 动画从支架当前位置开始执行
  • 动画是异步的,不会阻塞主线程
  • 动画执行期间可以重新启用系统追踪

核心启发

1. 为直播应用添加自动追踪

做什么:在直播/视频会议 App 中集成 DockKit,让主播或演讲者自由移动而始终保持在画面中。

为什么值得做:传统直播需要专人操作云台或主播受限在固定位置。DockKit 的 360 度追踪让单人即可完成专业级跟拍。

怎么开始:无需修改相机代码,只需添加 DockKit 状态监听和构图控制。根据 App 的 UI 布局选择 .left.center.right 对齐模式。

2. 构建手势控制的互动相机

做什么:用手势识别替代人脸追踪,让支架跟随用户的手部动作。

为什么值得做:手势追踪可以用于教学演示(跟随教鞭)、健身指导(纠正姿势)、游戏交互等场景,比人脸追踪更灵活。

怎么开始:用 VNDetectHumanHandPoseRequest 检测手部关键点,构建 Observation 传给 DockKit。可以进一步用 Create ML 训练手势分类模型,识别特定手势后触发内置动画。

3. 为教育视频创建智能跟拍

做什么:在教室或培训场景中使用 DockKit 支架自动跟踪讲师,讲师在黑板上写字或走动时画面自动跟随。

为什么值得做:录制教学视频通常需要摄像师跟拍,成本高且容易跟丢。DockKit 让 iPhone 成为自动摄像师。

怎么开始:将 iPhone 放在 DockKit 支架上,用系统级追踪即可。如需在讲师靠近白板时调整构图,可用 ROI 限制追踪区域。

4. 用电机动画增强交互反馈

做什么:在 App 中用支架的物理运动作为交互反馈,如确认操作、表达情绪、引导用户注意力。

为什么值得做:物理运动是比屏幕动画更直观的反馈方式。支架的”点头”(Yes)、“摇头”(No)、“唤醒”(Wakeup)等动画可以传达明确的语义。

怎么开始:在关键交互点(如用户完成设置、收到重要通知)调用 accessory.animate(.yes) 或自定义电机运动序列。结合手势识别,可以实现”推一下”支架就摇摆的趣味交互。

关联 Session

评论

GitHub Issues · utterances