SpatialExternalSurface は、アプリが画像や動画などのコンテンツを描画できる Surface を作成して管理するサブスペース コンポーザブルです。SpatialExternalSurface は、ステレオスコープ コンテンツまたはモノスコープ コンテンツのいずれかをサポートしています。
画像または動画コンテンツのサーフェスを追加する
次の例は、Media3 Exoplayer と SpatialExternalSurface を使用して、サイドバイサイドのステレオスコープ動画を読み込む方法を示しています。
@OptIn(ExperimentalComposeApi::class) @Composable fun SpatialExternalSurfaceContent() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) // Default width is 400.dp if no width modifier is specified .height(676.dp), // Default height is 400.dp if no height modifier is specified // Use StereoMode.Mono, StereoMode.SideBySide, or StereoMode.TopBottom, depending // upon which type of content you are rendering: monoscopic content, side-by-side stereo // content, or top-bottom stereo content stereoMode = StereoMode.SideBySide, ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } val videoUri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) // Represents a side-by-side stereo video, where each frame contains a pair of // video frames arranged side-by-side. The frame on the left represents the left // eye view, and the frame on the right represents the right eye view. .path("sbs_video.mp4") .build() val mediaItem = MediaItem.fromUri(videoUri) // onSurfaceCreated is invoked only one time, when the Surface is created onSurfaceCreated { surface -> exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } // onSurfaceDestroyed is invoked when the SpatialExternalSurface composable and its // associated Surface are destroyed onSurfaceDestroyed { exoPlayer.release() } } } }
コードに関する主なポイント
- レンダリングするコンテンツの種類に応じて、
StereoModeをMono、SideBySide、TopBottomのいずれかに設定します。Mono: 画像または動画フレームは、両目に表示される単一の同一画像で構成されます。SideBySide: 画像または動画フレームに、左右に並べられた画像または動画フレームのペアが含まれています。左側の画像またはフレームは左目のビューを表し、右側の画像またはフレームは右目のビューを表します。TopBottom: 画像または動画フレームには、垂直方向に積み重ねられた画像または動画フレームのペアが含まれています。上部の画像またはフレームは左目のビューを表し、下部の画像またはフレームは右目のビューを表します。
SpatialExternalSurfaceは長方形のサーフェスのみをサポートしています。- この
Surfaceは入力イベントをキャプチャしません。 StereoModeの変更をアプリケーションのレンダリングや動画のデコードと同期することはできません。- このコンポーザブルは他のパネルの前にレンダリングできないため、レイアウトに他のパネルがある場合は
MovePolicyを使用しないでください。
DRM で保護された動画コンテンツ用のサーフェスを追加する
SpatialExternalSurface は、DRM で保護された動画ストリームの再生もサポートしています。これを有効にするには、保護されたグラフィック バッファにレンダリングするセキュアなサーフェスを作成する必要があります。これにより、コンテンツが画面録画されたり、安全でないシステム コンポーネントからアクセスされたりするのを防ぐことができます。
セキュアなサーフェスを作成するには、SpatialExternalSurface コンポーザブルで SpatialExternalSurfaceProtection パラメータを SpatialExternalSurfaceProtection.Protected に設定します。また、ライセンス サーバーからライセンスを取得できるように、適切な DRM 情報を使用して Media3 Exoplayer を構成する必要があります。
次の例は、DRM で保護された動画ストリームを再生するように SpatialExternalSurface と ExoPlayer を構成する方法を示しています。
@OptIn(ExperimentalComposeApi::class) @Composable fun DrmSpatialVideoPlayer() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) .height(676.dp), stereoMode = StereoMode.SideBySide, surfaceProtection = SpatialExternalSurfaceProtection.Protected ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } // Define the URI for your DRM-protected content and license server. val videoUri = "https://your-content-provider.com/video.mpd" val drmLicenseUrl = "https://your-license-server.com/license" // Build a MediaItem with the necessary DRM configuration. val mediaItem = MediaItem.Builder() .setUri(videoUri) .setDrmConfiguration( MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID) .setLicenseUri(drmLicenseUrl) .build() ) .build() onSurfaceCreated { surface -> // The created surface is secure and can be used by the player. exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } onSurfaceDestroyed { exoPlayer.release() } } } }
コードに関する主なポイント
- 保護されたサーフェス:
SpatialExternalSurfaceでsurfaceProtection = SpatialExternalSurfaceProtection.Protectedを設定することは、基盤となるSurfaceが DRM コンテンツに適したセキュアなバッファによってバックアップされるために不可欠です。 - DRM 構成: DRM スキーム(
C.WIDEVINE_UUIDなど)とライセンス サーバーの URI を使用してMediaItemを構成する必要があります。ExoPlayer はこの情報を使用して DRM セッションを管理します。 - セキュアなコンテンツ: 保護されたサーフェスにレンダリングする場合、動画コンテンツはデコードされ、セキュアなパスに表示されます。これにより、コンテンツ ライセンスの要件を満たすことができます。これにより、コンテンツがスクリーン キャプチャに表示されることも防ぐことができます。