إضافة فيديو مكاني إلى تطبيقك

تتيح حزمة تطوير البرامج Jetpack XR تشغيل فيديوهات جنبًا إلى جنب مجسمة على أسطح مستوية. في الفيديو المجسّم، يتألف كل إطار من صورة للعين اليسرى وصورة للعين اليمنى لمنح المشاهدين إحساسًا بالعمق، ويُعرف ذلك أيضًا باسم الرؤية المجسّمة.

يمكنك عرض فيديوهات ثنائية الأبعاد غير مجسّمة في تطبيقات Android XR باستخدام واجهات برمجة التطبيقات العادية للوسائط المستخدَمة في تطوير تطبيقات 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. عليك تحديد ما إذا كان ملف MV-HEVC يحتوي على صورة أساسية يمنى أو يسرى في المَعلمة stereoMode عند طلب SurfaceEntity.create.

// 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()

تشغيل فيديوهات بنطاق 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 للواقع الممتد

إذا كنت مهتمًا بمعرفة كيفية تشغيل الفيديو باستخدام Jetpack Compose للواقع الممتد، تعرَّف على كيفية إضافة مساحة لعرض محتوى الصور أو الفيديو.