AVFoundationでカメラ撮影機能を実装してつまずいた話

AVFoundationでカメラ撮影機能を実装してつまずいた話 トラブルシューティング

WatchConnectivityでApple Watchとデータ連携する実装を終えた後、アプリ内で独自の撮影画面を作りたいと考え、AVFoundationによるカメラ撮影機能に挑戦しました。

1. UIImagePickerControllerと同じ感覚で扱おうとした

以前、写真ライブラリへのアクセスで使ったPHPickerと同じような感覚で、簡単なAPI呼び出しだけで撮影画面が作れると思い込んでいました。

let captureSession = AVCaptureSession()

このコードだけでは何も表示されず、撮影セッションの構築・入力デバイスの追加・プレビュー表示という複数の手順を自分で組み立てる必要があると分かりました。標準の写真選択とは異なり、カメラ制御そのものを扱うための、より低レイヤーなフレームワークだと理解しました。

2. プレビューレイヤーのサイズ調整を忘れて映像が崩れた

カメラ映像を画面に表示できるようになったものの、レイアウトを変更するたびに映像が引き伸ばされたり歪んだりする問題に悩まされました。

previewLayer.frame = view.bounds

AVCaptureVideoPreviewLayerはビューのサイズ変更に自動追従しないため、ビューのレイアウト変更のたびに明示的にframeを更新する必要があると分かりました。viewDidLayoutSubviewsなどのタイミングでこの処理を入れることで、正しい表示に修正できました。

3. デバイスの向きが変わると映像の向きがおかしくなった

画面を横向きに回転させると、プレビュー映像だけが縦向きのままになってしまう現象に遭遇しました。

気づいたこと:
previewLayer.connection?.videoOrientation の更新が必要

デバイスの向きの変化は自動的に映像の向きには反映されず、videoOrientationプロパティを画面回転のタイミングに合わせて自分で更新する必要があると分かりました。この設定を追加したことで、回転時も正しい向きで映像が表示されるようになりました。

4. シミュレータでカメラが起動せず原因調査に時間をかけた

実装が一通り終わったと思い、シミュレータで動作確認しようとしたところ、真っ黒な画面のまま何も表示されませんでした。

確認したこと:
シミュレータにはカメラハードウェアが存在しない

コードの不具合を疑って長時間調べていましたが、そもそもシミュレータにはカメラという物理デバイスが存在せず、AVCaptureDeviceの取得自体が失敗する仕組みだと分かりました。カメラ機能の動作確認は実機で行う必要があると理解し、無駄な調査時間を減らせるようになりました。

まとめ

  • AVFoundationでのカメラ撮影は、セッション構築・入力追加・プレビュー表示を自分で組み立てる低レイヤーな仕組み
  • プレビューレイヤーはビューのサイズ変更に自動追従しないため、レイアウト変更時にframeを更新する必要がある
  • 画面回転時の映像の向きはvideoOrientationを自分で更新しないと崩れたままになる
  • シミュレータにはカメラハードウェアがなく、動作確認は実機で行う必要がある

標準の写真選択機能とは違い、カメラという物理デバイスを直接扱う分、レイアウトや向きまで自分で面倒を見る必要があると実感した実装でした。


本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。

コメント

タイトルとURLをコピーしました