Jetpack XR SDK รองรับการเล่นวิดีโอ แบบเคียงข้างกันแบบสเตอริโอสโคปบนพื้นผิวเรียบ วิดีโอแบบสเตอริโอสโคปแต่ละเฟรม ประกอบด้วยภาพสำหรับตาซ้ายและตาขวาเพื่อให้ผู้ชมรู้สึกถึง ความลึก หรือที่เรียกว่าสเตอริโอสโคปี
คุณสามารถแสดงวิดีโอ 2 มิติแบบไม่สเตอริโอสโคปิกในแอป Android XR ได้ด้วยAPI สื่อมาตรฐานที่ใช้สำหรับการพัฒนา Android ในอุปกรณ์รูปแบบอื่นๆ
เล่นวิดีโอแบบเคียงข้างกันโดยใช้ Jetpack SceneCore
วิดีโอแบบเคียงข้างกันจะแสดงแต่ละเฟรมสเตอริโอสโคปเป็นรูปภาพ 2 รูป ที่จัดเรียงในแนวนอนติดกัน เฟรมวิดีโอบนและล่าง จัดเรียงในแนวตั้งติดกัน
วิดีโอแบบเคียงข้างกันไม่ใช่ตัวแปลงรหัส แต่เป็นวิธีจัดระเบียบเฟรมสเตอริโอสโคป ซึ่งหมายความว่าสามารถเข้ารหัสในตัวแปลงรหัสที่ Android รองรับ
คุณโหลดวิดีโอแบบเคียงข้างกันได้โดยใช้ Media3 Exoplayer แล้วจึงแสดงผล
โดยใช้ SurfaceEntity
ใหม่ หากต้องการสร้าง SurfaceEntity
ให้เรียกใช้
SurfaceEntity.create
ดังตัวอย่างต่อไปนี้
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 โดยใช้ Jetpack SceneCore
มาตรฐานตัวแปลงรหัส MV-HEVC ได้รับการเพิ่มประสิทธิภาพและออกแบบมาสำหรับวิดีโอสเตอริโอ ซึ่งช่วยให้แอปของคุณเล่นวิดีโอที่สมจริงได้อย่างมีประสิทธิภาพและมีคุณภาพยอดเยี่ยม ไฟล์ MV-HEVC มีสตรีมหลัก ซึ่งมักจะเป็นตาซ้าย และสตรีมสเตอริโอ ที่มีตาอีกข้าง
คุณโหลดวิดีโอแบบซ้อนทับได้โดยใช้ Media3 Exoplayer และ
แสดงผลโดยใช้ SurfaceEntity
ซึ่งคล้ายกับวิดีโอแบบเคียงข้างกัน คุณจะต้องระบุว่าไฟล์ MV-HEVC เป็นไฟล์หลักด้านซ้ายหรือขวาในพารามิเตอร์ stereoMode
เมื่อเรียกใช้ 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()
เล่นวิดีโอเชิงมิติพื้นที่ที่ได้รับการคุ้มครองโดย DRM โดยใช้ Jetpack SceneCore
Jetpack XR SDK รองรับการเล่นสตรีมวิดีโอที่เข้ารหัสโดยใช้เฟรมเวิร์กการจัดการสิทธิ์ดิจิทัล (DRM) ในตัวของ Android DRM ปกป้องเนื้อหาของคุณด้วยการเปิดใช้การจัดจำหน่ายที่ปลอดภัยและป้องกัน การคัดลอกหรือการเล่นที่ไม่ได้รับอนุญาต
กระบวนการนี้เกี่ยวข้องกับแอปพลิเคชันโปรแกรมเล่นสื่อของคุณที่ติดต่อเซิร์ฟเวอร์ใบอนุญาต เพื่อรับคีย์การถอดรหัส ใน Android กระบวนการนี้ได้รับการจัดการอย่างปลอดภัย และ เฟรมวิดีโอที่ถอดรหัสแล้วจะแสดงในบัฟเฟอร์กราฟิกที่ได้รับการป้องกันซึ่งระบบหรือแอปพลิเคชันอื่นๆ ไม่สามารถเข้าถึงได้ จึงป้องกันการจับภาพหน้าจอ
หากต้องการเล่นวิดีโอที่มีการป้องกันด้วย DRM ด้วย Jetpack SceneCore คุณต้องทำดังนี้
- กำหนดค่า
SurfaceEntity
เพื่อขอพื้นผิวที่ได้รับการปกป้อง - กำหนดค่า Media3 Exoplayer ด้วยข้อมูล DRM ที่จำเป็นเพื่อจัดการ การแลกเปลี่ยนคีย์
- ตั้งค่าเอาต์พุตของผู้เล่นเป็นพื้นผิวของ
SurfaceEntity
ตัวอย่างต่อไปนี้แสดงวิธีกำหนดค่า ExoPlayer ให้เล่นสตรีมที่ได้รับการปกป้องด้วย DRM
และแสดงบน 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()
ดูภาพรวมโดยละเอียดเพิ่มเติมเกี่ยวกับเฟรมเวิร์ก DRM ของสื่อใน Android ได้ที่เอกสารประกอบ DRM ของสื่อใน source.android.com
เล่นวิดีโอ 180 องศาและ 360 องศาโดยใช้ Jetpack SceneCore
SurfaceEntity
รองรับการเล่นวิดีโอ 180° บนพื้นผิวครึ่งทรงกลม
และวิดีโอ 360° บนพื้นผิวทรงกลม พารามิเตอร์ radius
หมายถึง
ขนาดรัศมีของพื้นผิวที่เกี่ยวข้องในหน่วยเมตรโดยค่าเริ่มต้น
โค้ดต่อไปนี้แสดงวิธีตั้งค่า SurfaceEntity
สำหรับการเล่นบนครึ่งทรงกลม 180°
และทรงกลม 360° เมื่อใช้รูปร่าง Canvas เหล่านี้ ให้วางตำแหน่ง
พื้นผิวโดยใช้ประโยชน์จากท่าทางศีรษะของผู้ใช้เพื่อมอบประสบการณ์ที่สมจริง
// 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.
การควบคุม SurfaceEntity ขั้นสูง
หากต้องการควบคุมการเรนเดอร์วิดีโอและรูปภาพขั้นสูง เช่น การใช้
เอฟเฟกต์วัสดุที่กำหนดเอง คุณสามารถทำงานร่วมกับ SurfaceEntity
ได้โดยตรงจาก
ไลบรารี SceneCore
ส่วนต่อไปนี้จะอธิบายฟีเจอร์ขั้นสูงบางอย่างที่พร้อมใช้งานใน SurfaceEntity
ใช้การฟุ้งขอบ
ทำให้ขอบของพื้นผิวเรียบเนียนเพื่อช่วยให้กลมกลืนกับสภาพแวดล้อมโดย
ตั้งค่าพร็อพเพอร์ตี้ 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)
ใช้มาสก์อัลฟ่า
ใช้มาสก์อัลฟ่าเพื่อสร้างพื้นผิวที่ไม่ใช่สี่เหลี่ยมผืนผ้าหรือเพิ่มเอฟเฟกต์ความโปร่งใส
ก่อนอื่น ให้โหลด Texture
จากชิ้นงาน แล้วกำหนดให้กับพร็อพเพอร์ตี้
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 }
เล่นวิดีโอเชิงมิติพื้นที่โดยใช้ Jetpack Compose สำหรับ XR
หากสนใจดูวิธีเล่นวิดีโอโดยใช้ Jetpack Compose สำหรับ XR โปรดดูวิธีเพิ่ม Surface สำหรับเนื้อหารูปภาพหรือวิดีโอ