WWDC Quick Look 💓 By SwiftGGTeam
Build compelling spatial photo and video experiences

Build compelling spatial photo and video experiences

元の動画を見る

ハイライト

iPhone 15 Pro の広角と超広角カメラは横画面時に同一水平基線上にあり、既存 AVFoundation API を 3 か所変更するだけで空間動画を録画できます。同期、キャリブレーション、エンコード、メタデータ書き込みはすべてシステムが処理します。


主要内容

Vision Pro には 3 種類の立体動画体験があります。3D Video は平面画面で深度感を呈示し、映画向け。Spatial Video はウィンドウ再生で、イマーシブモードではコンテンツが現実世界と融合し、日常記録向け。Apple Immersive Video は 180 度 8K と Spatial Audio で、プロ制作向け。3 つはウィンドウモードとイマーシブモードで呈示方法が異なり——3D 動画は環境内の大画面に埋め込まれ、空間動画は実物と同スケールのイマーシブビューに展開され、Apple Immersive は視聴者を完全に包み込みます。

過去 1 年間、空間メディアの録画と再生はシステムアプリに限定されていました。今年 Apple は新フレームワークなしでこれらの機能を開発者に公開しました。録画は AVFoundation、検出は PhotoKit、再生は QuickLook——すべて既存フレームワークに統合され、数行のコード変更で導入できます。

ハードウェア基盤は iPhone 15 Pro のカメラ配置です。広角と超広角カメラが対角配置から横並びに変更され、横画面時に同一水平基線上にあり、人間の目の配置に似ています。API レベルでは 3 ステップ: builtInDualWideCamera に切り替え、空間動画対応 format を選択、isSpatialVideoCaptureEnabled を有効化。再生と検出では、PhotosPicker.spatialMedia フィルタが追加、PhotoKit が spatialMedia サブタイプクエリをサポート、AVAssetPlaybackAssistant が任意のローカルファイルが空間動画か判定可能。表示では、QuickLook の PreviewApplication API が完全な空間呈示をサポート、Safari の Element FullScreen API が Web 上の空間写真をサポート、AVPlayerViewController が空間動画の 3D 再生をサポートします。


詳細

空間動画の録画

公式サンプルのコアコード(06:19):

class CaptureManager {
    var session: AVCaptureSession!
    var input: AVCaptureDeviceInput!
    var output: AVCaptureMovieFileOutput!

    func setupSession() throws -> Bool {
        session = AVCaptureSession()
        session.beginConfiguration()

        guard let videoDevice = AVCaptureDevice.default(
            .builtInDualWideCamera, for: .video, position: .back
        ) else { return false }

        var foundSpatialFormat = false
        for format in videoDevice.formats {
            if format.isSpatialVideoCaptureSupported {
                try videoDevice.lockForConfiguration()
                videoDevice.activeFormat = format
                videoDevice.unlockForConfiguration()
                foundSpatialFormat = true
                break
            }
        }
        guard foundSpatialFormat else { return false }

        let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice)
        guard session.canAddInput(videoDeviceInput) else { return false }
        session.addInput(videoDeviceInput)
        input = videoDeviceInput

        let movieFileOutput = AVCaptureMovieFileOutput()
        guard session.canAddOutput(movieFileOutput) else { return false }
        session.addOutput(movieFileOutput)
        output = movieFileOutput

        guard let connection = output.connection(with: .video) else { return false }
        guard connection.isVideoStabilizationSupported else { return false }
        connection.preferredVideoStabilizationMode = .cinematicExtendedEnhanced

        guard movieFileOutput.isSpatialVideoCaptureSupported else { return false }
        movieFileOutput.isSpatialVideoCaptureEnabled = true

        session.commitConfiguration()
        session.startRunning()
        return true
    }
}

キーポイント:

  • systemPreferredCamera ではなく builtInDualWideCamera を使用。空間動画には広角と超広角の同時動作が必要(06:22
  • videoDevice.formats を走査し isSpatialVideoCaptureSupported が true の format を見つけて activeFormat に設定(06:34
  • preferredVideoStabilizationMode.cinematicExtendedEnhanced に設定。より長い先読みウィンドウとより多くのクロップで滑らかな映像を得る(07:40
  • isSpatialVideoCaptureEnabled を true にして空間動画録画を有効化。iPhone 15 Pro のみサポート(06:56
  • 同期、キャリブレーション、エンコード、メタデータ書き込みはすべてシステムが処理。完成した空間動画ファイルが得られる

撮影不适の監視

広角と超広角は異なるタイプのカメラで、低照度下のノイズレベルが異なり、近距離撮影ではフォーカス不一致が起きます。iPhone 画面は単眼なので、撮影中にユーザーはこれらの問題を感知できません。Apple は spatialCaptureDiscomfortReasons プロパティを追加しました(09:13):

let observation = videoDevice.observe(\.spatialCaptureDiscomfortReasons) { (device, change) in
    guard let newValue = change.newValue else { return }
    if newValue.contains(.subjectTooClose) {
// ユーザーに後退を促す
    }
    if newValue.contains(.notEnoughLight) {
// ユーザーにより明るい環境を探すよう促す
    }
}

キーポイント:

  • KVO で spatialCaptureDiscomfortReasons の変化を監視
  • .subjectTooClose は被写体が近すぎて、いずれかのカメラがフォーカスできない
  • .notEnoughLight は光不足。2 つのカメラのノイズ差が視聴時の不快感を引き起こす可能性
  • システムカメラアプリの警告と同様、UI にガイダンスを表示することを推奨

空間コンテンツの検出

空間メディアを検出する 3 つの方法:

PhotosPicker は空間コンテンツのフィルタをサポート(09:58):

import SwiftUI
import PhotosUI

struct PickerView: View {
    @State var selectedItem: PhotosPickerItem?
    var body: some View {
        PhotosPicker(selection: $selectedItem, matching: .spatialMedia) {
            Text("Choose a spatial photo or video")
        }
    }
}

キーポイント:

  • matching: .spatialMedia で空間写真と動画のみを表示
  • ユーザーが手動でコンテンツを選択するシーン向け

PhotoKit で全空間アセットを直接クエリ(10:14):

import Photos

func fetchSpatialAssets() {
    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(
        format: "(mediaSubtypes & %d) != 0",
        argumentArray: [PHAssetMediaSubtype.spatialMedia.rawValue]
    )
    fetchResult = PHAsset.fetchAssets(with: fetchOptions)
}

キーポイント:

  • PHAssetMediaSubtype.spatialMedia をサブタイプフィルタとして使用
  • 空間写真または空間動画のみを返すようさらにフィルタ可能
  • ユーザー操作不要のプログラム的クエリ向け

AVAssetPlaybackAssistant でローカルファイルを検出(10:36):

import AVFoundation

extension AVURLAsset {
    func isSpatialVideo() async -> Bool {
        let assistant = AVAssetPlaybackAssistant(asset: self)
        let options = await assistant.playbackConfigurationOptions
        return options.contains(.spatialVideo)
    }
}

キーポイント:

  • playbackConfigurationOptions.spatialVideo が含まれるか確認
  • フォトライブラリ以外のソースから動画を読み込むシーン向け

空間コンテンツの表示

3 つの表示方法、それぞれ異なる強み:

  • QuickLook PreviewApplication: 空間写真と動画をサポート、システム写真アプリと同様の完全な空間呈示。標準的な空間再生体験向け(10:57
  • Safari Element FullScreen API: Web から空間写真を開き、新シーンで完全な空間呈示(11:36
  • AVPlayerViewController: 2D と 3D 動画の統一再生、HLS ストリーミングをサポート。注意: ここでは空間動画は 3D 動画としてのみ再生(空間動画のイマーシブビューは使用しない)。完全な空間呈示には PreviewApplication を使用(11:54

空間メタデータ

空間動画は空間メタデータ付き MV-HEVC ファイル、空間写真は空間メタデータ付き立体 HEIC ファイル。メタデータには以下が含まれます(13:39):

  • 投影タイプ: 常に rectilinear(直線投影)
  • 基線(Baseline): 2 つのカメラ中心間の水平距離、約 64mm で人間の目の間隔に近い。基線が大きいと微縮効果
  • 視野角(Field of View): 水平角度。大きいほどイマーシブだが解像度は低下。90 度超は非推奨
  • 視差調整(Disparity Adjustment): ウィンドウモードでの 3D 深度オフセットを制御。負の値でコンテンツが近づき、正の値で遠ざかる。数パーセントのオフセットで視聴感が大きく変わる

画像要件: 立体補正(光軸が平行)、光軸アライメント(画像中心と光軸中心が一致、クロップや水平シフトなし)、垂直視差なし(左右画像の同一特徴点の連結線は水平でなければならない)。


重要ポイント

  1. 既存カメラアプリに「空間動画」スイッチを追加: builtInDualWideCamera に切り替え、空間動画対応 format を選択、isSpatialVideoCaptureEnabled = true の 3 ステップのみ。価値がある理由: ユーザーがアプリで撮影したコンテンツが Vision Pro の空間体験に直接登場。iPhone 15 Pro だけの差別化機能。始め方: AVCam サンプルプロジェクトをベースに上記 3 ステップを適用。

  2. アルバム閲覧画面で空間コンテンツをフィルタ: PhotosPicker(matching: .spatialMedia) または PhotoKit の spatialMedia サブタイプクエリを使用。価値がある理由: Vision Pro ユーザーの空間コンテンツは増え続ける。専用エントリポイントは全コンテンツに混在させるより発見しやすい。始め方: 既存フォトピッカーに .spatialMedia フィルタ条件を追加。

  3. QuickLook PreviewApplication で空間メディアを表示: 最もシンプルな方案。数行のコードでシステム写真アプリと同様の空間呈示。価値がある理由: 独自の空間プレイヤーは立体レンダリング、イマーシブモード切り替えなど複雑なロジックが必要。QuickLook がすべて内蔵。始め方: QuickLook フレームワークをインポートし、PreviewApplication を作成して空間メディアファイルを渡す。

  4. 撮影不适ガイダンス UI を追加: KVO で spatialCaptureDiscomfortReasons を監視、.subjectTooClose または .notEnoughLight 時にガイダンスを表示。価値がある理由: iPhone 画面は単眼で、ユーザーは空間効果をプレビューできない。Vision Pro で再生して初めて不适に気づくのは遅すぎる。始め方: カメラプレビュー画面にガイダンスビューを重ね、システムカメラアプリの警告スタイルを参照。


関連セッション

コメント

GitHub Issues · utterances