افزودن ویدیو فراگیر به برنامه

دستگاه‌های XR قابل‌اعمال
این راهنمایی به شما کمک می‌کند برای این نوع دستگاه‌های واقعیت گسترده تجربه بسازید.
هدست‌های واقعیت گسترده
عینک واقعیت گسترده سیمی

«کیت توسعه نرم‌افزار Jetpack XR» از بازپخش ویدیوهای پهلو به پهلو استریوسکوپی روی سطوح صاف پشتیبانی می‌کند. در ویدیو سه‌بعدی، هر قاب از تصویر چشم چپ و چشم راست تشکیل شده است تا به بینندگان حس عمق بدهد—که به آن استریوپسیس نیز می‌گویند.

می‌توانید ویدیو دوبعدی غیرفضایی را در برنامه‌های Android XR با میاناهای برنامه‌سازی کاربردی رسانه استاندارد که برای توسعه Android در عوامل شکل دیگر استفاده می‌شود پردازش کنید.

پخش ویدیو پهلوبه‌پهلو بااستفاده از Jetpack SceneCore

در ویدیو کناربه‌کنار، هر قاب استریوسکوپی به‌صورت دو تصویر ارائه می‌شود که به‌صورت افقی در کنار یکدیگر قرار می‌گیرند. قاب‌های ویدیویی بالا و پایین به‌صورت عمودی در کنار یکدیگر چیده می‌شوند.

ویدیو کنار هم یک کدک نیست بلکه روشی برای سازماندهی قاب‌های استریوسکوپی است، به این معنی که می‌تواند در هریک از کدک‌های پشتیبانی‌شده توسط Android کدبندی شود.

می‌توانید ویدیو کنار به کنار را بااستفاده از 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) داخلی Android پشتیبانی می‌کند. «مدیریت حقوق دیجیتال» با فعال کردن توزیع ایمن و جلوگیری از کپی یا بازپخش غیرمجاز، از محتوای شما محافظت می‌کند.

این فرایند شامل تماس برنامه پخش‌کننده رسانه شما با سرور پروانه برای دریافت کلیدهای رمزگشایی است. در Android، این فرایند به‌صورت ایمن مدیریت می‌شود و قاب‌های ویدیو رمزگشایی‌شده در بافر گرافیکی محافظت‌شده‌ای پردازش می‌شوند که سیستم یا برنامه‌های دیگر نمی‌توانند به آن دسترسی داشته باشند و از ضبط صفحه‌نمایش جلوگیری می‌شود.

برای پخش ویدیو محافظت‌شده با DRM با Jetpack SceneCore، باید:

  1. SurfaceEntity را پیکربندی کنید تا سطح محافظت‌شده‌ای درخواست کند.
  2. Media3 Exoplayer را با اطلاعات DRM لازم برای مدیریت تبادل کلید پیکربندی کنید.
  3. برونداد پخش‌کننده را روی سطح 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 رسانه Android، به مستندات DRM رسانه در source.android.com مراجعه کنید.

پخش ویدیو ۱۸۰ و ۳۶۰ درجه بااستفاده از Jetpack SceneCore

SurfaceEntity از بازپخش ویدیوهای ۱۸۰ درجه در سطوح نیم‌کره‌ای و ویدیوهای ۳۶۰ درجه در سطوح کروی پشتیبانی می‌کند. پارامتر radius به‌طور پیش‌فرض به اندازه شعاعی سطوح مربوطه برحسب متر اشاره دارد.

کد زیر نحوه راه‌اندازی SurfaceEntity برای بازپخش در نیم‌کره ۱۸۰ درجه و کره ۳۶۰ درجه را نشان می‌دهد. هنگام استفاده از این شکل‌های بوم، سطح را با بهره‌گیری از وضعیت سر کاربر قرار دهید تا تجربه فراگیری ارائه دهید.

val devicePose = ArDevice.getInstance(xrSession).state.value.devicePose
val activitySpacePose = xrSession.scene.perceptionSpace.transformPoseTo(devicePose, xrSession.scene.activitySpace)

// 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 = activitySpacePose,
        shape = SurfaceEntity.Shape.Hemisphere(1.0f),
    )
// ... and use the surface for playing the media.

val devicePose = ArDevice.getInstance(xrSession).state.value.devicePose
val activitySpacePose = xrSession.scene.perceptionSpace.transformPoseTo(devicePose, xrSession.scene.activitySpace)
// Set up the surface for playing a 360° video on a sphere.
val sphereStereoSurfaceEntity =
    SurfaceEntity.create(
        session = xrSession,
        stereoMode = SurfaceEntity.StereoMode.TOP_BOTTOM,
        pose = activitySpacePose,
        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 آشنا شوید، با نحوه افزودن سطح برای محتوای تصویری یا ویدیویی آشنا شوید.