
# カメラの操作

## CameraVideoCapturer と AVCaptureDevice

Sora iOS SDK では、カメラの操作は `CameraVideoCapturer` を通して行います (以下、「キャプチャー」と表します) 。
キャプチャーはカメラを表す `AVCaptureDevice` と 1 対 1 で対応し、端末が搭載するカメラの数だけキャプチャーが存在 (あるいは生成) します。
デフォルトの設定では、前面カメラと背面カメラそれぞれの `AVCaptureDevice` に対応する 2 つのキャプチャーを用意しています。
前面カメラのキャプチャーは `front` 静的プロパティで、背面カメラのキャプチャーは `back` 静的プロパティで取得できます。

利用可能な `AVCaptureDevice` のリストは `CameraVideoCapturer.devices` 静的プロパティで取得できます。

## AVCaptureSession

キャプチャーの映像は `AVCaptureSession` によって管理されます。
`AVCaptureSession` は `captureSession` プロパティで取得できます。

## 映像の流れ

キャプチャーが取得した映像は、映像フレームに変換されて `stream` プロパティのストリームに渡されます。
`stream` プロパティに `nil` をセットすれば、キャプチャーの映像はいずれのストリームにも流れません (カメラは停止されません) 。

デフォルトの設定では、Sora に接続すると自動的にカメラが起動され、配信ストリームがキャプチャーにセットされます。

## 解像度と最大フレームレート

カメラ (`AVCaptureDevice`) は複数の解像度と最大フレームレートの組み合わせに対応しています。
この情報は `AVCaptureDevice.Format` に含まれます (以下、「フォーマット」と表します) 。
フォーマットの内容は `AVCaptureDevice` ごとに異なります。
いずれの端末も前面カメラと背面カメラで解像度と最大フレームレートが異なります。

カメラの起動にはフォーマットとフレームレートを指定する必要があります。
`AVCaptureDevice` が対応するフォーマットを取得するには `format(width:height:for:frameRate:)` 静的メソッドを使います。
最も近い解像度でかつ指定したフレームレートに対応するフォーマットを取得できます。
必ずしも希望する解像度が使えるとは限りません。また、フォーマットが対応していないフレームレートを指定した場合は無視されます。適切な値を設定するよう注意してください。

カメラの起動時に指定するフレームレートは、フォーマットが対応する最大フレームレート以下である必要があります。
たとえば、最大フレームレートが 30fps であるフォーマットを使う場合、起動時に指定するフレームレートは 30fps 以下でなければなりません。
フォーマットで使用できる最大フレームレートは `maxFrameRate(_:for:)` 静的メソッドで取得できます。
このメソッドは、指定したフォーマットが対応するフレームレートの幅のうち、指定したフレームレートに最も近いフレームレートを返します。
たとえば 40fps を指定した場合、指定したフォーマットが 40fps 以上に対応していれば 40fps を返します。
40fps に対応していなければ、対応する最大フレームレート (30fps など) を返します。

## カメラの操作が行われるディスパッチキュー

カメラの操作は専用のディスパッチキューで行われます。

## カメラの起動と停止

### カメラを起動する

デフォルトの設定では、カメラは配信開始時に自動的に起動します。
このときのカメラの設定は `Configuration` に指定する `CameraSettings` によります。
`CameraSettings` では次の項目を指定できます:

- 解像度 (`resolution` プロパティ)
- フレームレート (`frameRate` プロパティ)
- 配信開始時のカメラの位置 (`position` プロパティ)
- カメラの起動の有無 (`isEnabled` プロパティ)

配信開始時にカメラを停止しておき、あとから任意のタイミングで起動する場合は `isEnabled` に `false` を指定します。

手動でカメラを起動する手順を次に示します:

1. 起動したいカメラに対応する `AVCaptureDevice` を取得します。
2. 使用するフォーマットを決めます。使用可能なフォーマットは `format(width:height:for:frameRate:)` で取得できます。
3. 使用するフレームレートを決めます。2. で取得したフォーマットと希望するフレームレートを `maxFrameRate(_:for:)` の引数に与えて実行すると、その値を上限とする使用可能なフレームレートを取得できます。もし 60fps を指定しても、フォーマットが対応する上限が 30fps であれば 30fps を返すので注意してください。
4. `start(format:frameRate:completionHandler:)`) を実行してカメラを起動します。起動処理の終了後、起動の成否に関わらず `completionHandler:` が実行されます。

### カメラを停止・再起動する

映像の配信が終了すると、起動中のカメラも自動的に停止します。
(映像を配信しない場合でも `CameraSettings.isEnabled` が `true` であれば停止します) 。
起動中のカメラを一時的に停止するには `stop(completionHandler:)` を実行します。
停止したカメラを再起動するには `start(format:frameRate:completionHandler:)` か `restart(completionHandler:)` を実行します。
`restart(completionHandler:)` は停止前と同じ設定でカメラを再起動します。

また、 `MediaChannel.setVideoHardMute(Bool)` を利用する方法もあります。
[映像のハードミュート](mute.html#52a189) をご確認ください。

## 起動中のカメラの設定を変更する

起動中のカメラのフォーマットとフレームレートは `change(format:frameRate:completionHandler:)` で変更できます。
このメソッドは指定した設定でカメラを再起動します。

## カメラの位置を切り替える

カメラの前面と背面を切り替えるには `flip(_:completionHandler:)` 静的メソッドを実行します。
このメソッドは起動中のカメラの位置と反対のカメラを起動します。
このときに使われるフォーマットとフレームレートは、起動中のカメラの設定に近い値が検索されます。
任意の設定を使いたい場合は、起動中のカメラを停止してから任意のカメラを起動してください。

## カメラの映像を加工する

`CameraVideoCapturerHandlers` イベントハンドラの `onCapture` を実装します (`handlers` プロパティでイベントハンドラにアクセスできます) 。
`onCapture` にセットするクロージャーはカメラの映像フレームを受け取り、ストリームに渡すための映像フレームを返す必要があります。

## その他の操作

その他の操作は `AVCaptureDevice` を利用してください。
