Ran Engel

問題

iOS SimulatorもAndroid Emulatorも本物のカメラハードウェアを搭載していません。AVCaptureSessionを使用するQRスキャナー、文書撮影フロー、AR機能などを開発する場合、次の2つのワークフローのいずれかを選択することになります。

  • カメラを使用する変更があるたびに、物理デバイスだけでテストする
  • Simulator上で空白/シミュレートされたカメラ映像を見つめ、うまくいくことを願う

どちらも迅速にイテレーションを行う際には理想的ではありません。

解決策:CamBridge

CamBridgeは、2つの要素からなる小さなオープンソースツールです。

CamBridgeMenuBar — Macのメニューバーアプリで、Macのウェブカメラをキャプチャし、ローカルホスト上でJPEGフレームを長さプレフィックス付きでストリーミングします。ターミナルやビルド手順は不要で、ダウンロードして開き、カメラアクセスを許可するだけで完了します。

CamBridgeKit — Xcodeプロジェクトに追加するSwiftパッケージです。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

メニューバーアプリを1回実行し、パッケージを追加するだけで、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に記載されており、独自のクライアントを構築したい場合に参照できます。意図的にシンプルに設計されており、ローカルホスト上でスムーズにストリーミングするための長さプレフィックス付きJPEGフレームをTCPソケット経由で送信するプロトコルです。これは開発/テストツールであり、動画パイプラインではないため、画質よりもスムーズなストリーミングを重視しています。

はじめに

  1. ReleasesからCamBridgeMenuBar.appをダウンロードし、解凍して開きます。
  2. XcodeでFile → Add Package Dependencies…を選択し、リポジトリURLを追加してCamBridgeKitを選択します。
  3. 通常AVCaptureSessionを使用する箇所をCamBridgeCaptureSessionに置き換えます。

詳細な手順: https://github.com/engelon/CamBridge

今後の予定

iOS Simulator対応は完了しており、次はAndroid Emulator対応がロードマップにあります(サーバーは既に複数のクライアントを同時にサポートしているため、Android対応が完了すれば両方を同時にフィードできます)。

MITライセンスで提供されています。カメラ機能を定期的にテストしており、このツールでデバイステストのループを省略できた場合は、ぜひご連絡ください。IssueとPRはオープンです。