WWDC Quick Look 💓 By SwiftGGTeam
Learn about the Apple Projected Media Profile

Learn about the Apple Projected Media Profile

元の動画を見る

Highlight

APMP は QuickTime/MP4 の vexu box に projection、lens collection、view packing の 3 種類の box を新たに追加し、180/360/広角投影シグナルをコンシューマー向け動画ファイルに組み込みました。さらに visionOS 26 の AVFoundation で、認識・変換・読み書き・編集・HLS 配信までの一連のパイプラインがつながっています。


主な内容

これまで GoPro、Insta360、Canon EOS VR で撮影した 180/360/広角動画を Apple Vision Pro 上で正しく表示するには、開発者が自前で Spherical Metadata V1/V2 をパースし、フレームのパッキングが side-by-side か over-under かを判定し、最終的に左右それぞれの映像を手動でプレイヤーに渡す必要がありました。投影の種類、レンズ歪み、ステレオビューという 3 つの情報がバラバラのフィールドに散らばっており、統一されたコンテナ表現が存在しないため、ツールチェーンも各社で独自実装するしかなかったわけです。

Core Media Spatial Technologies チームのエンジニア Jon は本セッションで、Apple Projected Media Profile(APMP)を紹介し、これらの表現を QuickTime/MP4 の標準構造へと集約しました。visionOS 26 において APMP は、Video Extended Usage(vexu)拡張 box の組み合わせで非矩形投影を記述します。投影タイプ(equirectangular / half-equirectangular / parametricImmersive / appleImmersiveVideo)、レンズの内部パラメータと歪みパラメータ、左右眼のフレームパッキング方式を扱えます。AVFoundation、Core Media、Video Toolbox、HLS のツールチェーンも同時に更新されており、認識・変換・読み書き・編集・配信を同一の API で扱えるようになりました。あわせて Apple Positional Audio Codec(APAC)が 1/2/3 次の ambisonic エンコードに対応し、球面音場と球面映像を組み合わせることで、完全な没入体験を構成できます。


詳細

投影の種類(01:31)。 2D/3D/Spatial は rectilinear、180 度は half-equirectangular(X 軸を -90° 〜 +90° にマッピング)、360 度は equirectangular(X 軸を -180° 〜 +180°、Y 軸を -90° 〜 +90° にマッピング)を使います。広角・魚眼は ParametricImmersive を用い、3×3 のカメラ内部パラメータ行列 K(焦点距離、光学中心、skew)に加え、半径方向歪み・接線方向歪み・projection offset・radial angle limit・lens frame adjustments といったパラメータを含めることで、広角レンズの樽型歪みを補正します。

コンテナ内のシグナル(04:33)。 vexu の下に 3 つの box が新設されました。

  • Projection box:投影タイプを示す。
  • Lens Collection box:ParametricImmersive の intrinsics、extrinsics、歪みパラメータを格納する。
  • View Packing box:side-by-side か over-under かを示す。

最小構成のモノラル 360 ファイルなら projection box が 1 つあれば済みますし、ステレオ 180 ファイルなら stereo view box と half-equirectangular projection box の組み合わせが必要です。完全な仕様は developer.apple.com の『QuickTime and ISO Base Media File Formats and Spatial and Immersive Media』を参照してください。

従来の Spherical Metadata の認識(08:58)。 AVFoundation に AVURLAssetShouldParseExternalSphericalTagsKey が追加され、システムが Spherical Metadata V1/V2 を APMP として読み込めるようになりました。

import AVFoundation

func wasConvertedFromSpherical(url: URL) -> Bool {
    let assetOptions = [AVURLAssetShouldParseExternalSphericalTagsKey: true]
    let urlAsset = AVURLAsset(url: url, options: assetOptions)

    let track = try await urlAsset.loadTracks(withMediaType: .video).first!
    let formatDescription = try await videoTrack.load(.formatDescriptions).first

    let wasConvertedFromSpherical = formatDescription.extensions[.convertedFromExternalSphericalTags]
    return wasConvertedFromSpherical
}

ポイント:

  • AVURLAssetShouldParseExternalSphericalTagsKey: true:AVURLAsset が球面メタデータを APMP のフォーマットディスクリプション拡張へ合成するため、下流の API はそのまま APMP として処理できます。
  • formatDescription.extensions[.convertedFromExternalSphericalTags]:当該 asset が球面メタデータから合成されたものかどうかを判定でき、UI 上で個別の表示を出す際に便利です。

広角コンテンツを ParametricImmersive へ昇格させる(09:54)。 ImmersiveMediaSupport フレームワークには、GoPro HERO 13 や Insta360 Ace Pro 2 など主要機種のレンズパラメータが組み込まれています。

import ImmersiveMediaSupport

func upliftIntoParametricImmersiveIfPossible(url: URL) -> AVMutableMovie {
    let movie = AVMutableMovie(url: url)

    let assetInfo = try await ParametricImmersiveAssetInfo(asset: movie)
    if (assetInfo.isConvertible) {
        guard let newDescription = assetInfo.requiredFormatDescription else {
            fatalError("no format description for convertible asset")
        }
        let videoTracks = try await movie.loadTracks(withMediaType: .video)
        guard let videoTrack = videoTracks.first,
              let currentDescription = try await videoTrack.load(.formatDescriptions).first
        else {
            fatalError("missing format description for video track")
        }
        videoTrack.replaceFormatDescription(currentDescription, with: newDescription)
    }
    return movie
}

ポイント:

  • ParametricImmersiveAssetInfo(asset:):対象の動画が既知の広角カメラ機種に該当するかを検出します。
  • assetInfo.isConvertible:認識に成功すると true になります。
  • requiredFormatDescription:ParametricImmersive 投影、内部パラメータ、歪みパラメータを含む新しいフォーマットディスクリプションを取得できます。
  • replaceFormatDescription(_:with:):動画トラックのフォーマットディスクリプションを差し替えると、その動画はシステムから見て wide-FOV な APMP として扱われます。

非矩形投影の判別(10:58)。 AVAssetPlaybackAssistantplaybackConfigurationOptions を取得し、.nonRectilinearProjection.appleImmersiveVideo の 2 つを確認すれば、APMP と Apple Immersive Video をそれぞれ判別できます。

projectionKind と viewPackingKind の詳細判定(11:22)。 mediaCharacteristics に indicatesNonRectilinearProjection が含まれている場合は、formatDescription から .projectionKind(equirectangular / halfEquirectangular / parametricImmersive / appleImmersiveVideo)と .viewPackingKind(sideBySide / overUnder)を取り出し、レンダリングパイプラインの処理方法を分岐させます。

ステレオ編集に CMTaggedDynamicBuffer を使う(12:51)。 AVVideoComposition に outputBufferDescriptionfinish(withComposedTaggedBuffers:) が追加されました。

var config = try await AVVideoComposition.Configuration(for: asset)
config.outputBufferDescription = [[.stereoView(.leftEye)], [.stereoView(.rightEye)]]
let videoComposition = AVVideoComposition(configuration: config)

ポイント:

  • outputBufferDescription:compositor が左右眼 2 つの tagged buffer を出力することを宣言します。composition 開始前に必ず定義しなければなりません。
  • [.stereoView(.leftEye)] / [.stereoView(.rightEye)]:CM Tag によって各眼を識別します。

ステレオペアの書き込み(13:01)。 startRequest の中で左右眼それぞれの CMTaggedDynamicBuffer を構築し、各 buffer に .videoLayerID.stereoView の 2 つの CM Tag を付け、最後に asyncVideoCompositionRequest.finish(withComposedTaggedBuffers:) を呼び出します。

APMP ファイルの書き出し(13:18)。 AVAssetWriter を使う場合、投影シグナルを AVVideoCompressionPropertiesKey 辞書の CompressionPropertyKey.kind に渡せば、AVAssetWriterInput が APMP シグナル付きの vexu box を出力します。

配信パラメータ(13:51)。 HEVC Main / Main 10、4:2:0 クロマサブサンプリング、Rec.709 もしくは P3-D65 の色域を使用します。モノラルは 7680×3840、ステレオは片眼あたり 4320×4320、10-bit の 8K モノラルや 4K ステレオでは 30fps、ピークビットレートは 150 Mbps を超えないことが推奨されています。MV-HEVC のステレオ構成については『Apple HEVC Stereo Video Interoperability Profile』を参照してください。

AVQT(14:50)。 Advanced Video Quality Tool に equirectangular / half-equirectangular の投影認識が追加されました。等距円筒展開図上でより正確に圧縮品質を評価でき、HLS のビットレートラダー調整にも活用できます。

HLS(15:25)。 EXT-X-STREAM-INFORMATION に REQ-VIDEO-LAYOUT 属性が新設され、stereo と投影タイプを同時に表現できるようになりました。map segment の formatDescription にも対応する projection と stereo view 拡張が必要で、manifest に書くだけでは認識されません。

APAC(16:14)。 Apple Positional Audio Codec は 1 次(4 チャンネル)、2 次(9 チャンネル)、3 次(16 チャンネル)の ambisonic に対応しています。watchOS を除くすべての Apple プラットフォームでデコードでき、iOS、macOS、visionOS では AVAssetWriter にエンコーダーが内蔵されています。推奨ビットレートは 1 次で 384 kbps、3 次で 768 kbps です。APMP 動画と同じく HLS のセグメントとしてストリーミング配信できます。


主な示唆

1. UGC 没入動画 App に APMP の読み書きを組み込む。 なぜ取り組む価値があるのか: visionOS 26 の再生・編集・Quick Look はいずれも APMP のシグナルに基づいて投影方式を判断します。App が規格に沿ったファイルを書き出せば、AirDrop、iCloud、Photos がそのまま没入コンテンツとして処理してくれます。始め方: AVAssetWriterAVVideoCompressionPropertiesKey を使って CompressionPropertyKey.kind に equirectangular または halfEquirectangular を設定し、ステレオコンテンツであれば stereo view 拡張も付け加えます。

2. 既存の Spherical Metadata からの移行パスを用意する。 なぜ取り組む価値があるのか: 既存の GoPro MAX、Insta360 X5 などのファイルの多くは Spherical V1/V2 形式であり、これを拒絶するとインポート率が一気に落ちます。始め方: AVURLAsset を構築する際に AVURLAssetShouldParseExternalSphericalTagsKey: true を渡し、convertedFromExternalSphericalTags フラグを使って UI に「360 動画として認識しました」と表示します。重要な素材は avconvert や自前の変換スクリプトで APMP として永続的に書き戻すとよいでしょう。

3. 広角アクションカメラのコンテンツを ParametricImmersive に昇格させる。 なぜ取り組む価値があるのか: GoPro HERO 13 や Insta360 Ace Pro 2 の動画は元々 2D の広角映像であり、昇格させなければ通常の矩形動画として再生されてしまい、visionOS の没入感を活かせません。始め方: ImmersiveMediaSupportParametricImmersiveAssetInfo を使い、isConvertible が true の asset には replaceFormatDescription を呼び出して、内部パラメータと歪み情報をフォーマットディスクリプションに書き込みます。

4. ステレオ編集パイプラインを CMTaggedDynamicBuffer に対応させる。 なぜ取り組む価値があるのか: 従来のカスタム compositor は単一 buffer しか出力できず、ステレオ合成はフレーム結合で凌ぐしかありませんでした。新しい AVVideoComposition では左右眼それぞれの tagged buffer を直接受け渡せるため、レンダラーやエクスポーターの処理を通じてステレオ意味論を一貫して保てます。始め方: AVVideoComposition.ConfigurationoutputBufferDescription = [[.stereoView(.leftEye)], [.stereoView(.rightEye)]] を設定し、compositor 内で CMTaggedDynamicBuffer.videoLayerID.stereoView の 2 つの tag を付け、最後に finish(withComposedTaggedBuffers:) を呼び出します。

5. 没入動画の音声を APAC + ambisonic に移行する。 なぜ取り組む価値があるのか: 従来のステレオ音声は頭の動きにそのまま追従してしまい、没入感を損ねます。一方 ambisonic は音場全体を球面調和関数としてエンコードするため、Vision Pro のヘッドトラッキング再生と組み合わせて初めて、音の方向を正しく定位できます。始め方: 録音には 4 マイク以上の ambisonic マイクを使い、エンコードには AVAssetWriter の APAC outputSettings を利用します。1 次 384 kbps から始めて、3 次 768 kbps を上限とするのが目安です。HLS 配信は APMP 動画と同じ playlist に統合できます。


関連 Session

コメント

GitHub Issues · utterances