diff --git a/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt b/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt index d61ac2ad4df..3022adf4d1d 100644 --- a/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt +++ b/demos/compose/src/main/java/androidx/media3/demo/compose/MainActivity.kt @@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -44,6 +45,7 @@ import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.LifecycleStartEffect import androidx.media3.common.MediaItem import androidx.media3.common.Player +import androidx.media3.common.listen import androidx.media3.demo.compose.buttons.ExtraControls import androidx.media3.demo.compose.buttons.MinimalControls import androidx.media3.demo.compose.data.videos @@ -102,7 +104,7 @@ fun ComposeDemoApp(modifier: Modifier = Modifier) { private fun initializePlayer(context: Context): Player = ExoPlayer.Builder(context).build().apply { - setMediaItems(videos.map(MediaItem::fromUri)) + setMediaItems(videos.keys.map(MediaItem::fromUri)) prepare() } @@ -110,11 +112,20 @@ private fun initializePlayer(context: Context): Player = private fun MediaPlayerScreen(player: Player, modifier: Modifier = Modifier) { var showControls by remember { mutableStateOf(true) } var currentContentScaleIndex by remember { mutableIntStateOf(0) } + var surfaceType by remember { mutableIntStateOf(SURFACE_TYPE_SURFACE_VIEW) } val contentScale = CONTENT_SCALES[currentContentScaleIndex].second val presentationState = rememberPresentationState(player) val scaledModifier = Modifier.resizeWithContentScale(contentScale, presentationState.videoSizeDp) + LaunchedEffect(player) { + player.listen { + currentMediaItem?.localConfiguration?.let { + surfaceType = videos.getValue(it.uri.toString()) + } + } + } + // Only use MediaPlayerScreen's modifier once for the top level Composable Box(modifier) { // Always leave PlayerSurface to be part of the Compose tree because it will be initialised in @@ -122,7 +133,7 @@ private fun MediaPlayerScreen(player: Player, modifier: Modifier = Modifier) { // because the Player will not emit the relevant event, e.g. the first frame being ready. PlayerSurface( player = player, - surfaceType = SURFACE_TYPE_SURFACE_VIEW, + surfaceType = surfaceType, modifier = scaledModifier.noRippleClickable { showControls = !showControls }, ) diff --git a/demos/compose/src/main/java/androidx/media3/demo/compose/data/videos.kt b/demos/compose/src/main/java/androidx/media3/demo/compose/data/videos.kt index ed42d15d5a6..58479115e12 100644 --- a/demos/compose/src/main/java/androidx/media3/demo/compose/data/videos.kt +++ b/demos/compose/src/main/java/androidx/media3/demo/compose/data/videos.kt @@ -15,10 +15,15 @@ */ package androidx.media3.demo.compose.data +import androidx.media3.ui.compose.SURFACE_TYPE_SPHERICAL_GL_SURFACE_VIEW +import androidx.media3.ui.compose.SURFACE_TYPE_SURFACE_VIEW + val videos = - listOf( - "https://html5demos.com/assets/dizzy.mp4", - "https://storage.googleapis.com/exoplayer-test-media-0/shortform_2.mp4", - "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-vp9-360.webm", - "https://storage.googleapis.com/exoplayer-test-media-0/shortform_3.mp4", + mapOf( + "https://html5demos.com/assets/dizzy.mp4" to SURFACE_TYPE_SURFACE_VIEW, + "https://storage.googleapis.com/exoplayer-test-media-0/shortform_2.mp4" to SURFACE_TYPE_SURFACE_VIEW, + "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-vp9-360.webm" to SURFACE_TYPE_SURFACE_VIEW, + "https://storage.googleapis.com/exoplayer-test-media-0/shortform_3.mp4" to SURFACE_TYPE_SURFACE_VIEW, + // https://bitmovin.com/demos/vr-360/ + "https://cdn.bitmovin.com/content/assets/playhouse-vr/progressive.mp4" to SURFACE_TYPE_SPHERICAL_GL_SURFACE_VIEW, ) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java index ad268a0aaa3..71b452faef3 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java @@ -47,8 +47,9 @@ /** * Renders a GL scene in a non-VR Activity that is affected by phone orientation and touch input. * - *
The two input components are the TYPE_GAME_ROTATION_VECTOR Sensor and a TouchListener. The GL - * renderer combines these two inputs to render a scene with the appropriate camera orientation. + *
The two input components are the {@link Sensor#TYPE_GAME_ROTATION_VECTOR + * TYPE_GAME_ROTATION_VECTOR} Sensor and a TouchListener. The GL renderer combines these two inputs + * to render a scene with the appropriate camera orientation. * *
The primary complexity in this class is related to the various rotations. It is important to
* apply the touch and sensor rotations in the correct order or the user's touch manipulations won't
diff --git a/libraries/ui_compose/build.gradle b/libraries/ui_compose/build.gradle
index db04d25018d..d61ab137053 100644
--- a/libraries/ui_compose/build.gradle
+++ b/libraries/ui_compose/build.gradle
@@ -59,6 +59,7 @@ dependencies {
testImplementation 'androidx.compose.ui:ui-test-android:1.8.2'
testImplementation 'androidx.compose.ui:ui-test'
testImplementation 'androidx.compose.ui:ui-test-junit4'
+ testImplementation project(modulePrefix + 'lib-exoplayer')
testImplementation project(modulePrefix + 'test-utils')
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
}
diff --git a/libraries/ui_compose/proguard-rules.txt b/libraries/ui_compose/proguard-rules.txt
new file mode 100644
index 00000000000..c5d499780b4
--- /dev/null
+++ b/libraries/ui_compose/proguard-rules.txt
@@ -0,0 +1,7 @@
+# Proguard rules specific to the UI Compose module.
+
+# Constructor method and classes accessed via reflection in PlayerSurface
+-dontnote androidx.media3.exoplayer.video.spherical.SphericalGLSurfaceView
+-keepclassmembers class androidx.media3.exoplayer.video.spherical.SphericalGLSurfaceView {
+