diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 8bcdc35..df92f12 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
+
+
+
+
+
+
+
+
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 90c5665..d61bac8 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
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.update
import net.newpipe.newplayer.utils.VideoSize
import kotlinx.parcelize.Parcelize
import net.newpipe.newplayer.NewPlayer
-import net.newpipe.newplayer.ui.ContentFitMode
+import net.newpipe.newplayer.ui.ContentScale
val VIDEOPLAYER_UI_STATE = "video_player_ui_state"
@@ -51,7 +51,7 @@ data class VideoPlayerUIState(
var uiVisible: Boolean,
val contentRatio: Float,
val uiRatio: Float,
- val contentFitMode: ContentFitMode
+ val contentFitMode: ContentScale
) : Parcelable {
companion object {
val DEFAULT = VideoPlayerUIState(
@@ -60,7 +60,7 @@ data class VideoPlayerUIState(
uiVisible = false,
contentRatio = 16 / 9F,
uiRatio = 16F / 9F,
- contentFitMode = ContentFitMode.FIT_INSIDE
+ contentFitMode = ContentScale.FIT_INSIDE
)
}
}
@@ -71,6 +71,7 @@ interface VideoPlayerViewModel {
val uiState: StateFlow
var minContentRatio: Float
var maxContentRatio: Float
+ var contentFitMode: ContentScale
fun initUIState(instanceState: Bundle)
fun play()
@@ -129,6 +130,14 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
}
+ override var contentFitMode: ContentScale
+ get() = mutableUiState.value.contentFitMode
+ set(value) {
+ mutableUiState.update {
+ it.copy(contentFitMode = value)
+ }
+ }
+
private fun installExoPlayer() {
player?.let { player ->
Log.d(TAG, "Install player: ${player.videoSize.width}")
@@ -227,6 +236,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
override var minContentRatio = 4F / 3F
override var maxContentRatio = 16F / 9F
+ override var contentFitMode = ContentScale.FIT_INSIDE
override fun initUIState(instanceState: Bundle) {
println("dummy impl")
diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/ContentFitMode.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/ContentScale.kt
similarity index 63%
rename from new-player/src/main/java/net/newpipe/newplayer/ui/ContentFitMode.kt
rename to new-player/src/main/java/net/newpipe/newplayer/ui/ContentScale.kt
index 585bb92..0d75852 100644
--- a/new-player/src/main/java/net/newpipe/newplayer/ui/ContentFitMode.kt
+++ b/new-player/src/main/java/net/newpipe/newplayer/ui/ContentScale.kt
@@ -1,8 +1,8 @@
package net.newpipe.newplayer.ui
-enum class ContentFitMode {
+enum class ContentScale {
FILL,
FIT_INSIDE,
- ZOOM
+ CROP
}
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 5dc169c..893a3f8 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
@@ -28,6 +28,8 @@ import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -45,6 +47,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
+import androidx.media3.common.Player
import net.newpipe.newplayer.model.VideoPlayerViewModel
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
@@ -107,60 +110,13 @@ fun VideoPlayerUI(
.aspectRatio(uiState.uiRatio), color = Color.Black
) {
Box(contentAlignment = Alignment.Center) {
- val viewBoxModifier = Modifier
- when (uiState.contentFitMode) {
- ContentFitMode.FILL -> {
- println("fit mode fill")
- viewBoxModifier.fillMaxSize()
- }
-
- ContentFitMode.FIT_INSIDE -> {
- println("fit mode fit inside:")
- if (uiState.contentRatio < uiState.uiRatio) {
- println("fit mode fill max height")
- viewBoxModifier
- .fillMaxHeight()
- .aspectRatio(uiState.contentRatio)
- } else if (uiState.uiRatio < uiState.contentRatio) {
- println("fit mode fill max width")
- viewBoxModifier
- .fillMaxWidth()
- .aspectRatio(uiState.contentRatio)
- }
- }
-
- ContentFitMode.ZOOM -> {
- println("fit mode zoom:")
- if (uiState.uiRatio < uiState.contentRatio) {
- viewBoxModifier
- .fillMaxHeight()
- .aspectRatio(uiState.contentRatio)
- } else if (uiState.contentRatio < uiState.uiRatio) {
- viewBoxModifier
- .fillMaxWidth()
- .aspectRatio(uiState.contentRatio)
- }
- }
- }
-
- Box(modifier = viewBoxModifier) {
- AndroidView(factory = { context ->
- SurfaceView(context).also { view ->
- viewModel.player?.setVideoSurfaceView(view)
- }
- }, update = { view ->
- when (lifecycle) {
- Lifecycle.Event.ON_RESUME -> {
- viewModel.player?.setVideoSurfaceView(view)
- }
-
- else -> Unit
- }
- })
- Surface(color = Color.Green, modifier = Modifier.fillMaxSize()) {
-
- }
- }
+ PlaySurface(
+ player = viewModel.player,
+ lifecycle = lifecycle,
+ fitMode = uiState.contentFitMode,
+ uiRatio = uiState.uiRatio,
+ contentRatio = uiState.contentRatio
+ )
}
VideoPlayerControllerUI(
isPlaying = uiState.playing,
@@ -176,6 +132,50 @@ fun VideoPlayerUI(
}
}
+@Composable
+fun PlaySurface(
+ player: Player?,
+ lifecycle: Lifecycle.Event,
+ fitMode: ContentScale,
+ uiRatio: Float,
+ contentRatio: Float
+) {
+ val viewBoxModifier = Modifier
+ viewBoxModifier
+ .fillMaxWidth()
+ .aspectRatio(16F / 9F)
+
+ Box(
+ modifier = Modifier
+ .then(
+ when (fitMode) {
+ ContentScale.FILL -> Modifier.fillMaxSize()
+ ContentScale.FIT_INSIDE -> Modifier.aspectRatio(contentRatio)
+ ContentScale.CROP -> Modifier
+ .aspectRatio(contentRatio)
+ .wrapContentWidth(unbounded = true)
+ .fillMaxSize()
+ }
+ )
+ ) {
+
+ AndroidView(factory = { context ->
+ SurfaceView(context).also { view ->
+ player?.setVideoSurfaceView(view)
+ }
+ }, update = { view ->
+ when (lifecycle) {
+ Lifecycle.Event.ON_RESUME -> {
+ player?.setVideoSurfaceView(view)
+ }
+
+ else -> Unit
+ }
+ })
+
+ }
+}
+
@Preview(device = "spec:width=1080px,height=700px,dpi=440,orientation=landscape")
@Composable
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 4e907f9..ae2ea13 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
@@ -26,12 +26,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
-import androidx.lifecycle.viewmodel.compose.viewModel
import dagger.hilt.android.AndroidEntryPoint
import net.newpipe.newplayer.NewPlayer
import net.newpipe.newplayer.VideoPlayerView
import net.newpipe.newplayer.model.VideoPlayerViewModel
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
+import net.newpipe.newplayer.ui.ContentScale
import javax.inject.Inject
@AndroidEntryPoint
@@ -52,6 +52,7 @@ class MainActivity : AppCompatActivity() {
videoPlayerViewModel.newPlayer = newPlayer
videoPlayerViewModel.maxContentRatio = 4F/3F
+ videoPlayerViewModel.contentFitMode = ContentScale.FIT_INSIDE
/*
video_view.fullScreenToggleListener = object : VideoPlayerView.FullScreenToggleListener {