Ran Engel

问题

iOS Simulator 和 Android Emulator 都没有真实的摄像头硬件。如果你正在构建涉及 AVCaptureSession 的功能——QR 扫描、文档捕捉流程、AR 特性——你将面临两种工作流:

  • 每次都要在真实设备上测试所有涉及摄像头的改动
  • 在 Simulator 中盯着空白或模拟的摄像头画面,碰运气

在快速迭代时,这两种方式都不理想。

解决方案:CamBridge

CamBridge 是一款小型开源工具,由两部分组成:

CamBridgeMenuBar —— 一款 Mac 菜单栏应用,可捕获 Mac 的摄像头画面,并通过 localhost 以长度前缀 JPEG 帧的形式进行流式传输。无需终端、无需构建步骤——下载、打开、授予摄像头权限即可使用。

CamBridgeKit —— 一个可添加到 Xcode 项目的 Swift Package。它提供了 CamBridgeCaptureSession,可作为 AVCaptureSession 的直接替代品:

  • 在有真实摄像头时使用真实摄像头
  • 在没有时自动回退到桥接的摄像头画面(正是 Simulator 的情况)

这意味着你的视图代码无需针对 Simulator 进行特定分支:

import CamBridgeKit
import SwiftUI

struct ScannerView: View {
    @StateObject private var camera = CamBridgeCaptureSession()

    var body: some View {
        CamBridgePreviewView(session: camera)
            .onAppear { camera.start() }
            .onDisappear { camera.stop() }
    }
}

Enter fullscreen mode Exit fullscreen mode

只需运行一次菜单栏应用、添加 Package,Simulator 就能获得真实的动态画面进行测试——同一套代码路径在真机和 Simulator 上都能工作,并提供 isBridged 属性以便区分当前使用的是哪种来源。

如果你已有自己的摄像头处理流程,CamBridgeClient 可通过 Combine 直接发布解码后的 CGImage 帧,因此你无需绑定到 CamBridgeCaptureSession 的 API。

底层工作原理

┌────────────────────┐        TCP, localhost         ┌──────────────────────────────┐
│  CamBridgeMenuBar    │ ─────────────────────────────▶│   iOS Simulator                │
│  (captures webcam)   │   length-prefixed JPEG frames  │   your app + CamBridgeKit      │
└────────────────────┘                                └──────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

线协议在仓库的 Docs/PROTOCOL.md 中有详细说明。如果你想自己构建客户端,可参考该文档。该协议有意保持简单——通过 TCP Socket 传输长度前缀 JPEG 帧——针对 localhost 平滑流式传输进行了优化,而非图像保真度,因为这是一款开发/测试工具,而非视频处理管道。

开始使用

  1. Releases 下载 CamBridgeMenuBar.app,解压后打开。
  2. 在 Xcode 中:选择 File → Add Package Dependencies…,添加仓库 URL,选择 CamBridgeKit
  3. 在原本使用 AVCaptureSession 的地方替换为 CamBridgeCaptureSession

完整说明:https://github.com/engelon/CamBridge

后续计划

iOS Simulator 支持已完成;Android Emulator 支持是接下来的路线图(服务器已支持多个同时连接的客户端,因此一旦该功能上线,即可同时服务两者)。

本项目采用 MIT 许可。如果你经常测试摄像头功能,且本工具能为你节省设备测试流程,我很乐意听到你的反馈——Issue 和 PR 均已开放。