diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt index 83b74827..a33c0889 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.animation.slideOutHorizontally import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -24,6 +23,7 @@ import androidx.compose.material.icons.outlined.VolumeUp import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -39,6 +39,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect +import androidx.media3.common.Player +import androidx.media3.common.VideoSize import androidx.media3.common.util.UnstableApi import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView @@ -61,6 +63,7 @@ import kotlin.math.abs import kotlin.math.roundToInt private const val CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION = 0.32f +private const val WIDE_VIDEO_ASPECT_RATIO = 16f / 9f @OptIn(UnstableApi::class) @Composable @@ -80,12 +83,25 @@ fun PlayerScreen( var showQueuePanel by remember { mutableStateOf(false) } var horizontalSeekFeedback by remember { mutableStateOf(null) } var horizontalSeekPreviewPositionMs by remember { mutableStateOf(null) } + var videoAspectRatio by remember { mutableStateOf(calculateVideoAspectRatio(viewModel.player.videoSize)) } val overlayController = rememberPersistentOverlayController() LifecycleEventEffect(Lifecycle.Event.ON_STOP) { viewModel.pausePlayback() } + DisposableEffect(viewModel.player) { + val listener = object : Player.Listener { + override fun onVideoSizeChanged(videoSize: VideoSize) { + videoAspectRatio = calculateVideoAspectRatio(videoSize) + } + } + viewModel.player.addListener(listener) + onDispose { + viewModel.player.removeListener(listener) + } + } + LaunchedEffect(uiState.isPlaying) { if (uiState.isPlaying) { showQueuePanel = false @@ -93,6 +109,7 @@ fun PlayerScreen( } val playerControlsVisible = controlsVisible || uiState.isEnded || uiState.error != null + val playerResizeMode = playerResizeMode(videoAspectRatio) val subtitleBottomPaddingFraction = if (playerControlsVisible) { CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION @@ -109,18 +126,18 @@ fun PlayerScreen( factory = { ctx -> PlayerView(ctx).apply { useController = false - resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT + resizeMode = playerResizeMode player = viewModel.player subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) } }, update = { it.player = viewModel.player + it.resizeMode = playerResizeMode it.subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) }, modifier = Modifier - .fillMaxHeight() - .align(Alignment.Center) + .fillMaxSize() ) PlayerGesturesLayer( @@ -294,6 +311,21 @@ fun PlayerScreen( } } +@OptIn(UnstableApi::class) +private fun playerResizeMode(videoAspectRatio: Float): Int = + if (videoAspectRatio >= WIDE_VIDEO_ASPECT_RATIO) { + AspectRatioFrameLayout.RESIZE_MODE_ZOOM + } else { + AspectRatioFrameLayout.RESIZE_MODE_FIT + } + +private fun calculateVideoAspectRatio(videoSize: VideoSize): Float { + if (videoSize.width <= 0 || videoSize.height <= 0) { + return 0f + } + return videoSize.width * videoSize.pixelWidthHeightRatio / videoSize.height +} + @Composable private fun HiddenSeekTimeline( positionMs: Long,