الأسطح الخارجية المكانية

أجهزة XR المشمولة
تساعدك هذه الإرشادات في إنشاء تجارب لهذه الأنواع من أجهزة XR.
سماعات الرأس بنظام الواقع الممتد
نظارات سلكية بنظام الواقع الممتد

‫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 أيضًا تشغيل فيديوهات البث المباشر المحمية بموجب "إدارة الحقوق الرقمية". لتفعيل هذه الميزة، يجب إنشاء مساحة عرض آمنة يتم عرضها في مخازن مؤقتة للرسومات المحمية. يمنع ذلك تسجيل الشاشة أو وصول مكوّنات النظام غير الآمنة إلى المحتوى.

لإنشاء سطح آمن، اضبط المَعلمة SpatialExternalSurfaceProtection على SpatialExternalSurfaceProtection.Protected في الدالة المركّبة SpatialExternalSurface. بالإضافة إلى ذلك، يجب ضبط 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: Setting surfaceProtection = SpatialExternalSurfaceProtection.Protected on SpatialExternalSurface is essential so that the underlying Surface is backed by secure buffers suitable for DRM content.
  • إعدادات إدارة الحقوق الرقمية: يجب ضبط MediaItem باستخدام نظام إدارة الحقوق الرقمية (على سبيل المثال، C.WIDEVINE_UUID) ومعرّف الموارد المنتظم (URI) لخادم الترخيص. يستخدم ExoPlayer هذه المعلومات لإدارة جلسة إدارة الحقوق الرقمية.
  • المحتوى الآمن: عند العرض على سطح محمي، يتم فك ترميز محتوى الفيديو وعرضه على مسار آمن، ما يساعد في تلبية متطلبات ترخيص استخدام المحتوى. يؤدي ذلك أيضًا إلى منع ظهور المحتوى في لقطات الشاشة.