ویدیوی فضایی را به برنامه خود اضافه کنید

Jetpack XR SDK از پخش ویدئوهای استریوسکوپی کنار هم بر روی سطوح صاف پشتیبانی می کند. در ویدیوهای استریوسکوپی، هر فریم از یک تصویر چشم چپ و یک تصویر چشم راست تشکیل شده است تا به بینندگان احساس عمق بدهد - همچنین به عنوان stereopsis شناخته می شود.

می‌توانید ویدیوهای دوبعدی غیر استریوسکوپی را در برنامه‌های Android XR با APIهای رسانه استانداردی که برای توسعه Android استفاده می‌شوند، بر روی سایر فاکتورها ارائه دهید.

با استفاده از Jetpack SceneCore ویدیوی کنار هم را پخش کنید

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

ویدئوی ساید بای ساید یک کدک نیست، بلکه روشی برای سازماندهی فریم های استریوسکوپی است، به این معنی که می توان آن را در هر کدک پشتیبانی شده توسط Android رمزگذاری کرد.

می‌توانید ویدیو را با استفاده از Media3 Exoplayer بارگیری کنید و سپس آن را با استفاده از SurfaceEntity جدید رندر کنید. برای ایجاد یک SurfaceEntity ، همانطور که در مثال زیر نشان داده شده است، SurfaceEntity.create را فراخوانی کنید.

val stereoSurfaceEntity = SurfaceEntity.create(
    xrSession,
    SurfaceEntity.StereoMode.SIDE_BY_SIDE,
    Pose(Vector3(0.0f, 0.0f, -1.5f)),
    SurfaceEntity.CanvasShape.Quad(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(
    xrSession,
    SurfaceEntity.StereoMode.MULTIVIEW_LEFT_PRIMARY,
    Pose(Vector3(0.0f, 0.0f, -1.5f)),
    SurfaceEntity.CanvasShape.Quad(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()

با استفاده از Jetpack SceneCore ویدیوی فضایی محافظت شده با DRM را پخش کنید

Jetpack XR SDK از پخش جریان های ویدیوی رمزگذاری شده با استفاده از چارچوب داخلی مدیریت حقوق دیجیتال (DRM) اندروید پشتیبانی می کند. DRM با فعال کردن توزیع ایمن و جلوگیری از کپی یا پخش غیرمجاز از محتوای شما محافظت می کند.

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

برای پخش ویدیوی محافظت شده با 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)),
    canvasShape = SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f),
    contentSecurityLevel = SurfaceEntity.ContentSecurityLevel.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، به مستندات Media DRM در source.android.com مراجعه کنید.

پخش ویدیوی 180 درجه و 360 درجه با استفاده از Jetpack SceneCore

SurfaceEntity از پخش ویدیوهای 180 درجه روی سطوح نیمکره و ویدیوهای 360 درجه روی سطوح کروی پشتیبانی می کند. پارامتر radius به طور پیش فرض به اندازه شعاعی سطوح مربوطه بر حسب متر اشاره دارد.

کد زیر نحوه تنظیم SurfaceEntity را برای پخش در نیمکره 180 درجه و کره 360 درجه نشان می دهد. هنگام استفاده از این اشکال بوم، سطح را با استفاده از حالت سر کاربر برای ارائه یک تجربه همه جانبه قرار دهید.

// Set up the surface for playing a 180° video on a hemisphere.
val hemisphereStereoSurfaceEntity =
    SurfaceEntity.create(
        xrSession,
        SurfaceEntity.StereoMode.SIDE_BY_SIDE,
        xrSession.scene.spatialUser.head?.transformPoseTo(
            Pose.Identity,
            xrSession.scene.activitySpace
        )!!,
        SurfaceEntity.CanvasShape.Vr180Hemisphere(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(
        xrSession,
        SurfaceEntity.StereoMode.TOP_BOTTOM,
        xrSession.scene.spatialUser.head?.transformPoseTo(
            Pose.Identity,
            xrSession.scene.activitySpace
        )!!,
        SurfaceEntity.CanvasShape.Vr360Sphere(1.0f),
    )
// ... and use the surface for playing the media.

کنترل پیشرفته SurfaceEntity

برای کنترل پیشرفته‌تر بر رندر ویدیو و تصویر، مانند اعمال جلوه‌های متریال سفارشی، می‌توانید مستقیماً با SurfaceEntity از کتابخانه SceneCore کار کنید.

بخش‌های زیر برخی از ویژگی‌های پیشرفته موجود در SurfaceEntity را توضیح می‌دهند.

پر کردن لبه را اعمال کنید

با تنظیم ویژگی edgeFeather ، لبه های سطح را نرم کنید تا به آن کمک کنید با محیط ترکیب شود.

// 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.edgeFeather =
    SurfaceEntity.EdgeFeatheringParams.SmoothFeather(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"),
            TextureSampler.create()
        )

    // 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 علاقه دارید، یاد بگیرید که چگونه یک سطح برای محتوای تصویر یا ویدیو اضافه کنید .