ハイライト
visionOS の動画再生は既存の AVFoundation + AVKit コードをそのまま活用します。AVPlayerViewController は RealityKit レンダリングで空間没入体験を実現し、3D 動画、空間オーディオ、自動環境調光に対応。開発者は visionOS SDK でビルドし、プレイヤーをウィンドウいっぱいに表示するだけで済みます。
主要内容
既存コードがそのまま使える
iOS で AVPlayerViewController を使って動画を再生していますか?visionOS ではほとんどコードを変える必要がありません。
(00:42)AVFoundation がストリーミング、解析、デコード、同期などの低レベル処理を担当します。AVKit の AVPlayerViewController は visionOS で RealityKit レンダリングに強化され、動画がユーザー周囲の空間にシームレスに溶け込み、オーディオも空間位置に応答します。
互換性のある iOS App(iOS SDK でビルド)は iOS 互換の再生体験を得られます。完全な空間強化体験には、Xcode プロジェクトを visionOS SDK でビルドする必要があります。
3 行のコードで空間シネマを起動
(02:23)使い方は iOS/tvOS とまったく同じです:
import AVFoundation
import AVKit
let playerViewController = AVPlayerViewController()
playerViewController.player = AVPlayer(url: videoURL)
present(playerViewController, animated: true)
キーポイント:
- player item を作成する前に view controller に player を設定し、メディア読み込み前に表示方法を把握してパフォーマンスを向上
- AVPlayerViewController をウィンドウいっぱいに表示して最適な没入体験を実現
- SwiftUI では UIViewControllerRepresentable でラップ
空間再生体験
(03:27)App 起動後、ユーザー目の前に大きなスクリーンが現れ、部屋が自動的に暗くなり映画鑑賞の雰囲気を演出します。移動してもスクリーンはその位置に留まり、オーディオはスクリーンに固定されます。スクリーンを見て指をピンチすると、動画の前方に再生コントロールが浮かび上がります。Digital Crown で音量を調整するか、没入型環境(シアター環境など)を開きます。
再生コントロールの詳細
(04:48)visionOS の再生コントロールには以下が含まれます:
- 右上: 音量コントロール(Digital Crown でも調整可能)
- 左下: 再生/一時停止、巻き戻し/早送り
- 下部中央: シークバー
- 右下: その他のオプション(再生速度、音声トラック選択、字幕、調光効果)
調光効果(Dimming Effect)はオフにでき、動画視聴中も周囲の環境を見られます。
高度な機能
(05:49)
サムネイルシーク: HLS ストリームに I-frame only playlist(Trick Play トラック)が含まれる場合、進行バーをドラッグすると自動的にサムネイルが表示されます。幅 145 ピクセルの小さな Trick Play トラックを推奨します。
インタースティシャル: タイムラインにロゴ、振り返り、広告を挿入できます。AVPlayerInterstitialEventController でプログラム的に設定するか、HLS ストリーム内で記述します。
コンテキストアクション: 「イントロをスキップ」「次のエピソードを再生」などのカスタムボタンを追加できます。
カスタム情報パネル: コンテンツのメタデータや関連コンテンツの推薦を表示します。
没入型空間(Immersive Space)
(07:13)App は Immersive Space を作成でき、動画スクリーンは自動的にその空間に移動し、固定サイズと位置に固定されて最適な視聴角度を保証します。コントロールはスクリーンから離れて少し近づき、操作しやすくなります。
@main
struct MoviePlayingApp: App {
@State private var immersionStyle: ImmersionStyle = .full
var body: some Scene {
WindowGroup {
ContentView()
}
ImmersiveSpace(id: "theater") {
TheaterView()
}
.immersionStyle(selection: $immersionStyle, in: .full)
}
}
struct ContentView: View {
@Environment(\.openImmersiveSpace) var openImmersiveSpace
var body: some View {
PlayerView()
.onAppear {
Task {
await openImmersiveSpace(id: "theater")
}
}
}
}
キーポイント:
ImmersiveSpaceが 3D コンテンツシーンを定義openImmersiveSpaceで空間を開くと、AVPlayerViewController が自動的に動画スクリーンを移動- Immersive Space のデザインがプレイヤーのドッキングを収容できることを確認
詳細
動画表示方式の比較
(12:32)visionOS は用途に応じた複数の動画表示方式を提供します:
| 方式 | API | 適用シーン | 3D 動画 | 再生コントロール | システム統合 |
|---|---|---|---|---|---|
| フルスクリーンプレイヤー | AVPlayerViewController(ウィンドウいっぱい) | 映画鑑賞 | 対応 | 完全 | 完全 |
| インラインプレイヤー | AVPlayerViewController(ウィンドウいっぱいでない) | ドキュメント内埋め込み、プレビュー | 非対応 | 簡略 | 一部 |
| 3D シーンエンティティ | VideoPlayerComponent | スプラッシュ画面、動画トランジション | 対応 | なし | なし |
| カスタムジオメトリ | VideoMaterial | エフェクト、アート展示 | 対応 | なし | なし |
VideoPlayerComponent の使用
(09:56)3D シーンで動画をエンティティとして表示する必要がある場合(スプラッシュ画面、動画トランジションなど)、RealityKit の VideoPlayerComponent を使用します:
import RealityKit
import AVFoundation
// 動画エンティティを作成
let videoEntity = Entity()
// AVPlayer を作成
let player = AVPlayer(url: videoURL)
// VideoPlayerComponent を追加
videoEntity.components[VideoPlayerComponent.self] = VideoPlayerComponent(
avPlayer: player
)
// 通常のエンティティと同じように配置
videoEntity.position = [0, 1.5, -2]
videoEntity.scale = [2, 1.125, 1]
// シーンに追加
scene.addChild(videoEntity)
// 再生
player.play()
キーポイント:
VideoPlayerComponentが正しいアスペクト比の動画メッシュを自動作成- 字幕表示に対応
- AVPlayerLayer より高性能、3D 動画フォーマットに対応
- 再生コントロールやシステム統合が不要なシーンに最適
VideoMaterial の使用
(10:46)より多くの制御が必要な場合(カスタムジオメトリ上に動画を表示するなど)、VideoMaterial を使用します:
import RealityKit
import AVFoundation
// カスタムジオメトリを作成
let mesh = MeshResource.generatePlane(width: 2, height: 1.125)
// VideoMaterial を作成
let player = AVPlayer(url: videoURL)
let videoMaterial = VideoMaterial(avPlayer: player)
// エンティティに適用
let videoEntity = ModelEntity(mesh: mesh, materials: [videoMaterial])
scene.addChild(videoEntity)
キーポイント:
VideoMaterialは任意のジオメトリ上に動画を表示可能- 元のアスペクト比は保証されない
- 字幕表示は非対応
- 動画をエフェクトとして使うシーンに最適
SwiftUI 統合の完全な例
import SwiftUI
import AVKit
import AVFoundation
struct PlayerView: UIViewControllerRepresentable {
let videoURL: URL
func makeUIViewController(context: Context) -> AVPlayerViewController {
let controller = AVPlayerViewController()
let player = AVPlayer()
controller.player = player
// 先に player を設定してからコンテンツを読み込み、パフォーマンスを向上
let item = AVPlayerItem(url: videoURL)
player.replaceCurrentItem(with: item)
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {}
}
struct ContentView: View {
let videoURL = URL(string: "https://example.com/movie.m3u8")!
var body: some View {
PlayerView(videoURL: videoURL)
.ignoresSafeArea()
}
}
キーポイント:
ignoresSafeArea()でプレイヤーがウィンドウ全体を埋めることを保証AVPlayerItemを作成する前にcontroller.playerを設定し、プレイヤーが事前に表示方法を把握- 追加設定なしで空間オーディオと自動環境調光を取得
重要ポイント
-
既存の動画 App を visionOS に移行する
- 何を作るか: 既存の iOS 動画再生 App を visionOS SDK で再ビルド
- 価値がある理由: コード変更ゼロで大画面、空間オーディオ、環境調光を含む空間没入再生体験を獲得
- 始め方: Xcode で visionOS ターゲットを作成し、既存の AVPlayerViewController コードを再利用
-
動画 App に Immersive Space を追加する
- 何を作るか: 動画再生時に自動的に Immersive Space を開き、ユーザーをバーチャルシネマに誘導
- 価値がある理由: 動画スクリーンが最適な視聴位置に固定され、コントロールが近づいて操作しやすく、シネマ級体験を提供
- 始め方:
openImmersiveSpaceAPI をPlayerViewのonAppearでトリガー
-
サムネイルシークプレビューを実装する
- 何を作るか: HLS ストリームに Trick Play トラックを追加し、進行バードラッグ時にフレームプレビューを表示
- 価値がある理由: visionOS ではタッチスクリーンのような精密なシークができない。サムネイルが素早いナビゲーションを支援
- 始め方: HLS パッケージング時に I-frame only playlist を追加、幅 145 ピクセル
-
「イントロをスキップ」コンテキストアクションを追加する
- 何を作るか:
AVPlayerViewControllerの contextual actions API でスマートスキップボタンを追加 - 価値がある理由: visionOS の長尺動画体験には便利なナビゲーションが必要。コンテキストアクションは必要時に自動表示
- 始め方:
AVPlayerViewControllerDelegateのplayerViewController(_:contextualActionsFor:)メソッドを実装
- 何を作るか:
-
3D シーンで動画を環境要素として使う
- 何を作るか: VideoPlayerComponent で RealityKit シーンに動的動画要素を追加
- 価値がある理由: 空間体験 App に動的背景、情報表示、トランジション効果を追加
- 始め方: RealityKit エンティティを作成し、VideoPlayerComponent を付与してシーンに配置
関連セッション
- Deliver video content for spatial experiences — visionOS 向け 3D 動画ストリーミングコンテンツの準備と配信方法
- Design for spatial user interfaces — 空間コンピューティングプラットフォームの UI デザイン原則
- Meet SwiftUI for spatial computing — visionOS で SwiftUI を使ってインターフェースを構築
コメント
GitHub Issues · utterances