PremiumMediaSample showcases advanced media streaming and spatial integration techniques for Meta Quest headsets. It demonstrates DRM-protected video playback, custom shaders that cast screen light onto room surfaces, multi-process Jetpack Compose panels, and MRUK-based wall snapping.ExoPlayer with direct-to-surface renderingMRUK surfacesMRUKPremiumMediaSample project in Android Studio, connect your Quest device via USB or Wi-Fi, and run the app. When launched, the app requests Scene permission to load your room layout, then displays a home screen where you can select media to play.| File / Scene | What it demonstrates | Key concepts |
|---|---|---|
Main entry point; registers all systems, components, and features | Activity lifecycle, feature registration, IPC message handling | |
MRUK initialization and scene loading | MRUKFeature setup, scene permission handling, loadSceneFromDevice() | |
Orchestrates ExoPlayer, panels, cinema states | Central state management, entity lifecycle coordination | |
Creates video panels with spatial audio integration | Readable vs direct-to-surface rendering modes, VideoSurfacePanelRegistration | |
ExoPlayer factory with DRM support | OculusMediaCodecVideoRenderer, Widevine DRM session manager, DASH sources | |
MRUK-based wall snapping | Gaze ray-casting, grab repositioning, plane intersection | |
Extracts panel texture and distributes to shaders | SceneTexture detection, shader uniform distribution | |
Creates lighting meshes aligned to MRUK surfaces | MRUK plane quad generation, custom material assignment | |
heroLighting.glsl | Core lighting shader math | Rect-space transforms, light falloff, floor reflections, SDF shadows |
Content selection UI (separate process) | Multi-process Compose, IPC messaging, ActivityPanelRegistration | |
Media controls UI (separate process) | Cross-process state updates, custom Compose components |
OculusMediaCodecVideoRenderer to enable Widevine DRM playback. When a DRM license URL is provided, or when using non-rectilinear video shapes like 180° equirect, the sample forces direct-to-surface rendering:val panelRenderingStyle =
if (drmEnabled || mediaSource.videoShape != MediaSource.VideoShape.Rectilinear)
PanelRenderingStyle.DIRECT_TO_SURFACE
else PanelRenderingStyle.READABLE
ExoPlayerExt.kt for the complete DRM session manager configuration. For API reference, see DRM content.val emissiveFactor = Vector4(screenPos.x, screenPos.y, screenPos.z, width) val albedoFactor = Vector4(rotEuler.x, rotEuler.y, rotEuler.z, height)
HeroLightingSystem.kt and heroLighting.glsl for implementation details. For custom shader documentation, see Custom shaders.val headToAnchorableDirection = (anchorablePose.t - headPose.t).normalize() val hitInfo = doesRayIntersectPlane(headPose.t, headToAnchorableDirection, plane)
AnchorSnappingSystem.kt for the complete snapping logic. For MRUK API reference, see MRUK.<activity android:name=".panels.homePanel.HomePanelActivity"
android:process=":home_panel" />
IPCService.kt for the message routing implementation. For panel documentation, see Direct-to-surface rendering.HomePanelViewModel.kt defines the DASH URLs — replace these with your own streaming sources or add new entries with different stereo modes.heroLighting.glsl exposes parameters for light falloff distance and floor reflection intensity — adjust these to match different room sizes and content types.CinemaStateHandler.kt state machine supports adding new cinema states for different viewing modes, such as floor seating or dome projection.