Jetpack XR SDK hỗ trợ việc phát video song song lập thể trên các bề mặt phẳng. Với video lập thể, mỗi khung hình bao gồm hình ảnh cho mắt trái và hình ảnh cho mắt phải để mang đến cho người xem cảm giác về chiều sâu – còn được gọi là hiệu ứng lập thể.
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 được dùng để phát triển Android trên các hệ số hình dạng khác.
Phát video song song bằng Jetpack SceneCore
Với video song song, mỗi khung hình lập thể được trình bày dưới dạng hai hình ảnh được sắp xếp theo chiều ngang cạnh nhau. Khung hình video trên và dưới được sắp xếp theo chiều dọc, liền kề nhau.
Video song song không phải là một codec mà là một cách sắp xếp các khung hình lập thể. Điều này có nghĩa là video song song có thể được mã hoá bằng bất kỳ codec nào mà Android hỗ trợ.
Bạn có thể tải video song song bằng Media3 Exoplayer rồi kết xuất video đó bằng SurfaceEntity
mới. Để tạo một 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()
Phát video MV-HEVC bằng Jetpack SceneCore
Tiêu chuẩn bộ mã hoá và giải mã MV-HEVC được tối ưu hoá và thiết kế cho video lập thể, cho phép ứng dụng của bạn phát hiệu quả các video sống động với chất lượng cao. Tệp MV-HEVC có một luồng chính (thường là mắt trái) và một luồng âm thanh nổi với mắt còn lại.
Tương tự như video cạnh nhau, bạn có thể tải video này bằng Media3 Exoplayer và kết xuất bằng SurfaceEntity
. Bạn sẽ muốn chỉ định xem tệp MV-HEVC của mình là tệp chính bên trái hay bên phải trong tham số stereoMode
khi gọi 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()
Phát video không gian được bảo vệ bằng DRM bằng Jetpack SceneCore
Jetpack XR SDK hỗ trợ việc phát các luồng video được mã hoá bằng khung Quản lý quyền kỹ thuật số (DRM) tích hợp sẵn của Android. DRM bảo vệ nội dung của bạn bằng cách cho phép phân phối an toàn và ngăn chặn hành vi sao chép hoặc phát trái phép.
Quy trình này liên quan đến việc ứng dụng trình phát nội dung nghe nhìn của bạn liên hệ với một máy chủ cấp phép để lấy khoá giải mã. Trên Android, quy trình này được quản lý một cách an toàn và các khung hình video đã giải mã được kết xuất vào một vùng đệm đồ hoạ được bảo vệ mà hệ thống hoặc các ứng dụng khác không thể truy cập, ngăn chặn việc chụp màn hình.
Để phát video được bảo vệ bằng DRM bằng Jetpack SceneCore, bạn cần:
- Định cấu hình
SurfaceEntity
để yêu cầu một nền tảng được bảo vệ. - Định cấu hình Media3 Exoplayer bằng thông tin DRM cần thiết để xử lý việc trao đổi khoá.
- Đặt đầu ra của trình phát thành bề mặt của
SurfaceEntity
.
Ví dụ sau đây cho thấy cách định cấu hình ExoPlayer để phát một luồng được bảo vệ bằng DRM và hiển thị luồng đó trên một 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()
Để biết thông tin tổng quan chi tiết hơn về khung DRM nội dung nghe nhìn của Android, hãy xem Tài liệu về DRM nội dung nghe nhìn trên source.android.com.
Phát video 180 độ và 360 độ bằng Jetpack SceneCore
SurfaceEntity
hỗ trợ phát video 180° trên các bề mặt bán cầu và video 360° trên các bề mặt hình cầu. Tham số radius
đề cập đến kích thước hướng tâm của các bề mặt tương ứng theo mét theo mặc định.
Đoạn mã sau đây cho biết cách thiết lập SurfaceEntity
để phát trên bán cầu 180° và hình cầu 360°. Khi sử dụng các hình dạng canvas này, hãy đặt vị trí 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.
Chế độ kiểm soát SurfaceEntity nâng cao
Để kiểm soát việc kết xuất video và hình ảnh ở mức cao hơn, chẳng hạn như áp dụng các hiệu ứng vật liệu tuỳ chỉnh, bạn có thể làm việc trực tiếp với SurfaceEntity
trong thư viện SceneCore.
Các phần sau đây mô tả một số tính năng nâng cao có trên SurfaceEntity
.
Áp dụng hiệu ứng làm mềm viền
Làm mềm các cạnh của bề mặt để giúp bề mặt hoà vào môi trường bằng cách đặt thuộc tính 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)
Áp dụng mặt nạ alpha
Áp dụng mặt nạ alpha để tạo các bề mặt không có hình chữ nhật hoặc thêm hiệu ứng trong suốt. Trước tiên, hãy tải Texture
từ một tài sản, sau đó chỉ định tài sản đó cho thuộc tính 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 }
Phát video không gian bằng Jetpack Compose cho XR
Nếu bạn muốn tìm hiểu cách phát video bằng Jetpack Compose cho XR, hãy tìm hiểu cách thêm một bề mặt cho nội dung hình ảnh hoặc video.