SpatialExternalSurface एक सबस्पेस कंपोज़ेबल है, जो Surface को बनाता और मैनेज करता है. इसमें आपका ऐप्लिकेशन, इमेज या वीडियो जैसा कॉन्टेंट दिखा सकता है. SpatialExternalSurface में स्टीरियोस्कोपिक या मोनोस्कोपिक कॉन्टेंट को चलाया जा सकता है.
इमेज या वीडियो वाले कॉन्टेंट के लिए कोई प्लैटफ़ॉर्म जोड़ना
इस उदाहरण में, Media3 Exoplayer और SpatialExternalSurface का इस्तेमाल करके, साइड-बाय-साइड स्टीरियोस्कोपिक वीडियो लोड करने का तरीका बताया गया है:
@OptIn(ExperimentalComposeApi::class) @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() } } } }
कोड के बारे में अहम बातें
StereoModeकोMono,SideBySideयाTopBottomपर सेट करें. यह इस बात पर निर्भर करता है कि किस तरह का कॉन्टेंट रेंडर किया जा रहा है:Mono: इमेज या वीडियो फ़्रेम में एक ही इमेज होती है, जो दोनों आंखों को दिखती है.SideBySide: इमेज या वीडियो फ़्रेम में, इमेज या वीडियो फ़्रेम का एक जोड़ा होता है. इन्हें अगल-बगल रखा जाता है. इसमें बाईं ओर मौजूद इमेज या फ़्रेम, बाईं आंख से दिखने वाले व्यू को दिखाता है और दाईं ओर मौजूद इमेज या फ़्रेम, दाईं आंख से दिखने वाले व्यू को दिखाता है.TopBottom: इमेज या वीडियो फ़्रेम में, वर्टिकल तौर पर स्टैक की गई इमेज या वीडियो फ़्रेम का एक जोड़ा होता है. इसमें सबसे ऊपर मौजूद इमेज या फ़्रेम, बाईं आंख से दिखने वाले व्यू को दिखाता है. वहीं, सबसे नीचे मौजूद इमेज या फ़्रेम, दाईं आंख से दिखने वाले व्यू को दिखाता है.
SpatialExternalSurfaceसिर्फ़ रेक्टैंगल शेप वाले प्लैटफ़ॉर्म के साथ काम करता है.- यह
Surface, इनपुट इवेंट कैप्चर नहीं करता. StereoModeमें किए गए बदलावों को ऐप्लिकेशन रेंडरिंग या वीडियो डिकोडिंग के साथ सिंक नहीं किया जा सकता.- यह कंपोज़ेबल, अन्य पैनल के सामने रेंडर नहीं हो सकता. इसलिए, अगर लेआउट में अन्य पैनल मौजूद हैं, तो आपको
MovePolicyका इस्तेमाल नहीं करना चाहिए.
डीआरएम से सुरक्षित वीडियो कॉन्टेंट के लिए, कोई प्लैटफ़ॉर्म जोड़ना
SpatialExternalSurface में डीआरएम से सुरक्षित वीडियो स्ट्रीम चलाने की सुविधा भी है. इसे चालू करने के लिए, आपको एक सुरक्षित सरफ़ेस बनाना होगा, जो सुरक्षित ग्राफ़िक बफ़र को रेंडर करता हो. इससे, कॉन्टेंट को स्क्रीन-रिकॉर्ड होने या असुरक्षित सिस्टम कॉम्पोनेंट से ऐक्सेस होने से रोका जाता है.
सुरक्षित प्लैटफ़ॉर्म बनाने के लिए, SpatialExternalSurface कंपोज़ेबल पर SpatialExternalSurfaceProtection पैरामीटर को SpatialExternalSurfaceProtection.Protected पर सेट करें. इसके अलावा, आपको Media3 Exoplayer को सही डीआरएम जानकारी के साथ कॉन्फ़िगर करना होगा, ताकि लाइसेंस सर्वर से लाइसेंस हासिल किया जा सके.
यहां दिए गए उदाहरण में, डीआरएम से सुरक्षित वीडियो स्ट्रीम चलाने के लिए, SpatialExternalSurface और ExoPlayer को कॉन्फ़िगर करने का तरीका बताया गया है:
@OptIn(ExperimentalComposeApi::class) @Composable fun DrmSpatialVideoPlayer() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) .height(676.dp), stereoMode = StereoMode.SideBySide, surfaceProtection = SpatialExternalSurfaceProtection.Protected ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } // 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" // 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() onSurfaceCreated { surface -> // The created surface is secure and can be used by the player. exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } onSurfaceDestroyed { exoPlayer.release() } } } }
कोड के बारे में अहम बातें
- Protected Surface:
SpatialExternalSurfaceपरsurfaceProtection = SpatialExternalSurfaceProtection.Protectedको सेट करना ज़रूरी है, ताकिSurfaceको डीआरएम कॉन्टेंट के लिए सही सुरक्षित बफ़र से बैक अप किया जा सके. - डीआरएम कॉन्फ़िगरेशन: आपको डीआरएम स्कीम (उदाहरण के लिए,
C.WIDEVINE_UUID) और अपने लाइसेंस सर्वर के यूआरआई के साथMediaItemको कॉन्फ़िगर करना होगा. ExoPlayer इस जानकारी का इस्तेमाल, डीआरएम सेशन को मैनेज करने के लिए करता है. - सुरक्षित कॉन्टेंट: सुरक्षित प्लैटफ़ॉर्म पर रेंडर करते समय, वीडियो वाला कॉन्टेंट डिकोड किया जाता है और सुरक्षित पाथ पर दिखाया जाता है. इससे कॉन्टेंट के लाइसेंस की ज़रूरी शर्तें पूरी करने में मदद मिलती है. इससे, स्क्रीन कैप्चर में भी कॉन्टेंट नहीं दिखता.