Discover Continuity Camera for tvOS
Media & Web 进阶 20m

探索 tvOS 的连续互通相机

Discover Continuity Camera for tvOS

2023年6月5日

在 Apple 官方观看视频

一句话判断

tvOS 17 引入了连续互通相机——你的 Apple TV 应用现在可以把 iPhone 或 iPad 当作摄像头和麦克风使用,视频会议、内容创作、直播等全新品类的大门就此打开。

这场 Session 讲了什么

tvOS 团队的 Kevin Tulod 和 Core Audio 团队的 Somesh Ganesh 联合介绍了 tvOS 17 中连续互通相机和麦克风的实现方式。

2022 年 macOS Ventura 首先引入了连续互通相机,让 iPhone 可以作为 Mac 的网络摄像头。现在同样的能力来到了 Apple TV——用户只需将 iPhone 靠近 Apple TV,就能把设备的摄像头和麦克风作为 tvOS 应用的输入源。

从 API 层面看,tvOS 17 现在支持 iOS 上已有的全套 AVFoundation 捕获 API:AVCaptureDevice、AVCaptureDeviceInput、AVCaptureSession、AVCaptureOutput 以及 AVCaptureVideoPreviewLayer。如果你已经有一个使用这些 API 的 iOS 应用,大部分代码可以直接在 tvOS 上运行。

关键差异在于设备发现机制。Apple TV 是共享设备,没有内置摄像头,所以需要通过新的 AVContinuityDevicePickerViewController 来发现和选择可用的连续互通设备。这个控制器会列出所有登录了 Apple TV 的用户的可用设备,还支持访客配对。

Session 还详细讲解了 Core Audio 方面的 API 支持,包括高保真音频捕获、多声道处理等。

值得深挖的点

共享设备的独特挑战:与 iPhone 这种个人设备不同,Apple TV 是多人共享的。任何拥有兼容设备的人——包括访客——都可以将自己的设备作为连续互通相机使用。这意味着相机可能随时出现或消失,你的应用必须能优雅地处理设备的热插拔。

设备发现的两步流程:先用 AVCaptureDevice 检查是否有已连接的捕获设备。如果有,直接使用;如果没有,弹出 AVContinuityDevicePickerViewController 让用户选择。选中后 tvOS 会向用户的其他设备发送确认请求,用户在 iPhone 或 iPad 上接受后连接才建立。

iOS 到 tvOS 的迁移成本极低:Session 用一个已有的 iOS 相机应用做了现场演示。添加 tvOS 支持只需要在 Xcode 中将 Apple TV 添加为目标平台,然后处理设备发现逻辑。所有 AVCapture 相关代码无需修改。

Core Audio 的完整支持:不只是视频,tvOS 17 也完整支持了音频捕获 API。从简单的录音到复杂的多声道音频处理,AVFAudio 和 AudioToolbox 的能力全部可用。

代码片段

// 设备发现流程 - 检查可用设备并展示选择器
func setupCaptureDevices() {
    let discoverySession = AVCaptureDevice.DiscoverySession(
        deviceTypes: [.builtInWideAngleCamera],
        mediaType: .video,
        position: .unspecified
    )

    if let device = discoverySession.devices.first {
        // 已有可用设备,直接使用
        startCaptureSession(with: device)
    } else {
        // 没有可用设备,展示设备选择器
        presentDevicePicker()
    }
}

// 展示连续互通设备选择器
func presentDevicePicker() {
    let picker = AVContinuityDevicePickerViewController()
    picker.delegate = self
    present(picker, animated: true)
}

// 处理用户选择的设备
func continuityDevicePicker(
    _ picker: AVContinuityDevicePickerViewController,
    didSelect device: AVCaptureDevice
) {
    startCaptureSession(with: device)
}
// AVCaptureSession 配置 - 与 iOS 代码完全一致
class CaptureSession {
    let session = AVCaptureSession()

    func setActiveVideoInput(_ device: AVCaptureDevice) {
        session.beginConfiguration()
        // 移除旧的输入
        session.inputs.forEach { session.removeInput($0) }
        // 添加新的输入
        guard let input = try? AVCaptureDeviceInput(device: device) else { return }
        session.addInput(input)
        session.commitConfiguration()
        session.startRunning()
    }
}

// SwiftUI 中显示相机预览
struct CameraPreview: UIViewRepresentable {
    let previewLayer: AVCaptureVideoPreviewLayer

    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        view.layer.addSublayer(previewLayer)
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        previewLayer.frame = uiView.bounds
    }
}

最佳实践

  • 始终先检查已有设备:在弹出设备选择器之前,先用 DiscoverySession 检查是否已有可用设备。如果用户之前已经配对过,就没必要再展示选择 UI。
  • 处理好设备的动态变化:连续互通设备可能随时断开。监听设备可用性变化通知,在设备消失时暂停捕获会话,在设备重新出现时自动恢复。
  • Info.plist 中设置权限描述:camera 和 microphone usage description 是必需的。这是用户授权时看到的文案,要清楚说明为什么需要访问这些设备。
  • 考虑访客场景:Apple TV 经常出现在共享空间(客厅、度假租赁),访客配对功能让你的应用可以在这些场景下使用。
  • 音频捕获注意采样率配置:使用 Core Audio API 时,根据应用需求选择合适的采样率和缓冲区大小,避免不必要的延迟。

还有什么值得关注

  • 连续互通相机为 tvOS 开辟了全新的应用品类:视频会议应用、健身应用的实时姿势识别、AR 游戏、社交直播等——这些在以前不可能出现在 Apple TV 上。
  • Session 提到 tvOS 上的 AVCapture API 和 iOS 完全一致,这意味着你可以用同一套代码库同时服务两个平台。
  • 设备发现的安全设计值得注意——每次连接都需要用户在 iPhone 上主动确认,防止未经授权的设备偷偷使用摄像头。
  • 如果你的应用已经在 iOS 上使用了 AVFoundation,迁移到 tvOS 的主要工作量在于设备发现 UI 和设备热插拔处理,核心捕获逻辑无需修改。
  • Core Audio 部分提到了低延迟音频处理的能力,这对于实时通信类应用至关重要。
WWDC 2023