अपने ऐप्लिकेशन में स्पेस ऑडियो वाला वीडियो जोड़ना

Jetpack XR SDK, फ़्लैट सर्फ़ेस पर स्टीरियोस्कोपिक साइड-बाय-साइड वीडियो चलाने की सुविधा देता है. स्टीरियोस्कोपिक वीडियो में, हर फ़्रेम में बाईं और दाईं आंख के लिए इमेज होती है. इससे दर्शकों को गहराई का एहसास होता है. इसे स्टीरियोप्सिस भी कहा जाता है.

Android XR ऐप्लिकेशन पर, नॉन-स्टीरियोस्कोपिक 2D वीडियो रेंडर किया जा सकता है. इसके लिए, स्टैंडर्ड मीडिया एपीआई का इस्तेमाल किया जाता है. इनका इस्तेमाल, Android के अन्य डिवाइसों के लिए ऐप्लिकेशन डेवलप करने के लिए भी किया जाता है.

Jetpack SceneCore का इस्तेमाल करके, अगल-बगल वीडियो चलाना

साइड-बाय-साइड वीडियो में, हर स्टीरियोस्कोपिक फ़्रेम को दो इमेज के तौर पर दिखाया जाता है. ये इमेज, एक-दूसरे के बगल में हॉरिज़ॉन्टल तरीके से व्यवस्थित होती हैं. वीडियो के टॉप और बॉटम फ़्रेम, एक-दूसरे के ऊपर-नीचे वर्टिकल तरीके से व्यवस्थित किए जाते हैं.

साइड-बाय-साइड वीडियो, कोडेक नहीं है. यह स्टीरियोस्कोपिक फ़्रेम को व्यवस्थित करने का एक तरीका है. इसका मतलब है कि इसे 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()

Jetpack SceneCore का इस्तेमाल करके MV-HEVC वीडियो चलाना

MV-HEVC कोडेक स्टैंडर्ड को स्टीरियोस्कोपिक वीडियो के लिए ऑप्टिमाइज़ और डिज़ाइन किया गया है. इससे आपका ऐप्लिकेशन, इमर्सिव वीडियो को अच्छी क्वालिटी में आसानी से चला सकता है. MV-HEVC फ़ाइलों में एक प्राइमरी स्ट्रीम होती है. आम तौर पर, यह बाईं आंख के लिए होती है. साथ ही, इसमें दूसरी आंख के लिए एक स्टीरियो स्ट्रीम होती है.

साइड-बाय-साइड वीडियो की तरह, इसे Media3 Exoplayer का इस्तेमाल करके लोड किया जा सकता है. साथ ही, इसे SurfaceEntity का इस्तेमाल करके रेंडर किया जा सकता है. SurfaceEntity.create को कॉल करते समय, आपको stereoMode पैरामीटर में यह बताना होगा कि आपकी MV-HEVC फ़ाइल में बाईं ओर या दाईं ओर मौजूद इमेज प्राइमरी है.

// 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()

Jetpack SceneCore का इस्तेमाल करके, DRM से सुरक्षित स्पेशल वीडियो चलाना

Jetpack XR SDK, Android के बिल्ट-इन डिजिटल राइट मैनेजमेंट (डीआरएम) फ़्रेमवर्क का इस्तेमाल करके, एन्क्रिप्ट (सुरक्षित) की गई वीडियो स्ट्रीम चलाने की सुविधा देता है. डीआरएम, आपके कॉन्टेंट को सुरक्षित तरीके से डिस्ट्रिब्यूट करने की सुविधा देता है. साथ ही, बिना अनुमति के कॉन्टेंट को कॉपी करने या चलाने से रोकता है.

इस प्रोसेस में, आपका मीडिया प्लेयर ऐप्लिकेशन लाइसेंस सर्वर से संपर्क करता है, ताकि डिक्रिप्शन कुंजियां हासिल की जा सकें. Android पर, इस प्रोसेस को सुरक्षित तरीके से मैनेज किया जाता है. साथ ही, डिक्रिप्ट किए गए वीडियो फ़्रेम को सुरक्षित ग्राफ़िक्स बफ़र में रेंडर किया जाता है. इसे सिस्टम या अन्य ऐप्लिकेशन से ऐक्सेस नहीं किया जा सकता. इससे स्क्रीन कैप्चर करने से रोका जा सकता है.

डीआरएम से सुरक्षित वीडियो को Jetpack SceneCore की मदद से चलाने के लिए, आपको यह करना होगा:

  1. सुरक्षित किए गए किसी सर्फ़ेस का अनुरोध करने के लिए, SurfaceEntity को कॉन्फ़िगर करें.
  2. Media3 Exoplayer को ज़रूरी DRM जानकारी के साथ कॉन्फ़िगर करें, ताकि कुंजी के आदान-प्रदान को मैनेज किया जा सके.
  3. वीडियो प्लेयर का आउटपुट, SurfaceEntity की स्क्रीन पर सेट करें.

यहां दिए गए उदाहरण में, DRM से सुरक्षित स्ट्रीम चलाने और उसे SurfaceEntity पर रेंडर करने के लिए, ExoPlayer को कॉन्फ़िगर करने का तरीका बताया गया है:

// 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()

Android के मीडिया DRM फ़्रेमवर्क के बारे में ज़्यादा जानकारी के लिए, source.android.com पर मीडिया DRM से जुड़ा दस्तावेज़ देखें.

Jetpack SceneCore का इस्तेमाल करके, 180 डिग्री और 360 डिग्री वाला वीडियो चलाना

SurfaceEntity में, हेमिस्फ़ेरिकल (आधे गोले) वाली सतहों पर 180° वीडियो और स्फ़ेरिकल (गोले) वाली सतहों पर 360° वीडियो चलाने की सुविधा मिलती है. radius पैरामीटर, डिफ़ॉल्ट रूप से मीटर में संबंधित सतहों के रेडियल साइज़ को दिखाता है.

यहां दिए गए कोड में, 180° हेमिस्फ़ियर और 360° स्फ़ियर पर चलाने के लिए, SurfaceEntity को सेट अप करने का तरीका दिखाया गया है. इन कैनवस शेप का इस्तेमाल करते समय, उपयोगकर्ता के सिर की पोज़िशन के हिसाब से सर्फ़ेस को सेट करें, ताकि उसे शानदार अनुभव मिल सके.

// 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 for XR का इस्तेमाल करके स्पेशल वीडियो चलाना

अगर आपको XR के लिए Jetpack Compose का इस्तेमाल करके वीडियो चलाने का तरीका जानना है, तो इमेज या वीडियो कॉन्टेंट के लिए कोई सर्फ़ेस जोड़ने का तरीका जानें.