เพิ่มวิดีโอเสียงรอบทิศทางลงในแอป

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 คุณต้องทำดังนี้

  1. กำหนดค่า SurfaceEntity เพื่อขอพื้นผิวที่ได้รับการปกป้อง
  2. กำหนดค่า Media3 Exoplayer ด้วยข้อมูล DRM ที่จำเป็นเพื่อจัดการ การแลกเปลี่ยนคีย์
  3. ตั้งค่าเอาต์พุตของผู้เล่นเป็นพื้นผิวของ 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 สำหรับเนื้อหารูปภาพหรือวิดีโอ