From 4089de7272fe4bf0b9fccc5b4a644f4b992de917 Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Mon, 22 Jul 2024 16:59:18 +0200 Subject: [PATCH] fix content ratio using compose --- .idea/inspectionProfiles/Project_Default.xml | 41 +++++++++++++ .../newplayer/model/VideoPlayerViewModel.kt | 61 +++++++++++++++---- .../ui/VideoPlayerLoadingPlaceholder.kt | 5 +- .../net/newpipe/newplayer/ui/VideoPlayerUI.kt | 13 +++- .../newpipe/newplayer/testapp/MainActivity.kt | 2 + 5 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..44ca2d9 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt index 18175e7..eb828c5 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModel.kt @@ -24,6 +24,7 @@ import android.app.Application import android.os.Build import android.os.Bundle import android.os.Parcelable +import android.util.Log import androidx.annotation.RequiresApi import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.SavedStateHandle @@ -40,16 +41,25 @@ import net.newpipe.newplayer.NewPlayer val VIDEOPLAYER_UI_STATE = "video_player_ui_state" +private const val TAG = "VideoPlayerViewModel" + @Parcelize data class VideoPlayerUIState( val playing: Boolean, var fullscreen: Boolean, var uiVissible: Boolean, - var contentRatio: Float + var contentRatio: Float, + var minContentRatio: Float, + var maxContentRatio: Float ) : Parcelable { companion object { val DEFAULT = VideoPlayerUIState( - playing = false, fullscreen = false, uiVissible = false, 0F + playing = false, + fullscreen = false, + uiVissible = false, + contentRatio = 0F, + minContentRatio = 4F / 3F, + maxContentRatio = 16F / 9F ) } } @@ -59,6 +69,8 @@ interface VideoPlayerViewModel { val player: Player? val uiState: StateFlow var listener: Listener? + var minContentRatio: Float + var maxContentRatio: Float fun initUIState(instanceState: Bundle) fun play() @@ -78,7 +90,6 @@ interface VideoPlayerViewModel { } } - @HiltViewModel class VideoPlayerViewModelImpl @Inject constructor( private val savedStateHandle: SavedStateHandle, @@ -99,11 +110,36 @@ class VideoPlayerViewModelImpl @Inject constructor( override val uiState = mutableUiState.asStateFlow() override var listener: VideoPlayerViewModel.Listener? = null - override val player:Player? + override val player: Player? get() = newPlayer?.player + override var minContentRatio: Float + set(value) { + if (value <= 0 || mutableUiState.value.maxContentRatio < value) + Log.e( + TAG, + "Ignoring maxContentRatio: It must not be 0 or less and it may not be bigger then mmaxContentRatio. It was Set to: $value" + ) + else + mutableUiState.update { it.copy(minContentRatio = value) } + } + get() = mutableUiState.value.minContentRatio + + override var maxContentRatio: Float + get() = mutableUiState.value.maxContentRatio + set(value) { + if (value <= 0 || value < mutableUiState.value.minContentRatio) + Log.e( + TAG, + "Ignoring maxContentRatio: It must not be 0 or less and it may not be smaller then minContentRatio. It was Set to: $value" + ) + else + mutableUiState.update { it.copy(maxContentRatio = value) } + } + private fun installExoPlayer() { player?.let { player -> + Log.i(TAG, "Install player") player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { super.onIsPlayingChanged(isPlaying) @@ -143,17 +179,17 @@ class VideoPlayerViewModelImpl @Inject constructor( override fun onCleared() { super.onCleared() - println("gurken viewmodel cleared") + Log.d(TAG, "viewmodel cleared") } @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun initUIState(instanceState: Bundle) { val uiState = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) - instanceState.getParcelable(VIDEOPLAYER_UI_STATE, VideoPlayerUIState::class.java) - else - instanceState.getParcelable(VIDEOPLAYER_UI_STATE) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) instanceState.getParcelable( + VIDEOPLAYER_UI_STATE, VideoPlayerUIState::class.java + ) + else instanceState.getParcelable(VIDEOPLAYER_UI_STATE) uiState?.let { uiState -> mutableUiState.update { @@ -171,11 +207,11 @@ class VideoPlayerViewModelImpl @Inject constructor( } override fun prevStream() { - println("imeplement prev stream") + Log.e(TAG, "imeplement prev stream") } override fun nextStream() { - println("implement next stream") + Log.e(TAG, "implement next stream") } override fun switchToEmbeddedView() { @@ -196,7 +232,8 @@ class VideoPlayerViewModelImpl @Inject constructor( override val player: Player? = null override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT) override var listener: VideoPlayerViewModel.Listener? = null - + override var minContentRatio = 4F / 3F + override var maxContentRatio = 16F / 9F override fun initUIState(instanceState: Bundle) { println("dummy impl") diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerLoadingPlaceholder.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerLoadingPlaceholder.kt index f155f12..bd60582 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerLoadingPlaceholder.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerLoadingPlaceholder.kt @@ -1,6 +1,7 @@ package net.newpipe.newplayer.ui import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Surface @@ -16,9 +17,9 @@ import androidx.compose.ui.unit.dp import net.newpipe.newplayer.ui.theme.VideoPlayerTheme @Composable -fun VideoPlayerLoadingPlaceholder() { +fun VideoPlayerLoadingPlaceholder(aspectRatio:Float = 3F/1F) { Surface( - modifier = Modifier.fillMaxWidth().height(200.dp), + modifier = Modifier.fillMaxWidth().aspectRatio(aspectRatio), color = Color.Black ) { Box { diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt index 595be65..aa29e91 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerUI.kt @@ -25,7 +25,9 @@ import android.view.SurfaceView import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -53,8 +55,10 @@ import net.newpipe.newplayer.utils.findActivity fun VideoPlayerUI( viewModel: VideoPlayerViewModel?, ) { - if (viewModel?.player == null) { + if (viewModel == null) { VideoPlayerLoadingPlaceholder() + } else if (viewModel.player == null) { + VideoPlayerLoadingPlaceholder(viewModel.uiState.collectAsState().value.maxContentRatio) } else { val uiState by viewModel.uiState.collectAsState() @@ -106,8 +110,13 @@ fun VideoPlayerUI( } // Set UI + val aspectRatio = + uiState.contentRatio.coerceIn(uiState.minContentRatio, uiState.maxContentRatio) + Surface( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxWidth() + .aspectRatio(aspectRatio), color = Color.Black ) { AndroidView( diff --git a/test-app/src/main/java/net/newpipe/newplayer/testapp/MainActivity.kt b/test-app/src/main/java/net/newpipe/newplayer/testapp/MainActivity.kt index 9ca0fb3..a1487ff 100644 --- a/test-app/src/main/java/net/newpipe/newplayer/testapp/MainActivity.kt +++ b/test-app/src/main/java/net/newpipe/newplayer/testapp/MainActivity.kt @@ -51,6 +51,8 @@ class MainActivity : AppCompatActivity() { video_view.viewModel = videoPlayerViewModel videoPlayerViewModel.newPlayer = newPlayer + videoPlayerViewModel.maxContentRatio = 4F/3F + /* video_view.fullScreenToggleListener = object : VideoPlayerView.FullScreenToggleListener { override fun fullscreenToggle(turnOn: Boolean) {