Platform eksternal spasial

Perangkat XR yang kompatibel
Panduan ini membantu Anda membangun pengalaman untuk jenis perangkat XR ini.
Headset XR
Kacamata XR Berkabel

SpatialExternalSurface adalah composable subruang yang membuat dan mengelola Surface tempat aplikasi Anda dapat menggambar konten, seperti gambar atau video. SpatialExternalSurface mendukung konten stereoskopis atau monoskopis.

Menambahkan platform untuk konten gambar atau video

Contoh ini menunjukkan cara memuat video stereoskopis berdampingan menggunakan Media3 Exoplayer dan 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() }
        }
    }
}

Poin penting tentang kode

  • Tetapkan StereoMode ke Mono, SideBySide, atau TopBottom, bergantung pada jenis konten yang Anda render:
    • Mono: Frame gambar atau video terdiri dari satu gambar identik yang ditampilkan ke kedua mata.
    • SideBySide: Gambar atau frame video berisi sepasang gambar atau frame video yang disusun berdampingan, dengan gambar atau frame di sebelah kiri mewakili tampilan mata kiri, dan gambar atau frame di sebelah kanan mewakili tampilan mata kanan.
    • TopBottom: Frame gambar atau video berisi sepasang gambar atau frame video yang ditumpuk secara vertikal, dengan gambar atau frame di bagian atas mewakili tampilan mata kiri, dan gambar atau frame di bagian bawah mewakili tampilan mata kanan.
  • SpatialExternalSurface hanya mendukung platform persegi panjang.
  • Surface ini tidak merekam peristiwa input.
  • Perubahan StereoMode tidak dapat disinkronkan dengan rendering aplikasi atau decoding video.
  • Composable ini tidak dapat dirender di depan panel lain, jadi Anda tidak boleh menggunakan MovePolicy jika ada panel lain dalam tata letak.

Menambahkan platform untuk konten video yang dilindungi DRM

SpatialExternalSurface juga mendukung pemutaran streaming video yang dilindungi DRM. Untuk mengaktifkannya, Anda harus membuat platform aman yang merender ke buffer grafis yang dilindungi. Tindakan ini mencegah konten direkam di layar atau diakses oleh komponen sistem yang tidak aman.

Untuk membuat platform yang aman, tetapkan parameter SpatialExternalSurfaceProtection ke SpatialExternalSurfaceProtection.Protected pada composable SpatialExternalSurface. Selain itu, Anda harus mengonfigurasi Media3 Exoplayer dengan informasi DRM yang sesuai untuk menangani akuisisi lisensi dari server lisensi.

Contoh berikut menunjukkan cara mengonfigurasi SpatialExternalSurface dan ExoPlayer untuk memutar streaming video yang dilindungi DRM:

@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() }
        }
    }
}

Poin penting tentang kode

  • Platform yang Dilindungi: Menyetel surfaceProtection = SpatialExternalSurfaceProtection.Protected di SpatialExternalSurface sangat penting agar Surface yang mendasarinya didukung oleh buffer aman yang sesuai untuk konten DRM.
  • Konfigurasi DRM: Anda harus mengonfigurasi MediaItem dengan skema DRM (misalnya, C.WIDEVINE_UUID) dan URI server lisensi Anda. ExoPlayer menggunakan informasi ini untuk mengelola sesi DRM.
  • Konten Aman: Saat dirender ke platform yang dilindungi, konten video didekode dan ditampilkan di jalur yang aman, yang membantu memenuhi persyaratan lisensi konten. Hal ini juga mencegah konten muncul dalam screenshot.