CameraVideoCapturerHandlers

public class CameraVideoCapturerHandlers

CameraVideoCapturer のイベントハンドラです。

イベントハンドラのプロパティの get / set は、プロパティごとの HandlerStorage が持つ NSLock で 排他します。 利用する任意の executor からの設定と、配送する executor (onCapture は camera の capture session queue の frame callback、onStart / onStop は start / stop / restart / change / flip の 完了通知) からの読み取りが並行してもデータ競合しません。配送側は lock を解放してから取得済みの closure を呼びます (HandlerStorage の doc 参照)。

CameraVideoCapturer.handlers は型全体で共有する storage が、差し替えない限り同じ instance を 返すため、CameraVideoCapturer.handlers.onCapture = ... のような in-place 変更もその instance の HandlerStorage が排他します (CameraHandlersStorage が排他するのは参照の get / set だけです)。

呼び出し元のスレッドは保証されない。UI 更新や共有状態の変更は main queue / main actor へ 束ねること。

配送のたびにプロパティを読むため、接続の途中で設定を変更しても次の配送から反映される (プロパティごとの storage が排他するのは読み書きだけであり、配送側は lock を解放してから 取得済みの closure を呼ぶ)。

Swift 6 言語モードで @MainActor の文脈からハンドラーを設定する場合は、クロージャに @Sendable を付けるか nonisolated な関数へ処理を分離して隔離を外す。CameraVideoCapturer は Sendable のためそのまま main actor へ渡せる。VideoFrame は Sendable ではなく、onCapture は返した frame の所有権を SDK へ移すため、frame を Task へ運ばずに返却前に処理を終えること (nonisolated(unsafe) let で frame を main actor へ運ぶと、返却の後に frame を参照・変更する 経路が生まれる)。

カメラのイベントは新しい購読 API (Sora.subscribeEvents(bufferingPolicy:) / MediaChannel.subscribeEvents(bufferingPolicy:)) の対象外であり、従来どおりこの handler で 受け取る。

  • 生成された映像フレームを受け取ります。 返した映像フレームがストリームに渡されます。

    このクロージャーは libwebrtc の capture session queue 上で、MediaStream.send(videoFrame:) の ingress より前に呼ばれます。ingress 以降の処理 (VideoFilter の実行と RTCVideoSource への 配送) は frame ごとの直列 executor 上で行われます。

    返した frame の所有権は SDK へ移ります。MediaStream.send(videoFrame:) は配送の完了を 待たないため、返した後にその frame と保持する画素データを参照・変更しないでください。

    Declaration

    Swift

    public var onCapture: ((CameraVideoCapturer, VideoFrame) -> VideoFrame)? { get set }
  • CameraVideoCapturer.start(format:frameRate:completionHandler) の completionHandler の後に実行されます。 また CameraVideoCapturer.restart(completionHandler) / CameraVideoCapturer.change(format:frameRate:completionHandler) / CameraVideoCapturer.flip(_:completionHandler) でも、内部の start が成功した場合に呼び出されます。 内部の start は非同期に開始され、その完了通知は stop の完了通知より後に届くため、 restart / change / flip では onStop の後に onStart が呼ばれます。

    Declaration

    Swift

    public var onStart: ((CameraVideoCapturer) -> Void)? { get set }
  • CameraVideoCapturer.stop(completionHandler) 内で completionHandler の後に実行されます。 また CameraVideoCapturer.restart(completionHandler) / CameraVideoCapturer.change(format:frameRate:completionHandler) / CameraVideoCapturer.flip(_:completionHandler) でも、内部の stop が完了した場合に呼び出されます。 注意点については、 onStart のコメントを参照してください。

    Declaration

    Swift

    public var onStop: ((CameraVideoCapturer) -> Void)? { get set }
  • CameraVideoCapturer のイベントハンドラを初期化します。

    Declaration

    Swift

    public init()