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

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

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

می‌توانید ویدیوهای دوبعدی غیربرجسته‌نمایی را در برنامه‌های 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، باید در پارامتر stereoMode مشخص کنید که فایل MV-HEVC شما چپ یا راست اصلی است.

// 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 را با اطلاعات «مدیریت حقوق دیجیتال» لازم برای مدیریت تبادل کلید پیکربندی کنید.
  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 برای واقعیت گسترده

اگر می‌خواهید با نحوه پخش ویدیو بااستفاده از Jetpack Compose برای XR آشنا شوید، با نحوه افزودن سطح برای محتوای تصویری یا ویدیویی آشنا شوید.