Das Jetpack XR SDK unterstützt die Wiedergabe von stereoskopischen Nebeneinander-Videos auf flachen Oberflächen. Bei stereoskopischen Videos besteht jedes Frame aus einem Bild für das linke und einem Bild für das rechte Auge, um den Zuschauern ein Gefühl von Tiefe zu vermitteln. Dieses Phänomen wird auch als Stereopsis bezeichnet.
Sie können nicht stereoskopische 2D-Videos in Android XR-Apps mit den Standard-Media-APIs rendern, die für die Android-Entwicklung auf anderen Formfaktoren verwendet werden.
Nebeneinander-Video mit Jetpack SceneCore abspielen
Bei der Side-by-Side-Darstellung wird jedes stereoskopische Frame als zwei Bilder dargestellt, die horizontal nebeneinander angeordnet sind. Die oberen und unteren Videoframes werden vertikal nebeneinander angeordnet.
Das Side-by-Side-Video ist kein Codec, sondern eine Methode zum Organisieren stereoskopischer Frames. Es kann also mit einem der von Android unterstützten Codecs codiert werden.
Sie können Side-by-Side-Videos mit Media3 ExoPlayer laden und dann mit dem neuen SurfaceEntity
rendern. Rufen Sie zum Erstellen eines SurfaceEntity
SurfaceEntity.create
auf, wie im folgenden Beispiel gezeigt.
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()
MV-HEVC-Video mit Jetpack SceneCore abspielen
Der MV-HEVC-Codec-Standard ist für stereoskopische Videos optimiert und konzipiert. So kann Ihre App immersive Videos in hoher Qualität effizient wiedergeben. MV-HEVC-Dateien haben einen primären Stream, in der Regel das linke Auge, und einen Stereostream mit dem anderen Auge.
Ähnlich wie bei Side-by-Side-Videos können Sie es mit Media3 Exoplayer laden und mit dem SurfaceEntity
rendern. Sie müssen im Parameter stereoMode
angeben, ob Ihre MV-HEVC-Datei links oder rechts primär ist, wenn Sie SurfaceEntity.create
aufrufen.
// 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()
180°- und 360°-Videos mit Jetpack SceneCore abspielen
SurfaceEntity
unterstützt die Wiedergabe von 180°-Videos auf halbkugelförmigen Oberflächen und von 360°-Videos auf kugelförmigen Oberflächen. Der Parameter radius
bezieht sich standardmäßig auf die radiale Größe der jeweiligen Oberflächen in Metern.
Der folgende Code zeigt, wie SurfaceEntity
für die Wiedergabe auf einer 180°-Halbkugel und einer 360°-Kugel eingerichtet wird. Wenn Sie diese Canvas-Formen verwenden, positionieren Sie die Oberfläche mithilfe der Kopfhaltung des Nutzers, um ein immersives Erlebnis zu schaffen.
// 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.
Erweiterte Steuerung von SurfaceEntity
Wenn Sie die Darstellung von Videos und Bildern genauer steuern möchten, z. B. um benutzerdefinierte Materialeffekte anzuwenden, können Sie direkt mit SurfaceEntity
aus der SceneCore-Bibliothek arbeiten.
In den folgenden Abschnitten werden einige der erweiterten Funktionen beschrieben, die auf SurfaceEntity
verfügbar sind.
Weichzeichnen der Kanten anwenden
Weichen Sie die Kanten der Oberfläche auf, damit sie sich besser in die Umgebung einfügt. Dazu können Sie die Eigenschaft edgeFeather
festlegen.
// 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)
Alphamasken anwenden
Mit einer Alphamaskierung können Sie nicht rechteckige Oberflächen erstellen oder Transparenzeffekte hinzufügen. Laden Sie zuerst ein Texture
aus einem Asset und weisen Sie es dann dem Attribut primaryAlphaMaskTexture
zu:
// 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 }
Räumliche Videos mit Jetpack Compose für XR abspielen
Wenn Sie wissen möchten, wie Sie Videos mit Jetpack Compose für XR abspielen, fügen Sie eine Oberfläche für Bild- oder Videoinhalte hinzu.