View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

WWDC25に戻る

  • 概要
  • トランスクリプト
  • コード
  • キャプチャコントロールによるカメラ体験の向上

    カメラ体験でのキャプチャコントロールをカスタマイズする方法を学びましょう。新しいAirPodsサポートなど、物理的なキャプチャコントロールを使って写真を撮影する方法や、カメラコントロールで設定を調整する方法を紹介します。

    関連する章

    • 0:00 - イントロダクション
    • 2:51 - 物理的なキャプチャ
    • 3:01 - イベント処理
    • 6:39 - AirPodsでのリモートキャプチャ
    • 10:00 - カメラコントロール

    リソース

    • Accessing the camera while multitasking
    • AVFoundation
    • AVMultiCamPiP: Capturing from Multiple Cameras
    • Capture setup
    • Capturing Photos with Depth
    • Creating a camera experience for the Lock Screen
    • Creating a camera extension with Core Media I/O
    • DockKit
    • Forum: Photos & Camera
    • Scanning data with the camera
    • Supporting Continuity Camera in your macOS app
    • Supporting Continuity Camera in your tvOS app
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC24

    • ロック画面での優れたカメラキャプチャ体験の構築

    WWDC23

    • iPadOSアプリで外部カメラをサポート
    • tvOS向けの連携カメラ機能
  • このビデオを検索

    こんにちは Vitaliyです AVKitチームでエンジニアをしています 「Enhancing your camera experience with capture controls」にようこそ このセッションでは アプリにおけるユーザー操作を改善する 新しいパワフルな方法をご紹介します キャプチャコントロールでは プログラムで 物理ボタンのジェスチャを カメラアクションにマッピングして ネイティブのiOSカメラアプリで使い慣れた 操作感を ユーザーに提供します iOS 26で導入された 驚くべき新機能もご紹介します 皆さんもきっと気に入ると思います

    キャプチャコントロールの威力が 皆さんにも伝わりやすいよう iOSでカメラアプリを使ってみます 画面上のUIボタンを使って 撮影するかわりに 物理ボタンを使ってみます

    音量を上げるボタンを クリックするだけで キャプチャを開始できます

    このAPIで使えるのは クリックだけではありません 長押しにも対応しています たとえば カメラモードでは 音量下げボタンを長押しすると ビデオ録画が始まります

    キャプチャコントロールによって ユーザーはもっと柔軟に カメラを使用できるようになり 忘れられない瞬間を iPhoneで捉えられます

    このセッションでは まず 物理的なキャプチャとは何か そして サポートされている 物理ボタンを紹介します 次に アプリ内で APIを効果的に使って ユーザー操作を処理する方法や デモでお見せしたように 堅牢で 応答性の高いカメラインターフェイスの 構築方法を紹介します

    また iOS 26の エキサイティングな新機能 AirPodsでのリモートコントロールも お見せします

    最後に 同僚のNickさんから iPhone 16の カメラコントロールの概要を紹介します

    APIの主要な機能を 紹介する前に iOSで 優れたカメラ体験を 生み出すための 主要なフレームワークを確認しましょう カメラアプリの軸となるアーキテクチャは AVFoundationで APIを介して 下位レベルの キャプチャ機能を提供します たとえば 写真ならAVCapturePhotoOutput ビデオなら AVCaptureMovieFileOutputです

    UIレイヤとAVFoundationを 集約するため これらのフレームワークの上位に AVKitがあります

    AVKitに含まれるキャプチャ固有のAPIに AVCaptureEventInteractionがあります

    ここで AVCaptureEventInteractionの 主な特長と機能を 紹介しましょう このAPIを使用すると 音量上げや音量下げなどの 物理ボタンや iPhone 16で導入された カメラコントロールのデフォルトの動作を オーバーライドできます

    AVCaptureEventInteractionが サポートする もう1つのボタンが アクションボタンです アクションボタンをキャプチャ用に 設定する方法については 昨年のセッションをご覧ください

    物理ボタンを押すたびに キャプチャイベント通知がトリガされます この通知には イベントのフェーズが含まれており ボタン操作のライフサイクル全体を 正確に制御できます フェーズは3つあります 「began」は ボタンが押された瞬間です アプリのカメラオブジェクト 準備には最適のフェーズです

    「cancelled」は アプリがバックグラウンドに 切り替わる瞬間 または キャプチャが利用できない瞬間です

    「ended」は ボタンから指を離した瞬間です カメラオブジェクトが キャプチャを開始するべきフェーズです

    AVCaptureEventInteractionにも ボタンの押下を プライマリアクションと セカンダリアクションで区別する 機能があります ボタンを押すと キャプチャ通知がトリガされ 指定したハンドラにのみ 送信されます

    プライマリアクションは 音量下げボタン、アクションボタン カメラコントロールでトリガされ セカンダリアクションは 音量上げボタンでトリガされます 同じボタンで2つのハンドラの トリガはできません それぞれ異なるアクションを表すよう 設計されているためです セカンダリハンドラは省略可能で 指定がない場合は 音量上げるボタンのクリックで プライマリアクションをトリガします このような設計にすることで アプリにモジュール性が加わり ユーザーにとって優れたカメラ体験を デザインする際の 柔軟性が高まります このAPIは キャプチャのユースケースを 対象としたものです システムは カメラ使用中のアプリにだけ キャプチャイベントを送信します このAPIの採用により デフォルトの 物理ボタンの動作が上書きされるため アプリは常に 受信したイベントに 適切に応答する必要があります イベントの処理に失敗した場合 ボタンが機能せず ユーザー体験が 貧弱なものとなってしまいます

    バックグラウンド化された キャプチャアプリや 実行中の AVCaptureSessionがないアプリは イベントを受信しません ボタンを押すと 音量の調整やカメラの起動など デフォルトの システムアクションがトリガされます

    AVCaptureEventInteractionは UIKit専用に設計されたAPIですが SwiftUIデベロッパも onCameraCaptureEvent ビューモディファイアを介して この機能にアクセスできます どちらかを採用すれば 同じ動作を実行できます

    AVCaptureEventInteractionについて 理解したところで 簡単なカメラアプリを作成しましょう SwiftUIのonCameraCaptureEvent ビューモディファイアを使用して 物理ボタンで写真を キャプチャできるようにします まず カメラアプリの ユーザーインターフェイスを作成します カメラ出力を 画面に表示させるための CameraViewを含めます

    次に ビューにボタンを追加して 写真をキャプチャできるようにします このボタンを CameraModelに接続して タップすると写真のキャプチャを トリガするようにします

    これで 画面上のボタンを押すと 写真を撮影する 機能ビューができました ただ 物理ボタンを押すと システムアクションがトリガされます そこで このセッションで紹介した APIを使って ハードウェアボタン操作を カメラ専用にします まず AVKitフレームワークを インポートします 次に onCameraCaptureEvent ビューモディファイアを CameraViewにアタッチして イベントフェーズ終了時に 写真を撮るようにします

    とても簡単ですね わずか6行のコードを追加するだけで 写真キャプチャでも 内蔵カメラアプリと同様に直感的な 物理ボタン操作が できるようになりました これこそが Capture Controls APIの パワーの見せ所です 今年 そのAVCaptureEventInteractionが AirPodのステム 特に H2チップを搭載したAirPodsステムの クリックによりトリガされた プライマリアクションもサポートすることを 発表でき とても嬉しく思います これで 忘れられない瞬間を スマートフォンを操作することなく リモートで キャプチャできるようになります

    すでにAPIを ご採用いただいている皆さんは iOS 26ではこの機能を 無料でご利用いただけます

    この新機能の動作を 実際に確認してみましょう まず 右のAirPodを入れて 左側も入れます

    装着完了!

    AirPodsを キャプチャ用に構成するには 設定を表示して

    下にスクロールし 「リモートカメラ キャプチャ」セクションを表示します

    キャプチャのトリガに使用する操作を ここで選択できます 「1回押す」オプションを選択します

    ここで カメラアプリに戻ります

    ちょっと後ろに下がって 片方のステムをクリックして 写真を撮ります

    これで デバイス操作なしでも カメラを制御できるようになりました

    リモートカメラ制御に AirPodsを使用するので オーディオフィードバックが 不可欠です キャプチャ中は 画面を見ていない 可能性がありますが コマンドが認識されたか 確認が必要になるからです

    そこで AirPodのステムのクリック専用に サウンド再生を制御する 新しいAPIを導入しました AirPodのクリック以外によって キャプチャイベントがトリガされた場合 AVCaptureEventInteractionオブジェクトは サウンドフィードバック制御を許可しません

    新機能AVCaptureEventInteractionを ユーザー側の追加作業なしで 使えるようにするため AirPodsのクリック専用に デフォルトのトーンを追加しました

    ユースケースによっては このサウンドが 適さない場合もあるでしょう そのため アプリのバンドルで 独自のサウンドを提供して サウンド再生を カスタマイズできるようにしました

    このあたりで カメラアプリの .onCameraCaptureEvent ビューモディファイアに戻りましょう iOS 26では このコードを 変更しないでおくと AirPodステムをクリックしたとき デフォルトのサウンドが聞こえます 写真撮影に特化したアプリを 構築していることもあり デフォルトのサウンドでは アプリに適さない可能性もあります

    特定のシナリオに合わせて キャプチャサウンドを調整するには まず defaultSoundDisabledパラメータで デフォルトのサウンドを無効にします

    音声フィードバックが 必要な場合は イベントオブジェクトのplaySoundメソッドで cameraShutterサウンドを再生します shouldPlaySoundプロパティは AirPodのステムをクリックして キャプチャアクションをトリガした場合だけ trueになる点に注意してください

    ここまでの話をまとめると AVCaptureEventInteraction APIは アプリのために高品質のカメラ体験を 構築するプロセスを大幅に簡略化します APIの主な特徴と実装に関する ベストプラクティスを確認しました 今年のアップデート内容である AirPodステムのクリックで カメラ キャプチャを制御する方法も確認しました Nickさんにバトンタッチして AVCaptureControlsの話に移りましょう こんにちは Nick Lupinettiです Camera Experienceチームの ソフトウェアエンジニアです AVCaptureControlについて ご紹介できることを 嬉しく思います これは iPhone16のカメラコントロールを アプリのカメラインターフェイス用に 物理的なハードウェアに切り替えるための パワフルな手段です カメラコントロールは 汎用性の高いキャプチャツールで クリックでカメラアプリを起動し シャッターボタンとして機能し 指の置き場所を変えることなく 調整まで迅速に行うことができます

    これら3つの機能を 起動から順番に見ていきましょう アプリ起動のため デバイスのロック中でも カメラコントロールでアクセスできることが 必要になります つまり ロック画面キャプチャ機能拡張を 作成することになります 詳しくは ロック画面での カメラ体験に関する 昨年のセッションをご覧ください

    次の カメラコントロールをアプリの シャッターボタンとして使う方法は簡単です 先ほどVitaliyさんがお見せしたように キャプチャイベントAPIの1つを 設定するだけです カメラコントロールは プライマリイベント コールバックを実行します 音量ボタンの場合と同じです ここからは お楽しみの カメラ設定の調整に関するパートです カメラコントロールは 従来の カメラシャッターのような 軽く押すジェスチャをサポートしており 作業に集中しやすい クリーンプレビューをアクティブにして コントロールのスライドで 調整可能な設定を表示します その他の設定は 2回軽く押した後 カメラコントロールをスライドさせて もう1回軽く押すと 選択できます

    最上位レベルには 2種類のコントロールがあります 数値指定用のスライダと リスト項目選択用のピッカーです

    スライダには2つのタイプがあります 連続型と不連続型です

    連続型スライダは 指定した範囲内で 任意の数値を選択できます たとえば iOSはデフォルトで 拡大/縮小の連続スライダを装備しています 推奨最小サイズから デバイスの最大サイズまで 倍率の全域をサポートします 不連続型スライダの場合も 数値を選択しますが 選択には デベロッパが設定した 明示的なセット または ある値から別の値への 固定ステップを使用します iOSには 露出バイアス用に 不連続型スライダが組み込まれています +2から-2の間で3分の1刻みで 従来使われてきた 管理しやすい単位を採用しています

    ピッカーも不連続型スライダと同様に 有限の選択肢から選択しますが インデックスが付いています インデックスには コントロールの状態に 名前付きでマップされています たとえば フラッシュの 「オン」と「オフ」や カメラアプリの フォトグラフスタイルの名前などです さて 各種コントロールについて 理解できたところで これらを実装するクラスを 見てみましょう コントロールはAVFoundation フレームワークで定義されます AVCaptureControlは 継承元となる抽象基底クラスです

    システム定義のサブクラスは 2つあり これらによって ズームや露出バイアスなど どのアプリでも 内蔵カメラと 同じ動作を採用できます スライダには 連続型と不連続型という 2つの標準サブクラスがあり ピッカーについては 自分で動作を定義できます アプリにコントロールを採用するには AVCaptureSessionに追加します 通常 セッション構成の最初のステップでは キャプチャデバイスを作成して 入力としてラップされた セッションに追加します 次に システム定義コントロールが 作成され 同じデバイスを参照することで プロパティの実行を 代行します アプリ定義の動作を 割り当てたコントロールも このとき作成され 最後に コントロールが セッションに追加されます

    ユーザーからのカメラコントロール操作に アプリが応答できるよう 考慮するべきフローがいくつかあります システムが提供するコントロールは カメラコントロールからの値を 構成済みデバイスに 直接適用します videoZoomFactorやexposureTargetBiasを 自分で設定する必要はありません

    ただし モデルやUIの更新が 必要になる場合があります Key-Value Observing(KVO)を すでに使用している場合は 関連するプロパティの 変更状況を把握するため 引き続きこのメカニズムを使用して インターフェイスを更新できます

    KVOを使用していない場合は アクションハンドラを使用して システムコントロールを作成します 値が変更されると メインスレッドでこれを呼び出して UIを直接更新できるようになります

    アプリ定義のコントロールは常に アクションコールバックを使用して作成され 指定したキューで実行されます コントロールでのキャプチャ設定が 必要な場合は ステータスの管理ポイントで キューを指定することにより 同期的に実行できます これで メインキューのUIを更新できます

    さて Vitaliyさんと作った カメラコントロールを アプリに組み込む準備ができました キャプチャ操作は 追加してもらったので コントロールはすでに 撮影用の シャッターボタンとして機能しています コードの追加はしていません

    カメラコントロールによるズームインや ズームアウトもサポートしたいですね これも追加しましょう

    ここで キャプチャセッションを構成して デバイスを使用します まず コントロールの サポート状況を確認します iPhone 16のように カメラコントロールを備えたデバイス以外では 利用できないからです

    システム提供のコントロールは わずか1行のコードで簡単に作成できます

    コントロールを追加する前に セッションで 受け入れ可能か確認しましょう たとえば システムがデバイス用に提供する ズームコントロールは追加できません すでにズームコントロールに 関連付けられているからです 最後に コントロールを セッションに追加します

    これで カメラコントロールによるズームを うまく機能させる準備は完了です ひとつ問題があります ピンチジェスチャでのズームインも サポートしていますが カメラコントロールでズームインした後 UIが最新ではないため ピンチジェスチャが 古い倍率に戻ってしまいます ですが 修正は簡単です 倍率を引数として受け取る アクションクロージャを使用して スライダを作成するだけです 新しい値は デリゲートコールバックや ObservableModelプロパティを使用して UIに適用されます

    ピンチジェスチャの背後にある モデルが同期すれば カメラコントロールで ズームできるようになり ピンチも常に 正しい倍率から始められます

    次に デフォルトでは使用できない コントロールを追加します ですが 自前で作成する前に 優れたコントロールとは何かを 考えてみましょう カメラコントロールとは その名の通り iPhoneカメラで使用することを 想定しているので 外観やキャプチャ体験にも 影響してくるはずです そのため コントロールが無関係な領域に 影響を与えてしまうと 混乱を招きます カメラコントロールを採用するためだけに キャプチャセッションを導入しないように カメラの動作には 電力や プライバシーの要件が関連するため キャプチャ体験だけに とどめておくのがベストです カスタムコントロールの良い例が ピッカーです アプリがサポートするエフェクトや フィルタの反復処理に利用できます

    このようなコントロールは通常 UIに比べ キャプチャ寄りで操作する必要があります どのようになるか見てみましょう 先ほど書いたコードから始めて ズームコントロールを加えます コントロールの数は セッションの maxControlsCountプロパティで報告され 追加できる数には制限がある点に 注意してください 制限数に達すると canAddControlがfalseを返します では エフェクトを定義します エフェクトは ビデオサンプルバッファを使用して 専用のキューにレンダリングされますが 私たちのアプリは iOS 17で導入された リアクションエフェクトを使用します 使用可能な順序なしのセットをもとに エフェクトとその名前をまとめた 順番付きリストを作成しました ピッカーは オプションの反復処理時に表示する エフェクト名で初期化されます ズームコントロールと区別するため ピッカーには 固有の名前と SF Symbol画像が必要です コントロールがサポートされていない場合は 除外するのではなく 無効にすることを お勧めします そうすれば 操作はできなくても 引き続き表示されます こうしておかないと 別のコントロールが フォールバックとして選択され ユーザーを当惑させてしまう 可能性があります

    ピッカーで選択されたインデックスを ユーザーが変更すると これに対応するよう反応します アクションのターゲットに セッションキューを指定します デバイス管理における 隔離コンテキストにしているためです あとは コントロールの配列に ピッカーを追加するだけです さっそく結果を確認しましょう

    カメラコントロールを操作すると この新しい構成では ズームが無効になっています コントロールを変更しましょう オーバーレイをスワイプすれば リストでピッカーをチェックアウトできます スクロールして 軽く押すと オプションが表示されます エフェクトを順番に選択して プレビューで再生して確認できます

    Rock on!

    Vitaliyさんと私とで ここまでご紹介してきたように 世界最高クラスのカメラアプリを構築する 素晴らしいツールは豊富にあります

    iOSデバイスの物理ボタンで メディアをキャプチャする方法と iOS 26で AirPodsの操作により これを簡単に実行できることも紹介しました カメラコントロールを 便利なツールとして活用して アプリのキャプチャ操作を パワーアップする方法もお伝えしました developer.apple.com/jpには さらに素晴らしいリソースが揃っています カメラコントロール用の ヒューマンインターフェイスガイドラインや 新機能のテスト向けに AirPodsを設定する方法のガイダンス そして記事とサンプルコードで カメラコントロールを取り入れる方法の 詳細を確認していだけます 皆さんの手によって ユーザーの注目の的になるカメラが 誕生するのを 楽しみにしています ご視聴ありがとうございました

    • 5:35 - Initial PhotoCapture view setup

      import SwiftUI
      
      struct PhotoCapture: View {
          var body: some View {
              VStack {
                  CameraView()
              }
          }
      }
    • 5:37 - Connecting a button to the camera model

      import SwiftUI
      
      struct PhotoCapture: View {
          let camera = CameraModel()
          var body: some View {
              VStack {
                  CameraView()
                  Button(action: camera.capturePhoto) {
                      Text("Take a photo")
                  }
              }
          }
      }
    • 6:10 - Importing AVKit

      import AVKit
      import SwiftUI
      
      struct PhotoCapture: View {
          let camera = CameraModel()
          var body: some View {
              VStack {
                  CameraView()
                  Button(action: camera.capturePhoto) {
                      Text("Take a photo")
                  }
              }
          }
      }
    • 6:14 - Setting up onCameraCaptureEvent view modifier

      import AVKit
      import SwiftUI
      
      struct PhotoCapture: View {
          let camera = CameraModel()
          var body: some View {
              VStack {
                  CameraView()
                  .onCameraCaptureEvent { event in
                      if event.phase == .ended {
                         camera.capturePhoto()
                      }
                  }
                  Button(action: camera.capturePhoto) {
                      Text("Take a photo")
                  }
              }
          }
      }
    • 8:53 - Default sound for onCameraCaptureEvent view modifier

      .onCameraCaptureEvent { event
      	if event.phase == .ended {
         	camera.capturePhoto() 
        }
      }
    • 9:13 - Play photo shutter sound on AirPod stem click

      .onCameraCaptureEvent(defaultSoundDisabled: true) { event in
          if event.phase == .ended {a
              if event.shouldPlaySound {d
                  event.play(.cameraShutter)
              }
          }
          camera.capturePhoto()
       }
    • 14:46 - Add a build-in zoom slider to Camera Control

      captureSession.beginConfiguration()
      
      // configure device inputs and outputs
      
      if captureSession.supportsControls {
          let zoomControl = AVCaptureSystemZoomSlider(device: device)
      
          if captureSession.canAddControl(zoomControl) {
              captureSession.addControl(zoomControl)
          }
      }
      
      captureSession.commitConfiguration()
    • 15:40 - Modifying the built-in zoom slider to receive updates when zoom changes

      let zoomControl = AVCaptureSystemZoomSlider(device: device) { [weak self] zoomFactor in
          self?.updateUI(zoomFactor: zoomFactor)
      }
    • 16:46 - Adding a custom reaction-effects picker alongside zoom slider

      let reactions = device.availableReactionTypes.sorted { $0.rawValue < $1.rawValue }
      let titles = reactions.map { localizedTitle(reaction: $0) }
      let picker = AVCaptureIndexPicker(“Reactions", symbolName: “face.smiling.inverted”,
          localizedIndexTitles: titles)
      
      picker.isEnabled = device.canPerformReactionEffects
      picker.setActionQueue(sessionQueue) { index in
          device.performEffect(for: reactions[index])
      }
      
      let controls: [AVCaptureControl] = [zoomControl, picker]
      
      for control in controls {
          if captureSession.canAddControl(control) {
              captureSession.addControl(control)
          }
      }

Developer Footer

  • ビデオ
  • WWDC25
  • キャプチャコントロールによるカメラ体験の向上
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン