Menambahkan video spasial ke aplikasi

Jetpack XR SDK mendukung pemutaran video berdampingan stereoskopik ke permukaan datar. Dengan video stereoskopis, setiap frame terdiri dari gambar mata kiri dan mata kanan untuk memberikan kesan kedalaman kepada penonton—juga dikenal sebagai stereopsis.

Anda dapat merender video 2D non-stereoskopik di aplikasi Android XR dengan API media standar yang digunakan untuk pengembangan Android pada faktor bentuk lainnya.

Memutar video berdampingan menggunakan Jetpack SceneCore

Dengan video berdampingan, setiap frame stereoskopik ditampilkan sebagai dua gambar yang disusun berdampingan secara horizontal. Frame video atas dan bawah disusun secara vertikal berdekatan satu sama lain.

Video berdampingan bukanlah codec, melainkan cara mengatur frame stereoskopik, yang berarti dapat dienkode dalam codec apa pun yang didukung oleh Android.

Anda dapat memuat video berdampingan menggunakan Media3 Exoplayer, lalu merendernya menggunakan SurfaceEntity baru. Untuk membuat SurfaceEntity, panggil SurfaceEntity.create, seperti yang ditunjukkan dalam contoh berikut.

val stereoSurfaceEntity = SurfaceEntity.create(
    xrSession,
    SurfaceEntity.StereoMode.SIDE_BY_SIDE,
    Pose(Vector3(0.0f, 0.0f, -1.5f)),
    SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f)
)
val videoUri = Uri.Builder()
    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
    .path("sbs_video.mp4")
    .build()
val mediaItem = MediaItem.fromUri(videoUri)

val exoPlayer = ExoPlayer.Builder(this).build()
exoPlayer.setVideoSurface(stereoSurfaceEntity.getSurface())
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()

Memutar video MV-HEVC menggunakan Jetpack SceneCore

Standar codec MV-HEVC dioptimalkan dan dirancang untuk video stereoskopik, sehingga aplikasi Anda dapat memutar video imersif secara efisien dengan kualitas yang sangat baik. File MV-HEVC memiliki aliran utama, biasanya mata kiri, dan aliran stereo dengan mata lainnya.

Mirip dengan video berdampingan, Anda dapat memuatnya menggunakan Media3 Exoplayer dan merendernya menggunakan SurfaceEntity. Anda harus menentukan apakah file MV-HEVC Anda adalah primer kiri atau kanan dalam parameter stereoMode saat memanggil SurfaceEntity.create.

// Create the SurfaceEntity with the StereoMode corresponding to the MV-HEVC content
val stereoSurfaceEntity = SurfaceEntity.create(
    xrSession,
    SurfaceEntity.StereoMode.MULTIVIEW_LEFT_PRIMARY,
    Pose(Vector3(0.0f, 0.0f, -1.5f)),
    SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f)
)
val videoUri = Uri.Builder()
    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
    .path("mvhevc_video.mp4")
    .build()
val mediaItem = MediaItem.fromUri(videoUri)

val exoPlayer = ExoPlayer.Builder(this).build()
exoPlayer.setVideoSurface(stereoSurfaceEntity.getSurface())
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()

Memutar video spasial yang dilindungi DRM menggunakan Jetpack SceneCore

Jetpack XR SDK mendukung pemutaran streaming video terenkripsi menggunakan framework Manajemen Hak Digital (DRM) bawaan Android. DRM melindungi konten Anda dengan memungkinkan distribusi yang aman dan mencegah penyalinan atau pemutaran yang tidak sah.

Proses ini melibatkan aplikasi pemutar media Anda yang menghubungi server lisensi untuk mendapatkan kunci dekripsi. Di Android, proses ini dikelola dengan aman, dan frame video yang didekripsi dirender ke buffer grafis yang dilindungi yang tidak dapat diakses oleh sistem atau aplikasi lain, sehingga mencegah perekaman layar.

Untuk memutar video yang dilindungi DRM dengan Jetpack SceneCore, Anda harus:

  1. Konfigurasi SurfaceEntity untuk meminta platform yang dilindungi.
  2. Konfigurasi Media3 Exoplayer dengan informasi DRM yang diperlukan untuk menangani pertukaran kunci.
  3. Setel output pemutar ke permukaan SurfaceEntity.

Contoh berikut menunjukkan cara mengonfigurasi ExoPlayer untuk memutar streaming yang dilindungi DRM dan merendernya di SurfaceEntity:

// Create a SurfaceEntity with DRM content

// 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"

// Create the SurfaceEntity with the PROTECTED content security level.
val protectedSurfaceEntity = SurfaceEntity.create(
    session = xrSession,
    stereoMode = SurfaceEntity.StereoMode.SIDE_BY_SIDE,
    pose = Pose(Vector3(0.0f, 0.0f, -1.5f)),
    canvasShape = SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f),
    contentSecurityLevel = SurfaceEntity.ContentSecurityLevel.PROTECTED
)

// 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()

// Initialize ExoPlayer and set the protected surface.
val exoPlayer = ExoPlayer.Builder(this).build()
exoPlayer.setVideoSurface(protectedSurfaceEntity.getSurface())

// Set the media item and start playback.
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()

Untuk mengetahui ringkasan yang lebih mendetail tentang framework DRM media Android, lihat dokumentasi DRM Media di source.android.com.

Memutar video 180 derajat dan 360 derajat menggunakan Jetpack SceneCore

SurfaceEntity mendukung pemutaran video 180° di permukaan hemisfer dan video 360° di permukaan bola. Parameter radius mengacu pada ukuran radial permukaan masing-masing dalam meter secara default.

Kode berikut menunjukkan cara menyiapkan SurfaceEntity untuk pemutaran pada hemisfer 180° dan bola 360°. Saat menggunakan bentuk kanvas ini, posisikan permukaan dengan memanfaatkan pose kepala pengguna untuk memberikan pengalaman imersif.

// Set up the surface for playing a 180° video on a hemisphere.
val hemisphereStereoSurfaceEntity =
    SurfaceEntity.create(
        xrSession,
        SurfaceEntity.StereoMode.SIDE_BY_SIDE,
        xrSession.scene.spatialUser.head?.transformPoseTo(
            Pose.Identity,
            xrSession.scene.activitySpace
        )!!,
        SurfaceEntity.CanvasShape.Vr180Hemisphere(1.0f),
    )
// ... and use the surface for playing the media.

// Set up the surface for playing a 360° video on a sphere.
val sphereStereoSurfaceEntity =
    SurfaceEntity.create(
        xrSession,
        SurfaceEntity.StereoMode.TOP_BOTTOM,
        xrSession.scene.spatialUser.head?.transformPoseTo(
            Pose.Identity,
            xrSession.scene.activitySpace
        )!!,
        SurfaceEntity.CanvasShape.Vr360Sphere(1.0f),
    )
// ... and use the surface for playing the media.

Kontrol SurfaceEntity lanjutan

Untuk kontrol yang lebih canggih atas rendering video dan gambar, seperti menerapkan efek materi kustom, Anda dapat bekerja langsung dengan SurfaceEntity dari library SceneCore.

Bagian berikut menjelaskan beberapa fitur lanjutan yang tersedia di SurfaceEntity.

Menerapkan pembauran tepi

Haluskan tepi permukaan untuk membantu memadukannya dengan lingkungan dengan menetapkan properti edgeFeather.

// Create a SurfaceEntity.
val surfaceEntity = SurfaceEntity.create(
    session = xrSession,
    pose = Pose(Vector3(0.0f, 0.0f, -1.5f))
)

// Feather the edges of the surface.
surfaceEntity.edgeFeather =
    SurfaceEntity.EdgeFeatheringParams.SmoothFeather(0.1f, 0.1f)

Menerapkan mask alfa

Terapkan mask alpha untuk membuat permukaan non-persegi panjang atau menambahkan efek transparansi. Pertama, muat Texture dari aset, lalu tetapkan ke properti primaryAlphaMaskTexture:

// Create a SurfaceEntity.
val surfaceEntity = SurfaceEntity.create(
    session = xrSession,
    pose = Pose(Vector3(0.0f, 0.0f, -1.5f))
)

// Load the texture in a coroutine scope.
activity.lifecycleScope.launch {
    val alphaMaskTexture =
        Texture.create(
            xrSession,
            Paths.get("textures", "alpha_mask.png"),
            TextureSampler.create()
        )

    // Apply the alpha mask.
    surfaceEntity.primaryAlphaMaskTexture = alphaMaskTexture

    // To remove the mask, set the property to null.
    surfaceEntity.primaryAlphaMaskTexture = null
}

Memutar video spasial menggunakan Jetpack Compose untuk XR

Jika Anda tertarik untuk mempelajari cara memutar video menggunakan Jetpack Compose untuk XR, pelajari cara menambahkan permukaan untuk konten gambar atau video.