הוספת סרטון מרחבי לאפליקציה

‫Jetpack XR SDK תומך בהפעלה של סרטון סטריאוסקופי זה לצד זה על משטחים שטוחים. בסרטון תלת-ממדי, כל פריים מורכב מתמונה לעין שמאל ותמונה לעין ימין, כדי לתת לצופים תחושה של עומק – תחושה שנקראת גם סטריאופסיס.

אפשר להציג סרטוני דו-ממד לא סטריאוסקופיים באפליקציות 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, צריך לציין בפרמטר stereoMode אם קובץ ה-MV-HEVC הוא ראשי שמאלי או ראשי ימני.

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

הפעלת סרטון מרחבי שמוגן על ידי DRM באמצעות Jetpack SceneCore

‫Jetpack XR SDK תומך בהפעלה של סטרימינג מוצפן של סרטונים באמצעות מסגרת ניהול הזכויות הדיגיטלי (DRM) המובנית ב-Android. ‫DRM מגן על התוכן שלכם על ידי הפצה מאובטחת ומניעת העתקה או הפעלה לא מורשות.

התהליך כולל פנייה של אפליקציית נגן המדיה לשרת רישיונות כדי לקבל מפתחות פענוח. ב-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)),
    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 זמינה במאמרי העזרה בנושא 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 for XR

אם אתם רוצים לדעת איך להפעיל סרטון באמצעות Jetpack Compose ל-XR, אתם יכולים לקרוא על הוספת משטח לתוכן של תמונות או סרטונים.