کیت توسعه نرمافزاری Jetpack XR از پخش ویدیوی استریوسکوپیک پهلو به پهلو روی سطوح صاف پشتیبانی میکند. در ویدیوی استریوسکوپیک، هر فریم از یک تصویر چشم چپ و یک تصویر چشم راست تشکیل شده است تا به بینندگان حس عمق بدهد - که به عنوان استریوپسیس نیز شناخته میشود.
شما میتوانید ویدیوی دوبعدی غیر برجستهنما را در برنامههای اندروید XR با APIهای رسانهای استاندارد که برای توسعه اندروید روی سایر فرمفکتورها استفاده میشوند، رندر کنید.
پخش ویدیوهای کنار هم با استفاده از Jetpack SceneCore
در ویدئوی پهلو به پهلو، هر فریم استریوسکوپی به صورت دو تصویر که به صورت افقی در کنار یکدیگر قرار گرفتهاند، نمایش داده میشود. فریمهای ویدئویی بالا و پایین به صورت عمودی در کنار یکدیگر قرار گرفتهاند.
ویدیوی کنار هم یک کدک نیست، بلکه روشی برای سازماندهی فریمهای استریوسکوپی است، به این معنی که میتواند در هر یک از کدکهای پشتیبانی شده توسط اندروید کدگذاری شود.
شما میتوانید ویدیوهای کنار هم را با استفاده از Media3 Exoplayer بارگذاری کنید و سپس آن را با استفاده از SurfaceEntity جدید رندر کنید. برای ایجاد یک SurfaceEntity ، همانطور که در مثال زیر نشان داده شده است، SurfaceEntity.create را فراخوانی کنید.
val stereoSurfaceEntity = SurfaceEntity.create( session = xrSession, stereoMode = SurfaceEntity.StereoMode.SIDE_BY_SIDE, pose = Pose(Vector3(0.0f, 0.0f, -1.5f)), shape = SurfaceEntity.Shape.Quad(FloatSize2d(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 آن را رندر کنید. هنگام فراخوانی SurfaceEntity.create ، باید مشخص کنید که فایل MV-HEVC شما در پارامتر stereoMode در سمت چپ یا راست اصلی قرار دارد.
// Create the SurfaceEntity with the StereoMode corresponding to the MV-HEVC content val stereoSurfaceEntity = SurfaceEntity.create( session = xrSession, stereoMode = SurfaceEntity.StereoMode.MULTIVIEW_LEFT_PRIMARY, pose = Pose(Vector3(0.0f, 0.0f, -1.5f)), shape = SurfaceEntity.Shape.Quad(FloatSize2d(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 از پخش جریانهای ویدیویی رمزگذاریشده با استفاده از چارچوب مدیریت حقوق دیجیتال (DRM) داخلی اندروید پشتیبانی میکند. DRM با فعال کردن توزیع ایمن و جلوگیری از کپی یا پخش غیرمجاز، از محتوای شما محافظت میکند.
این فرآیند شامل تماس برنامه پخشکننده رسانه شما با یک سرور مجوز برای دریافت کلیدهای رمزگشایی است. در اندروید، این فرآیند به صورت ایمن مدیریت میشود و فریمهای ویدیویی رمزگشایی شده در یک بافر گرافیکی محافظتشده رندر میشوند که توسط سیستم یا سایر برنامهها قابل دسترسی نیست و از ضبط صفحه جلوگیری میکند.
برای پخش ویدیوهای محافظتشده با DRM با Jetpack SceneCore، باید:
-
SurfaceEntityبرای درخواست یک سطح محافظتشده پیکربندی کنید. - Media3 Exoplayer را با اطلاعات DRM لازم برای مدیریت تبادل کلید پیکربندی کنید.
- خروجی پخشکننده را روی سطح
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)), shape = SurfaceEntity.Shape.Quad(FloatSize2d(1.0f, 1.0f)), surfaceProtection = SurfaceEntity.SurfaceProtection.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 رسانهای اندروید، به مستندات Media DRM در source.android.com مراجعه کنید.
پخش ویدیوهای ۱۸۰ درجه و ۳۶۰ درجه با استفاده از Jetpack SceneCore
SurfaceEntity از پخش ویدیوهای ۱۸۰ درجه روی سطوح نیمکره و ویدیوهای ۳۶۰ درجه روی سطوح کروی پشتیبانی میکند. پارامتر radius به طور پیشفرض به اندازه شعاعی سطوح مربوطه بر حسب متر اشاره دارد.
کد زیر نحوه تنظیم SurfaceEntity برای پخش در نیمکره ۱۸۰ درجه و کره ۳۶۰ درجه را نشان میدهد. هنگام استفاده از این اشکال بوم، سطح را با استفاده از موقعیت سر کاربر تنظیم کنید تا یک تجربه فراگیر ارائه شود.
// Set up the surface for playing a 180° video on a hemisphere. val hemisphereStereoSurfaceEntity = SurfaceEntity.create( session = xrSession, stereoMode = SurfaceEntity.StereoMode.SIDE_BY_SIDE, pose = xrSession.scene.spatialUser.head?.transformPoseTo( Pose.Identity, xrSession.scene.activitySpace )!!, shape = SurfaceEntity.Shape.Hemisphere(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( session = xrSession, stereoMode = SurfaceEntity.StereoMode.TOP_BOTTOM, pose = xrSession.scene.spatialUser.head?.transformPoseTo( Pose.Identity, xrSession.scene.activitySpace )!!, shape = SurfaceEntity.Shape.Sphere(1.0f), ) // ... and use the surface for playing the media.
کنترل پیشرفته SurfaceEntity
برای کنترل پیشرفتهتر بر رندر ویدیو و تصویر، مانند اعمال جلوههای متریال سفارشی، میتوانید مستقیماً با SurfaceEntity از کتابخانه SceneCore کار کنید.
بخشهای زیر برخی از ویژگیهای پیشرفته موجود در SurfaceEntity را شرح میدهند.
اعمال پر کردن لبه
با تنظیم ویژگی edgeFeatheringParams لبههای سطح را نرم کنید تا به ترکیب آن با محیط کمک شود.
// 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.edgeFeatheringParams = SurfaceEntity.EdgeFeatheringParams.RectangleFeather(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"), ) // 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 علاقهمند هستید، نحوه اضافه کردن یک سطح برای محتوای تصویر یا ویدیو را بیاموزید.