Jetpack XR SDK는 평평한 표면에 대한 입체 비디오 나란히 재생을 지원합니다. 입체 동영상의 경우 각 프레임은 시청자에게 깊이감을 주기 위해 왼쪽 눈 이미지와 오른쪽 눈 이미지로 구성됩니다.
다른 폼 팩터의 Android 개발에 사용되는 표준 미디어 API를 사용하여 Android XR 앱에서 비입체 2D 동영상을 렌더링할 수 있습니다.
Jetpack XR SDK를 사용하여 동영상 나란히 재생
나란히 표시된 동영상에서는 각 입체 프레임이 서로 나란히 가로로 배열된 두 이미지로 표시됩니다. 상단 및 하단 동영상 프레임이 서로 나란히 세로로 정렬됩니다.
나란히 표시 동영상은 코덱이 아니라 입체 프레임을 구성하는 방법입니다. 즉, Android에서 지원하는 모든 코덱으로 인코딩할 수 있습니다.
Jetpack SceneCore
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()
XR용 Jetpack Compose
Alpha04 이상
버전 1.0.0-alpha04
부터 XR용 Jetpack Compose는 나란히 동영상을 로드하고 렌더링하는 또 다른 방법을 제공합니다. 앱이 이미지나 동영상과 같은 콘텐츠를 그릴 수 있는 Surface
를 만들고 관리하는 하위 공간 컴포저블인 SpatialExternalSurface
를 사용하세요. SpatialExternalSurface
에 관한 자세한 내용은 XR용 Compose로 UI 개발 가이드를 참고하세요.
이 예에서는 Media3 Exoplayer 및 SpatialExternalSurface
를 사용하여 나란히 표시되는 동영상을 로드하는 방법을 보여줍니다.
@Composable fun SpatialExternalSurfaceContent() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) // Default width is 400.dp if no width modifier is specified .height(676.dp), // Default height is 400.dp if no height modifier is specified // Use StereoMode.Mono, StereoMode.SideBySide, or StereoMode.TopBottom, depending // upon which type of content you are rendering: monoscopic content, side-by-side stereo // content, or top-bottom stereo content stereoMode = StereoMode.SideBySide, ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } val videoUri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) // Represents a side-by-side stereo video, where each frame contains a pair of // video frames arranged side-by-side. The frame on the left represents the left // eye view, and the frame on the right represents the right eye view. .path("sbs_video.mp4") .build() val mediaItem = MediaItem.fromUri(videoUri) // onSurfaceCreated is invoked only one time, when the Surface is created onSurfaceCreated { surface -> exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } // onSurfaceDestroyed is invoked when the SpatialExternalSurface composable and its // associated Surface are destroyed onSurfaceDestroyed { exoPlayer.release() } } } }
Jetpack XR SDK를 사용하여 180도 및 360도 동영상 재생
SurfaceEntity
는 반구형 표면에서 180도 동영상을 재생하고 구형 표면에서 360도 동영상을 재생합니다. 동영상이 입체인 경우 파일은 나란히 표시되는 형식이어야 합니다.
다음 코드는 180도 반구와 360도 구체에서 재생할 수 있도록 SurfaceEntity
를 설정하는 방법을 보여줍니다. 이러한 캔버스 도형을 사용할 때는 사용자의 머리 자세를 활용하여 노출 영역을 배치하여 몰입도 높은 환경을 제공합니다.
// 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.