サイト内を検索 HONG HUANG

従来のストリーミングを visionOS へ:3D・180°・360° 動画の再生パイプライン

クライアント内 HLS サーバー、APMP メタデータ、MV-HEVC を使い、既存のステレオ映像とパノラマ配信を Vision Pro のネイティブプレーヤーへ届ける仕組み。

共有

変換前 — 元のステレオ配置 · 13 秒
変換後 — Vision Pro で再生 · 13 秒

背景

従来のストリーミングプラットフォームには、左右または上下に並べて格納されたステレオ動画や、180°・360° のパノラマ動画がすでに数多くあります。両眼視差とパノラマ投影を組み合わせた素材もあり、ヘッドセットでの視聴に自然に適しています。しかし、通常の画面向けに作られた再生パイプラインは、それらを普通の長方形画像として扱うことが少なくありません。左右の映像は隣り合って表示され、パノラマは平面に展開されます。同じプレーヤーを Vision Pro へ移しただけでは、コンテンツが本来持っている奥行きや空間感覚は自動的には戻りません。

Apple のネイティブメディア配信システムには、こうしたコンテンツをより明確に記述する方法があります。MV-HEVC は符号化レイヤーで左右のビューを保持し、Apple Projected Media Profile(APMP)は 180°・360° 動画など、投影メディアの形状とビュー情報を記述します。HLS で配信する場合、プレイリストにも対応する表示レイアウトを宣言し、初期化セグメント内のメディア記述と一致させる必要があります。元のピクセル、符号化、これらの宣言が一体となって、システムによる表示方法を決めます。Apple Movie Profiles、APMP の概要

仕組み

この実装の重要な要素の一つは、クライアント内で動作するローカル HLS サーバーです。 変換が必要なステレオパノラマコンテンツでは、クライアントが元の CDN から動画をオンデマンドで取得し、左右のビューを処理して符号化を変換します。そして、正しい投影情報を含む HLS プレイリストとメディアセグメントをローカルサーバーから提供します。

システムプレーヤーは 127.0.0.1 経由でこのストリームへアクセスし、通常の HLS と同じ手順で再生、バッファリング、シークを行います。プレーヤーがセグメントを要求するたびに、ローカルサーバーはキャッシュ済みの結果を返すか、そのセグメントの生成を開始します。これにより、Vision Pro のネイティブな再生体験を保ちながら、変換と再生を同時に進められます。

元の CDN → デバイス上のメディア適応 → ローカル HLS サーバー → Vision Pro システムプレーヤー

ローカルサーバーが出力する HLS(HTTP Live Streaming)は、Apple の HLS Authoring Specification for Apple Devices に従います。RFC 8216 は HLS の中核プロトコルを定義していますが、ステレオ表示や投影レイアウトといった新しい機能を扱うには、その後の拡張も理解する必要があります。この記事では、Apple が公開している HTTP Live Streaming 2nd Edition 草案も参照しています。RFC 8216、Apple デバイス向け HLS オーサリング仕様

このパイプラインでは、三つの名称がそれぞれ異なる役割を持ちます。HLS は転送とプレイリストを構成し、APMP は投影メディアのフォーマット要件を定義し、MV-HEVC はステレオ動画の符号化を担います。 ステレオ APMP コンテンツをネイティブに配信するには、三つの層をすべて整合させる必要があります。Apple Movie Profiles

HLS は二段階のプレイリストでコンテンツを記述します。マルチバリアントプレイリストには、利用可能な動画バリアント、コーデック能力、関連する音声トラックを記載します。メディアプレイリストには、実際のセグメント、長さ、初期化情報を記載します。プレーヤーはまず適切なバリアントを選び、メディア時間に従って対応するリソースを取得します。

3D・180°・360° の再生に最も直接関係する属性は REQ-VIDEO-LAYOUT です。マルチバリアントプレイリストの EXT-X-STREAM-INF タグに置かれ、その動画バリアントが必要とする表示能力を宣言します。値には二種類の情報を組み合わせられます。

次元値意味
動画ビューCH-MONOモノスコピック:両目に同じビューを表示
動画ビューCH-STEREOステレオ:左右のビューを別々に表示する必要あり
投影PROJ-RECT通常の長方形による平面表示
投影PROJ-HEQU半エクイレクタングラー、180° 投影
投影PROJ-EQUIエクイレクタングラー、360° 投影

ここで CH は動画のビューを表します。音声チャンネルは対応する音声トラックの宣言で扱います。組み合わせは明快です。CH-STEREO/PROJ-RECT は平面 3D、CH-STEREO/PROJ-HEQU はステレオ 180° 動画、CH-STEREO/PROJ-EQUI はステレオ 360° 動画を表します。ステレオの値を CH-MONO に置き換えると、対応するモノスコピックパノラマになります。通常のモノスコピック平面動画は既定のケースなので、この属性は通常省略されます。これらの値は表示要件を宣言するもので、具体的な形状とビュー情報はメディア自体から読み取る必要があります。HLS 第 2 版草案:REQ-VIDEO-LAYOUT

これにより、実装で EXT-X-VERSION:12 が使われる理由も分かります。REQ- 接頭辞を持つ属性を含むプレイリストには、12 以上のプロトコル互換バージョンが必要です。この数字は、プレイリストがクライアントの解析能力に求める要件を示します。動画フォーマットのバージョンではなく、すべての Vision Pro 動画がバージョン 12 を使うという意味でもありません。各子プレイリストは、使用するタグから自身の互換性要件を決定します。Apple:EXT-X-VERSION タグについて

空間レイアウトに加えて、マルチバリアントプレイリストは動画バリアントのデコードと選択に必要な情報も提供しなければなりません。

タグまたは属性宣言する内容再生への影響
EXT-X-STREAM-INF動画バリアントとその属性。次行の URI はメディアプレイリストを指す特定の動画バリアントの再生入口を確立
CODECS動画・音声コーデックの種類と対応するパラメータープレーヤーがデコード互換性を判断できる。実際のビットストリームと一致させる
SUPPLEMENTAL-CODECS特定の Dolby Vision 構成など、一部の配信構成に必要な補助コーデック情報拡張レイヤーや関連するコーデック能力の追加情報を提供
RESOLUTION / FRAME-RATE動画の解像度とフレームレート表示動作とバリアント選択に情報を提供
BANDWIDTH / AVERAGE-BANDWIDTHピーク時および平均の帯域幅要件ネットワーク状況に応じた選択を支援する。エンコーダーのビットレート設定ではない
VIDEO-RANGESDR、HLG、PQ などのダイナミックレンジ種別動画の伝達特性を記述する。ビュー数や投影範囲とは独立
EXT-X-MEDIA と AUDIO音声グループを定義し、動画バリアントと関連付ける音声と動画が分離された再生リソースを構成

Apple の公式 HLS サンプル付録では、これらの属性を組み合わせる方法を確認できます。たとえば VIDEO-RANGE=PQ だけでは、コンテンツが Dolby Vision を使うことも、ステレオまたはパノラマであることも証明できません。

メディアプレイリストでは、宣言の焦点がタイムライン、初期化情報、セグメント境界へ移ります。

タグ宣言する内容
EXT-X-MAP現在のセグメントが使う初期化セグメント。fMP4 ではデコーダー設定、トラック記述、対応するステレオ・投影メタデータを含む
EXTINF次のメディアセグメントの長さ(秒)
EXT-X-TARGETDURATIONプレイリストにおけるセグメント長の上限。各 EXTINF を最も近い整数秒に丸めた値がこれを超えてはならない
EXT-X-BYTERANGEリソース内にあるセグメントのバイト長とオフセット。大きなファイルを複数の論理セグメントとして Range 読み込みできる
EXT-X-MEDIA-SEQUENCEプレイリスト先頭のメディアセグメントのシーケンス番号。セグメント順を識別する
EXT-X-DISCONTINUITY後続セグメントのタイムスタンプ列、形式、その他の特性に不連続があり、プレーヤーが解釈状態を再確立する必要があることを示す
EXT-X-INDEPENDENT-SEGMENTS他セグメントのメディアサンプルに依存せず各セグメントをデコードできることを示す。初期化情報は引き続き必要
EXT-X-PLAYLIST-TYPE:VOD内容が固定されたビデオオンデマンド用プレイリストであることを示す
EXT-X-ENDLISTこれ以上メディアセグメントが追加されないことを示す

これらのタグが、セグメント再生とランダムシークの基盤になります。RFC 8216:プレイリストとメディアセグメント

空間再生は最終的に、宣言の連鎖全体が一貫しているかどうかに依存します。 マルチバリアントプレイリストが CH-STEREO/PROJ-HEQU を宣言するなら、初期化セグメントには一致するステレオおよび半エクイレクタングラー投影の記述が必要で、実際の動画も配信要件を満たす二つのビューを提供しなければなりません。vexu、eyes、proj などの MP4 構造がこうしたメディアの意味を担います。これらはコンテナメタデータであり、EXT-X-MAP が参照する初期化セグメントを通じて再生パイプラインへ入ります。APMP の概要

したがって、クライアント側の適応では三つの課題を同時に解く必要があります。元画像を正しい左右のビューまたは投影コンテンツへ整え、対象の配信形式で符号化・パッケージ化し、メディアと一致する HLS 宣言を生成します。システムはこの情報を使って利用可能な能力を識別し、適切な視聴体験を提供します。

実装方針

既存の動画には、必要なステレオまたはパノラマ情報がすでに含まれています。メディアを適応させれば、クライアントから Vision Pro のネイティブ再生システムへ届けられます。これが今回の出発点でした。既存の動画リソースと配信基盤を再利用し、デバイス上で投影記述を追加してメディア配信を再構成し、必要に応じて左右のビューを処理して符号化を変換します。長方形画像の中で眠っていた空間情報を、直接視聴できるステレオ体験と没入体験へ変えることが目標でした。

この方針により、従来型ストリーミングクライアントへ新しい再生能力を加えました。左右並びの動画はステレオで視聴でき、180° コンテンツは目の前に半球として広がり、360° コンテンツは周囲を包みます。ステレオ表示とパノラマ投影は自由に組み合わせられます。

すべての体験で同じシステムプレーヤーを使い、再生、一時停止、シーク、画質選択、情報パネルを維持しています。画面上ではいくつかの選択肢にしか見えませんが、その背後には CDN のアドレス解決、セグメント索引、メディアのパッケージ化、ステレオ合成、動画符号化、システム表示があります。

中心となる課題は、長方形画像を運ぶだけだったパイプラインに、動画が持つ空間的な意味をすべて表現させることでした。

最初に、「目に対応するビューの数」と「画像を配置する場所」を二つの独立した次元へ分けました。

ビューレイアウトは左右の目が何を受け取るかを決め、投影はピクセルを平面、半球、完全な球面のどこへ置くかを決めます。一般的な視聴体験は、次の表で直接表せます。

ビューレイアウト平面180°360°
モノスコピック通常の 2D 動画モノスコピック半球動画モノスコピック全景動画
ステレオ平面 3D 動画ステレオ 180° 動画ステレオ 360° 動画

Side-by-Side(SBS)と Over-Under は、左右のビューを一枚の画像へ格納する方法です。MV-HEVC(Multiview HEVC)は符号化レイヤーで複数のビューを保持します。これらは「180° か 360° か」とは異なる問いに答えています。

プレーヤーは、メディアがパイプラインのどの段階にあるかも追跡する必要があります。処理すべき元素材なのか、すでにシステム要件を満たした配信可能なコンテンツなのか、という区別です。同じ「ステレオ 180°」の体験でも、SBS の元ファイルと配信可能な MV-HEVC ファイルでは処理経路が異なります。Apple Projected Media Profile(APMP)も制作と配信を明確に区別しています。ステレオ APMP の配信には MV-HEVC を使い、制作時のフレームパッキングをそのまま配信形式として扱うことはできません。Apple Movie Profiles

このモデルが、その後の作業に安定した土台を与えました。画質の変更は動画バリアントを変え、CDN の変更はアクセス経路を変えます。どちらの場合も、ビューレイアウトと投影の意味は維持しなければなりません。

全体のパイプラインは次のようになります。

再生パイプライン:元メディアと CDN 候補が選択・索引読み込みを経て三つの適応経路へ分岐し、システムの能力認識と AVKit プレーヤーへ合流する。

フルサイズのパイプライン図を開く

レンダリングへ進む前に、まず動画をどこから取得し、どうオンデマンドで読むかを解決しました。

従来のストリーミングソースが、完全な MP4 ファイルを配信するとは限りません。音声と動画は分離されていることが多く、同じコンテンツに複数の画質、コーデック、CDN URL が存在します。メディアデータは、初期化範囲とセグメント索引で記述されます。

そのため、URL の取得は出発点にすぎません。メイン URL とバックアップ URL を候補としてまとめ、ノードの種類に応じて優先順位を付けました。たとえば一部の PCDN ノードは優先度を下げ、リクエストが失敗したら別の候補を試します。選択は「先頭の URL を使う」だけでなく、ノードの特性と実際の読み込み結果を考慮するようになりました。

URL の選択以上に重要だったのが HTTP Range の挙動です。視聴者が特定の時刻へシークすると、下位レイヤーはその時刻を元ファイルのバイト範囲へ変換し、デコードに必要なデータだけを取得します。セグメント索引 sidx がその橋渡しをし、メディア時間、セグメント長、元オブジェクト内の位置を結び付けます。

見落としやすい点の一つが、索引の座標系です。索引を単独でダウンロードするとメモリ内の位置はゼロから始まりますが、元ファイル内のバイト位置は変わりません。パーサーはこの関係を保持する必要があります。そうしなければ、もっともらしいオフセットが誤ったデータを指すことになります。

このレイヤーでは、保守的に見える選択も残しました。重要なメタデータには、同時実行数を制御した個別の Range リクエストを使います。複数範囲をまとめればリクエスト数を減らせますが、一部の CDN はマルチレンジリクエストに対してオブジェクト全体を返します。小さなメタデータ取得が巨大なファイルのダウンロードになってしまいます。実装ではセグメント読み込みのレスポンス状態と返された長さを確認し、失敗する候補から切り替えます。

バックアップ URL への切り替えにも明確な境界があります。下流のレスポンスがメディアバイトを出力し始めた後で、別の CDN のレスポンスを自由につなぐことはできません。ネットワーク層が「再試行成功」と報告しても、プレーヤーには壊れたデータの継ぎ合わせが届くからです。この制約は、最初のフレーム、シーク、障害復旧の信頼性に直結します。

ファイル形式のランダムアクセスが必要な処理経路のために、仮想 MP4 レイヤーも構築しました。ファイルヘッダーとサンプルテーブルをローカルで組み立て、仮想ファイル内の読み込みを遠隔の音声・動画オブジェクトへ対応付けます。元のメディアデータは CDN に残り、クライアントは必要な分だけ取得します。

これにより、処理を始める前に動画全体をダウンロードすることなく、分離した遠隔メディアリソースを上位レイヤーから一つのアセットとして扱えます。

前述のプロトコル記述を使い、元の DASH リソースにある初期化情報と sidx 索引を HLS へ再構成できます。EXT-X-MAP は初期化セグメントを参照し、EXTINF は時間区間を表し、EXT-X-BYTERANGE は元の CDN オブジェクト内の位置を表します。この基本転送経路は、同じメディアデータへアクセスする別の記述を生成するため、既存の圧縮セグメントを再利用できます。

モノスコピックの 180°・360° コンテンツでは、適応の中心は投影の意味です。

パノラマ動画も、保存時には長方形画像です。変わるのはピクセルの意味です。360° のエクイレクタングラー画像は横軸に経度、縦軸に緯度を割り当てます。180° の半エクイレクタングラー画像は前方の半球を覆います。システムが正しい視聴空間を再構成するには、この対応を知る必要があります。WWDC25:visionOS の動画体験を探る

元のピクセルが対象投影とすでに一致し、符号化とパッケージも処理要件を満たす場合、圧縮済みのメディアデータを保ったまま、初期化情報へ APMP の投影宣言を加え、一致する HLS 記述を生成できます。この経路の主なコストはコンテナ処理とネットワーク読み込みです。

MP4 では、関連情報を Video Extended Usage、つまり vexu が保持します。proj/prji は投影形式、eyes/stri はステレオビュー情報、制作素材の pack/pkin は左右のビューの格納方法を記述します。それぞれ形状、ビュー、保存レイアウトという別の問いに答えるため、互いに代用できません。Stereo Video ISOBMFF Extensions

宣言を書き込んだ後も、システムが非平面投影を実際に認識するか確認する必要があります。モノスコピックパノラマの経路では、AVAssetPlaybackAssistant から能力情報を照会し、認識に失敗した場合の明示的なフォールバックを残しています。

この方法には明確な境界があります。対象投影へ展開済みのパノラマ素材には正しい空間記述を付けられますが、デュアルフィッシュアイなど別の投影には、適切な幾何変換が必要です。

左右並びの 3D では、処理がすべてのフレームに及びます。

通常のデコーダーで SBS 動画を読むと、二つの画像を含んだ一枚のフレームが得られます。システムがステレオコンテンツとして利用できるようにするには、実際のパッキングレイアウトに従って二つのビューを分離し、同じ表示時刻を保ち、それぞれが左目用か右目用かを明示する必要があります。

平面ステレオ経路では、カスタム動画コンポジターでこの処理を行い、Core Media のタグ付きバッファーを通して左右のビューを出力します。タグにはメディアタイプ、目の割り当て、投影の意味が含まれ、合成結果にシステムが理解できる構造を与えます。AVAsynchronousVideoCompositionRequest

アスペクト比、切り出し方向、出力サイズも一緒に扱う必要があります。SBS は片目あたりの有効な幅に影響し、Over-Under は有効な高さに影響します。格納済み画像全体の寸法を片目の寸法として扱うと、景色が押しつぶされます。左右の順序を反転すると、知覚される奥行き関係も変わります。

色情報もパイプライン全体を通る必要があります。デコード済みフレームの YCbCr 行列、色原色、伝達関数を、コンポジターの出力へ正しく継承しなければなりません。左右のビューを正しく分離しても、色の記述が失われれば色ずれや明るさ関係の誤りが起こります。空間適応では、形状、時間、色を同時に維持する必要があります。

この経路は再生中に左右のビューを配布できるため、完全なステレオファイルが事前に生成されるのを待たずに済みます。ただし出力は実行時の左右ビューフレームです。配信仕様に適合した MV-HEVC 動画を生成する能力とは異なる段階にあります。

ステレオパノラマ動画では、適応をさらに符号化と配信まで進めました。

配信の再構成が必要なステレオパノラマストリームには、オンデマンドで MV-HEVC へ変換し、APMP fMP4/HLS としてパッケージ化する経路を追加しました。具体的な経路はソースの提供方法によって変わります。ファイル形式の入力では、投影タグ付きのステレオ合成を引き続き使えます。別々のストリームで配信される投影ステレオコンテンツでは、まずネイティブ配信形式への変換を試し、互換性のためにコンポジター経路も残します。Apple の公式変換サンプルも、元のレイアウト、投影記述、配信形式の完全な関係を示しています。投影動画を Apple Projected Media Profile へ変換する

この処理は、再生位置を中心にしたセグメントパイプラインとして構成しました。まず必要な遠隔の音声・動画セグメントを特定し、読み取り可能な入力として準備します。デコード後に左右のビューを分離して VideoToolbox へ渡し、符号化します。パッケージ層が初期化セグメントとメディアセグメントを出力し、システムプレーヤーはローカルのループバック HTTP サーバーから HLS リソースを読み取ります。

これにより、動画全体は完全なタイムライン索引を保ちながら、必要なセグメントだけを変換できます。シークすると処理対象領域の優先度が変わり、再生位置が移動した後は古いタスクをキャンセルできます。生成済みセグメントは上限付きキャッシュへ入り、近接セグメントは適度に先読みします。

スケジューリングの目標は、同じ時間領域を中心にネットワーク読み込み、デコード、符号化、再生バッファリングを調整することです。最初のフレームには、再生可能な領域をできるだけ早く用意する必要があります。連続再生には十分な処理スループットが必要で、シーク時には作業を新しい位置へ素早く移す必要があります。解像度、フレームレート、ネットワーク状況、デバイス負荷が、これらの目標間のトレードオフを形作ります。

セグメント変換には、慎重に扱うべき境界もあります。元セグメントと対象セグメントの境界が一致しない場合があるため、切り詰めにはタイムスタンプを使います。独立して符号化した領域には、正しい初期化宣言と不連続宣言が必要です。音声は同じタイムラインで出力へ入れます。対象セグメントの生成に失敗したら、エラーを明らかにし、再試行できるようにします。前のセグメントで穴を埋めると、プレーヤーは同じ短い部分を繰り返してしまいます。

この経路には再符号化が含まれます。そのため「元の解像度を維持する」はサイズ決定の方針を表すだけです。画質、色、音声にはそれぞれ固有の処理制約があり、具体的な符号化経路ごとに評価する必要があります。

最後の層は、メディア能力を確実にシステムプレーヤーへ渡すことです。

再生と操作の中心には AVPlayer と AVPlayerViewController を置き、利用可能な視聴体験は AVKit に管理させました。これにより、空間再生を既存の一時停止、シーク、画質選択、パネルのロジックへ組み込めます。AVKit で没入型メディアを再生する

この層では、三つの状態を区別し続ける必要があります。アプリが許可する体験、現在のメディアが提供できるとシステムが判断した体験、ユーザーが実際に入った体験です。設定で没入体験を許可しても、それはアプリが提供する意思を示すだけです。成功を確認するには、メディア認識と実際の体験状態から得られる根拠も必要です。

そのため、モード切り替えはトランザクションとして扱います。新しいメディア構成をバックグラウンドで準備し、成功してからプレーヤーを置き換え、現在位置と再生意図を復元します。準備に失敗した場合は古いコンテンツを維持します。ユーザーが続けて複数の切り替えを要求した場合、古いタスクの結果が最新の選択を上書きしてはいけません。

同じ仕組みで、画質変更と転送経路のフォールバックも扱います。ネットワーク障害により読み込み経路が変わっても、「ステレオ 180°」を異なるメディアの意味を持つコンテンツへ密かに変えてはいけません。本当にダウングレードが必要なら、実際の再生状態と画面に表示する選択を同期させます。

このパイプライン用に作成した検証記録では、HLS 宣言、コンテナメタデータ、フレームワークの認識、コンポジター出力、最終的な視聴体験を段階ごとに調べます。構造テストは情報が一貫して伝わるかを確認し、実機での視覚確認は形状、左右の順序、継ぎ目、最初のフレーム、切り替え動作を検証します。この二種類の根拠には異なる役割があります。

この記事の対象は、平面ステレオ動画と、180°・360° 投影コンテンツを組み合わせたものの適応です。Apple ブランドの Apple Immersive Video には、独自の形式と制作システムがあります。通常のステレオパノラマコンテンツを APMP へ変換しても、自動的に Apple Immersive Video になるわけではありません。Apple Immersive Video

この仕事で最も達成感があったのは、ネットワーク、コンテナ、符号化、レンダリングに分散していた制約を、一つの協調する再生パイプラインへまとめられたことです。ユーザーが視聴オプションを変えると、元データの読み込み、フレームの構成、システムによるコンテンツの理解がすべて連動して変化します。

動画は同じストリーミング基盤から届きますが、私たちがそれを見る空間は大きく広がります。

長い道のり

実際のところ、このプロジェクトには非常に長い期間がかかり、決して順調ではありませんでした。

このような動画アプリを作りたいと初めて思ったのは 2024 年初頭です。空間ビデオ、3D ビデオ、没入型ビデオを初めて体験した時期でした。

自分の考えが少しずつ形になり、Apple の API も発展を続けました。visionOS 26 が登場したころには、従来のステレオ動画を AVPlayerViewController で再生するために必要な API がそろいました。

同時に、さらに大きな変化も起きていました。AI です。初期の ChatGPT や Claude を使ってこの問題を解こうと試み続け、アプローチはすでにかなり成熟していました。

そして GPT 5.6 の公開からしばらく経ったある日、このプロジェクトをきちんと完成させる時が来たと決めました。

このプロジェクトでの私自身の経験として、コーディングと実装詳細の調査の 80% 以上を GPT 5.6 が担ったことは認めなければなりません。

HLS のタグや属性をデバッグし、動画セグメントを手作業で分割・整列するコードをすべて自分で書いていたら、どれほどの時間が必要だったか想像もつきません。

参考資料

この記事は、実装したパイプラインのアーキテクチャと原則に焦点を当てています。APMP と関連するシステム再生機能については、visionOS 26 以降を前提にしています。

コメント

GitHub アカウントでディスカッションに参加できます。コメントはこのブログの Discussions で公開されます。 GitHub で開く

あわせて読みたい