commit shit

This commit is contained in:
Christian Schabesberger 2024-07-23 16:58:33 +02:00
parent 8551a36a0c
commit b95db7cd07
5 changed files with 100 additions and 55 deletions

View File

@ -4,7 +4,7 @@
<selectionStates>
<SelectionState runConfigName="TestApp">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2024-07-23T10:30:52.346401525Z">
<DropdownSelection timestamp="2024-07-23T14:30:02.857797708Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=981f7af2" />

View File

@ -29,7 +29,6 @@ import androidx.annotation.RequiresApi
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.media3.common.Player
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
@ -44,7 +43,6 @@ import net.newpipe.newplayer.utils.VideoSize
import kotlinx.parcelize.Parcelize
import net.newpipe.newplayer.NewPlayer
import net.newpipe.newplayer.ui.ContentScale
import java.lang.Thread.sleep
val VIDEOPLAYER_UI_STATE = "video_player_ui_state"
@ -57,7 +55,7 @@ data class VideoPlayerUIState(
val uiVissible: Boolean,
var uiVisible: Boolean,
val contentRatio: Float,
val uiRatio: Float,
val embeddedUiRatio: Float,
val contentFitMode: ContentScale
) : Parcelable {
companion object {
@ -67,7 +65,7 @@ data class VideoPlayerUIState(
uiVissible = false,
uiVisible = false,
contentRatio = 16 / 9F,
uiRatio = 16F / 9F,
embeddedUiRatio = 16F / 9F,
contentFitMode = ContentScale.FIT_INSIDE
)
}
@ -80,7 +78,7 @@ interface VideoPlayerViewModel {
var minContentRatio: Float
var maxContentRatio: Float
var contentFitMode: ContentScale
var fullscreenListener: FullscreenListener?
var callbackListener: Listener?
fun initUIState(instanceState: Bundle)
fun play()
@ -92,8 +90,9 @@ interface VideoPlayerViewModel {
fun showUi()
fun hideUi()
interface FullscreenListener {
interface Listener {
fun onFullscreenToggle(isFullscreen: Boolean)
fun onUiVissibleToggle(isVissible: Boolean)
}
}
@ -106,10 +105,10 @@ class VideoPlayerViewModelImpl @Inject constructor(
// private
private val mutableUiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
private var currentContentRatio = 1F
private var uiVisibilityJob:Job? = null
private var uiVisibilityJob: Job? = null
//interface
override var fullscreenListener: VideoPlayerViewModel.FullscreenListener? = null
override var callbackListener: VideoPlayerViewModel.Listener? = null
override var newPlayer: NewPlayer? = null
set(value) {
@ -131,7 +130,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
)
else {
field = value
mutableUiState.update { it.copy(uiRatio = getUiRatio()) }
mutableUiState.update { it.copy(embeddedUiRatio = getEmbeddedUiRatio()) }
}
}
@ -145,7 +144,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
)
else {
field = value
mutableUiState.update { it.copy(uiRatio = getUiRatio()) }
mutableUiState.update { it.copy(embeddedUiRatio = getEmbeddedUiRatio()) }
}
}
@ -186,7 +185,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
mutableUiState.update {
it.copy(
contentRatio = currentContentRatio,
uiRatio = getUiRatio()
embeddedUiRatio = getEmbeddedUiRatio()
)
}
}
@ -214,15 +213,12 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
override fun play() {
uiVisibilityJob?.cancel()
mutableUiState.update {
it.copy(uiVissible = false)
}
hideUi()
newPlayer?.play()
}
override fun pause() {
resetHideUiDelayed()
uiVisibilityJob?.cancel()
newPlayer?.pause()
}
@ -237,6 +233,9 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
override fun showUi() {
if (mutableUiState.value.fullscreen)
callbackListener?.onUiVissibleToggle(true)
mutableUiState.update {
it.copy(uiVissible = true)
}
@ -246,14 +245,15 @@ class VideoPlayerViewModelImpl @Inject constructor(
private fun resetHideUiDelayed() {
uiVisibilityJob?.cancel()
uiVisibilityJob = viewModelScope.launch {
delay(2000)
mutableUiState.update {
it.copy(uiVissible = false)
}
delay(4000)
hideUi()
}
}
override fun hideUi() {
if (mutableUiState.value.fullscreen)
callbackListener?.onUiVissibleToggle(false)
uiVisibilityJob?.cancel()
mutableUiState.update {
it.copy(uiVissible = false)
@ -261,7 +261,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
override fun switchToEmbeddedView() {
fullscreenListener?.onFullscreenToggle(false)
callbackListener?.onFullscreenToggle(false)
uiVisibilityJob?.cancel()
mutableUiState.update {
it.copy(fullscreen = false, uiVissible = false)
@ -269,7 +269,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
override fun switchToFullscreen() {
fullscreenListener?.onFullscreenToggle(true)
callbackListener?.onFullscreenToggle(true)
uiVisibilityJob?.cancel()
mutableUiState.update {
@ -277,13 +277,15 @@ class VideoPlayerViewModelImpl @Inject constructor(
}
}
private fun getUiRatio() =
private fun getEmbeddedUiRatio() =
player?.let { player ->
val videoRatio = VideoSize.fromMedia3VideoSize(player.videoSize).getRatio()
return if (videoRatio.isNaN())
minContentRatio
return (if (videoRatio.isNaN())
currentContentRatio
else
videoRatio.coerceIn(minContentRatio, maxContentRatio)
videoRatio).coerceIn(minContentRatio, maxContentRatio)
} ?: minContentRatio
@ -295,7 +297,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
override var minContentRatio = 4F / 3F
override var maxContentRatio = 16F / 9F
override var contentFitMode = ContentScale.FIT_INSIDE
override var fullscreenListener: VideoPlayerViewModel.FullscreenListener? = null
override var callbackListener: VideoPlayerViewModel.Listener? = null
override fun initUIState(instanceState: Bundle) {
println("dummy impl")

View File

@ -29,14 +29,19 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.windowInsetsTopHeight
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.automirrored.filled.MenuBook
@ -100,7 +105,15 @@ fun VideoPlayerControllerUI(
hideUi: () -> Unit
) {
Box(modifier = Modifier) {
val insets = WindowInsets.systemBars
Box(
modifier = Modifier.then(
if (fullscreen)
Modifier.windowInsetsPadding(insets)
else
Modifier
)
) {
if (!uiVissible) {
TouchUi(
modifier = Modifier.fillMaxSize(),
@ -124,7 +137,6 @@ fun VideoPlayerControllerUI(
modifier = if (fullscreen) {
Modifier
.background(Color.Transparent)
.windowInsetsPadding(WindowInsets.systemBars)
} else {
Modifier
.background(Color.Transparent)

View File

@ -22,18 +22,15 @@ package net.newpipe.newplayer.ui
import android.content.pm.ActivityInfo
import android.view.SurfaceView
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
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
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -42,6 +39,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView
@ -60,7 +58,7 @@ fun VideoPlayerUI(
if (viewModel == null) {
VideoPlayerLoadingPlaceholder()
} else if (viewModel.player == null) {
VideoPlayerLoadingPlaceholder(viewModel.uiState.collectAsState().value.uiRatio)
VideoPlayerLoadingPlaceholder(viewModel.uiState.collectAsState().value.embeddedUiRatio)
} else {
val uiState by viewModel.uiState.collectAsState()
@ -68,6 +66,8 @@ fun VideoPlayerUI(
mutableStateOf(Lifecycle.Event.ON_CREATE)
}
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
// Prepare stuff for the SurfaceView to which the video will be rendered
@ -83,17 +83,6 @@ fun VideoPlayerUI(
}
// Handle Fullscreen/Embedded view transition
if (uiState.fullscreen) {
BackHandler {
//closeFullscreen(viewModel, activity!!)
}
}
LaunchedEffect(key1 = uiState.fullscreen) {
println("gurken launch fullscreen: ${uiState.fullscreen}")
}
// Set Screen Rotation
if (uiState.fullscreen) {
if (uiState.contentRatio < 1) {
@ -103,18 +92,22 @@ fun VideoPlayerUI(
}
}
val displayMetrics = context.resources.displayMetrics
val screenRatio =
displayMetrics.widthPixels.toFloat() / displayMetrics.heightPixels.toFloat()
// Set UI
Surface(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(uiState.uiRatio), color = Color.Black
.aspectRatio(uiState.embeddedUiRatio), color = Color.Black
) {
Box(contentAlignment = Alignment.Center) {
PlaySurface(
player = viewModel.player,
lifecycle = lifecycle,
fitMode = uiState.contentFitMode,
uiRatio = uiState.uiRatio,
uiRatio = if (uiState.fullscreen) screenRatio else uiState.embeddedUiRatio,
contentRatio = uiState.contentRatio
)
}
@ -148,12 +141,19 @@ fun PlaySurface(
.fillMaxWidth()
.aspectRatio(16F / 9F)
/*
Box(
modifier = Modifier
.then(
when (fitMode) {
ContentScale.FILL -> Modifier.fillMaxSize()
ContentScale.FIT_INSIDE -> Modifier.aspectRatio(contentRatio)
ContentScale.FIT_INSIDE -> Modifier
.aspectRatio(contentRatio)
.then(
if (contentRatio < uiRatio) Modifier
.fillMaxWidth() else Modifier.fillMaxHeight()
)
ContentScale.CROP -> Modifier
.aspectRatio(contentRatio)
.wrapContentWidth(unbounded = true)
@ -161,7 +161,8 @@ fun PlaySurface(
}
)
) {
*/
Box(modifier = Modifier.fillMaxHeight().aspectRatio(contentRatio)) {
AndroidView(factory = { context ->
SurfaceView(context).also { view ->
player?.setVideoSurfaceView(view)

View File

@ -27,6 +27,7 @@ import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import dagger.hilt.android.AndroidEntryPoint
@ -62,17 +63,33 @@ class MainActivity : AppCompatActivity() {
video_view.viewModel = videoPlayerViewModel
videoPlayerViewModel.newPlayer = newPlayer
//videoPlayerViewModel.maxContentRatio = 4F/3F
videoPlayerViewModel.maxContentRatio = 4F/3F
videoPlayerViewModel.contentFitMode = ContentScale.FIT_INSIDE
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(
systemBars.left,
systemBars.top,
systemBars.right,
systemBars.bottom
)
insets
}
if (videoPlayerViewModel.uiState.value.fullscreen) {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(0, 0, 0, 0)
insets
}
//ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
// v.setPadding(0, 0, 0, 0)
// insets
//}
buttons_layout.visibility = View.GONE
//windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
} else {
buttons_layout.visibility = View.VISIBLE
@ -86,8 +103,21 @@ class MainActivity : AppCompatActivity() {
)
insets
}
//windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
}
videoPlayerViewModel.callbackListener = object : VideoPlayerViewModel.Listener {
override fun onFullscreenToggle(isFullscreen: Boolean) {}
override fun onUiVissibleToggle(isVissible: Boolean) {
if (isVissible) {
// windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
} else {
// windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}
}
}
}
}