commit shit
This commit is contained in:
parent
8551a36a0c
commit
b95db7cd07
|
@ -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" />
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue