SDK Jetpack XR hỗ trợ phát video cạnh nhau âm thanh nổi trên các bề mặt phẳng. Với video 3D, mỗi khung hình bao gồm một hình ảnh mắt trái và một hình ảnh mắt phải để mang đến cho người xem cảm giác về chiều sâu.
Bạn có thể kết xuất video 2D không lập thể trên các ứng dụng Android XR bằng API đa phương tiện tiêu chuẩn dùng để phát triển Android trên các hệ số hình dạng khác.
Phát video cạnh nhau bằng SDK Jetpack XR
Với video cạnh nhau, mỗi khung hình ba chiều được trình bày dưới dạng hai hình ảnh được sắp xếp cạnh nhau theo chiều ngang. Các khung hình video trên cùng và dưới cùng được sắp xếp theo chiều dọc cạnh nhau.
Video cạnh nhau không phải là một bộ mã hoá và giải mã mà là một cách sắp xếp các khung hình ba chiều, tức là video này có thể được mã hoá bằng bất kỳ bộ mã hoá và giải mã nào mà Android hỗ trợ.
Jetpack SceneCore
Bạn có thể tải video cạnh nhau bằng Media3 Exoplayer, sau đó hiển thị video đó bằng SurfaceEntity
mới. Để tạo SurfaceEntity
, hãy gọi SurfaceEntity.create
như trong ví dụ sau.
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()
Jetpack Compose cho XR
Alpha04 trở lên
Kể từ Phiên bản 1.0.0-alpha04
, Jetpack Compose cho XR cung cấp một cách khác để tải và kết xuất video cạnh nhau. Sử dụng SpatialExternalSurface
, một thành phần kết hợp không gian con tạo và quản lý Surface
mà ứng dụng có thể vẽ nội dung, chẳng hạn như hình ảnh hoặc video. Để biết thêm thông tin chi tiết về SpatialExternalSurface
, hãy xem hướng dẫn Phát triển giao diện người dùng bằng Compose cho XR.
Ví dụ này minh hoạ cách tải video cạnh nhau bằng Media3 Exoplayer và SpatialExternalSurface
.
@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() } } } }
Phát video 180 độ và 360 độ bằng SDK Jetpack XR
SurfaceEntity
hỗ trợ phát video 180° trên bề mặt hình bán cầu và video 360° trên bề mặt hình cầu. Nếu video là 3D, thì các tệp phải ở định dạng cạnh nhau.
Mã sau đây cho biết cách thiết lập SurfaceEntity
để phát trên một bán cầu 180° và một hình cầu 360°. Khi sử dụng các hình dạng canvas này, hãy định vị bề mặt bằng cách tận dụng tư thế đầu của người dùng để mang lại trải nghiệm sống động.
// 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.