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 composable تنظیم کنید. علاوهبراین، باید
Media3 Exoplayer را با اطلاعات مناسب «مدیریت حقوق دیجیتال» پیکربندی کنید تا بتواند
دریافت پروانه را از سرور پروانه مدیریت کند.
مثال زیر نحوه پیکربندی SpatialExternalSurface و
ExoPlayer را برای پخش جاریسازی ویدیویی محافظتشده با DRM نشان میدهد:
@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.ProtectedonSpatialExternalSurfaceis essential so that the underlyingSurfaceis backed by secure buffers suitable for DRM content. - پیکربندی DRM: باید
MediaItemرا با طرح DRM (برای مثال،C.WIDEVINE_UUID) و URI سرور پروانه خود پیکربندی کنید. ExoPlayer از این اطلاعات برای مدیریت جلسه DRM استفاده میکند. - محتوای امن: هنگام ارائه به یک سطح محافظتشده، محتوای ویدیو در یک مسیر امن رمزگشایی و نمایش داده میشود که به برآورده کردن الزامات صدور پروانه محتوا کمک میکند. این کار همچنین از نمایش محتوا در ضبط صفحهنمایش جلوگیری میکند.