😺

(Swift)iPhoneのライトを点灯した状態でAVCaptureVideoDataOutputを利用する方法

2024/07/22に公開

はじめに

お急ぎの方のため、先に結論から。

  1. AVCaptureVideoDataOutputを使用中にライトを点灯させるにはAVCaptureSessionにAVCapturePhotoOutputを追加してください。
  2. 必要になる処理はAVCapturePhotoOutputをセッションに追加するだけです。なにかパラメータを設定したりデリゲートを実装するなどの対応は不要です。
  3. iOS 15からiOS 17までのiPhone実機でライトが点灯することを確認しました。おそらくiOS 15以前の古いiOSも同様に動作するはずです。
  4. ビデオ処理中かつライト点灯中にコントロールセンターを開くとライトが消灯かつ非活性としてアイコンが表示されます。アイコンの表示がライトの状態と連動していないため不具合と思われます。
  5. 可能性はかなり低いと思いますが、今後iOSが更新されて、この回避策が利用できなくなるかもしれません。ライトの点灯機能が必須なアプリを開発する場合は実機で動作確認することをおすすめします。

それでは本題に進みましょう。

サンプルアプリ

ライトを点灯した状態でカメラの映像をリアルタイムに処理するサンプルアプリを作成しました。実装方法だけ知りたい方は以下のリポジトリにあるCameraManager.swiftを参考にしてください。

https://github.com/moutend/UsingTorchWithVideoDataOutput

カメラ使用中はライトを点灯できない?

通常、カメラを使用中の場合はライトを点灯できません。この挙動はiOS標準のカメラアプリも同様です。

ライトの制限についてはAVCaptureVideoDataOutputで映像を処理する場合も適用されます。UIにカメラのプレビュー映像を表示しているかは関係なく、AVCaptureSessionが設定された時点でライトは点灯できなくなります。

ライトを点灯できるパターン

例外的に出力先として以下いずれかを設定した場合はライトを点灯できます。

  1. AVCapturePhotoOutput
  2. AVCaptureMovieFileOutput

さて、AVCaptureSessionは静止画と動画の出力先を同時に指定できます。そこでAVCapturePhotoOutputをセッションに追加すると、本来は点灯できないはずのライトが映像処理中に点灯できる、という仕組みです。

なお、AVCaptureVideoDataOutputとAVCaptureMovieFileOutputは同時に利用できません。正確にはセッションの追加処理は成功しますが、AVCaptureVideoDataOutputSampleBufferDelegateが実行されません。

(余談その1)カメラ使用中にライトを点灯できるアプリの例

先ほど、カメラ使用中はライトを点灯できないと説明しました。しかし、それは一般的な話であって、探してみるとカメラ使用中にライトを点灯できるアプリがいくつかあります。

例えばiOS標準の拡大鏡アプリはカメラ映像のプレビュー中にライトを点灯できます。点灯・消灯だけではなくライトの明るさも自由に調整できます。

サードパーティのアプリにもライトを点灯できるものがあります。例えばMicrosoftのSeeing AIアプリはカメラ映像のプレビュー中にライトを点灯できます。

(余談その2)setTorchModeOnメソッドの挙動

AVCaptureVideoDataOutputのみセッションに追加した状態で.setTorchModeOn(level: 1.0)を実行すると、メソッドの呼び出しは成功します。しかし、実際にはライトは点灯しません。

なお、、メソッドの呼び出し後に.torchLevelプロパティの値を取得すると0.0のまま変化ありません。この挙動を利用して、メソッドの呼び出しは成功したのにライトが点灯できなかった、という状況を検出できます。

参考資料

  1. Lighting - Apple Developer Documentation
  2. AVCapturePhotoOutput - Apple Developer Documentation
  3. AVCaptureVideoDataOutput - Apple Developer Documentation

Discussion