restructure NewPlayerUI and VideoPlayerUI
This commit is contained in:
parent
a222a7c9a0
commit
25593c8ed6
|
@ -53,7 +53,7 @@ import androidx.core.view.WindowCompat
|
|||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import net.newpipe.newplayer.model.UIModeState
|
||||
|
@ -62,6 +62,7 @@ import net.newpipe.newplayer.model.NewPlayerViewModelDummy
|
|||
import net.newpipe.newplayer.ui.streamselect.StreamSelectUI
|
||||
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||
import net.newpipe.newplayer.ui.videoplayer.VideoPlayerControllerUI
|
||||
import net.newpipe.newplayer.ui.videoplayer.VideoPlayerUi
|
||||
import net.newpipe.newplayer.utils.LockScreenOrientation
|
||||
import net.newpipe.newplayer.utils.getDefaultBrightness
|
||||
import net.newpipe.newplayer.utils.setScreenBrightness
|
||||
|
@ -79,11 +80,6 @@ fun NewPlayerUI(
|
|||
VideoPlayerLoadingPlaceholder(viewModel.uiState.collectAsState().value.embeddedUiRatio)
|
||||
} else {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
val exoPlayer by viewModel.newPlayer?.exoPlayer!!.collectAsState()
|
||||
|
||||
var lifecycle by remember {
|
||||
mutableStateOf(Lifecycle.Event.ON_CREATE)
|
||||
}
|
||||
|
||||
val activity = LocalContext.current as Activity
|
||||
val view = LocalView.current
|
||||
|
@ -93,8 +89,6 @@ fun NewPlayerUI(
|
|||
windowInsetsController.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
|
||||
val defaultBrightness = getDefaultBrightness(activity)
|
||||
|
||||
// Setup fullscreen
|
||||
|
@ -141,24 +135,6 @@ fun NewPlayerUI(
|
|||
}
|
||||
}
|
||||
|
||||
// Prepare stuff for the SurfaceView to which the video will be rendered
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
lifecycle = event
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val displayMetrics = activity.resources.displayMetrics
|
||||
val screenRatio =
|
||||
displayMetrics.widthPixels.toFloat() / displayMetrics.heightPixels.toFloat()
|
||||
|
||||
|
||||
LaunchedEffect(key1 = uiState.brightness) {
|
||||
Log.d(TAG, "New Brightnes: ${uiState.brightness}")
|
||||
setScreenBrightness(
|
||||
|
@ -170,48 +146,7 @@ fun NewPlayerUI(
|
|||
if (uiState.uiMode == UIModeState.PLACEHOLDER) {
|
||||
VideoPlayerLoadingPlaceholder(uiState.embeddedUiRatio)
|
||||
} else {
|
||||
Surface(
|
||||
modifier = Modifier.then(
|
||||
if (uiState.uiMode.fullscreen) Modifier.fillMaxSize()
|
||||
else Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(uiState.embeddedUiRatio)
|
||||
), color = Color.Black
|
||||
) {
|
||||
|
||||
exoPlayer?.let { exoPlayer ->
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
PlaySurface(
|
||||
player = exoPlayer,
|
||||
lifecycle = lifecycle,
|
||||
fitMode = uiState.contentFitMode,
|
||||
uiRatio = if (uiState.uiMode.fullscreen) screenRatio
|
||||
else uiState.embeddedUiRatio,
|
||||
contentRatio = uiState.contentRatio
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the checks if VideoPlayerControllerUI should be visible or not are done by
|
||||
// The VideoPlayerControllerUI composable itself. This is because Visibility of
|
||||
// the controller is more complicated than just using a simple if statement.
|
||||
VideoPlayerControllerUI(
|
||||
viewModel, uiState = uiState
|
||||
)
|
||||
|
||||
AnimatedVisibility(visible = uiState.uiMode.isStreamSelect) {
|
||||
StreamSelectUI(
|
||||
viewModel = viewModel,
|
||||
uiState = uiState,
|
||||
isChapterSelect = false
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(visible = uiState.uiMode.isChapterSelect) {
|
||||
StreamSelectUI(viewModel = viewModel, uiState = uiState, isChapterSelect = true)
|
||||
}
|
||||
}
|
||||
VideoPlayerUi(viewModel = viewModel, uiState = uiState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package net.newpipe.newplayer.ui.videoplayer
|
||||
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
|
@ -38,6 +39,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import net.newpipe.newplayer.model.NewPlayerUIState
|
||||
import net.newpipe.newplayer.model.NewPlayerViewModel
|
||||
import net.newpipe.newplayer.model.NewPlayerViewModelDummy
|
||||
|
@ -50,6 +52,7 @@ import net.newpipe.newplayer.utils.getInsets
|
|||
val CONTROLLER_UI_BACKGROUND_COLOR = Color(0x75000000)
|
||||
val STREAMSELECT_UI_BACKGROUND_COLOR = Color(0xba000000)
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Composable
|
||||
fun VideoPlayerControllerUI(
|
||||
viewModel: NewPlayerViewModel, uiState: NewPlayerUIState
|
||||
|
@ -136,6 +139,7 @@ fun PreviewBackgroundSurface(
|
|||
// Preview
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Preview(device = "spec:width=1080px,height=600px,dpi=440,orientation=landscape")
|
||||
@Composable
|
||||
fun VideoPlayerControllerUIPreviewEmbedded() {
|
||||
|
@ -146,6 +150,7 @@ fun VideoPlayerControllerUIPreviewEmbedded() {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=landscape")
|
||||
@Composable
|
||||
fun VideoPlayerControllerUIPreviewLandscape() {
|
||||
|
@ -156,6 +161,7 @@ fun VideoPlayerControllerUIPreviewLandscape() {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=portrait")
|
||||
@Composable
|
||||
fun VideoPlayerControllerUIPreviewPortrait() {
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/* NewPlayer
|
||||
*
|
||||
* @author Christian Schabesberger
|
||||
*
|
||||
* Copyright (C) NewPipe e.V. 2024 <code(at)newpipe-ev.de>
|
||||
*
|
||||
* NewPlayer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPlayer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.newpipe.newplayer.ui.videoplayer
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Box
|
||||
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
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
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.lifecycle.Lifecycle
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import net.newpipe.newplayer.model.NewPlayerUIState
|
||||
import net.newpipe.newplayer.model.NewPlayerViewModel
|
||||
import net.newpipe.newplayer.ui.PlaySurface
|
||||
import net.newpipe.newplayer.ui.streamselect.StreamSelectUI
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
@Composable
|
||||
fun VideoPlayerUi(viewModel: NewPlayerViewModel, uiState: NewPlayerUIState) {
|
||||
val exoPlayer by viewModel.newPlayer?.exoPlayer!!.collectAsState()
|
||||
|
||||
var lifecycle by remember {
|
||||
mutableStateOf(Lifecycle.Event.ON_CREATE)
|
||||
}
|
||||
|
||||
val activity = LocalContext.current as Activity
|
||||
|
||||
val displayMetrics = activity.resources.displayMetrics
|
||||
|
||||
val screenRatio =
|
||||
displayMetrics.widthPixels.toFloat() / displayMetrics.heightPixels.toFloat()
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
|
||||
// Prepare stuff for the SurfaceView to which the video will be rendered
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
lifecycle = event
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.then(
|
||||
if (uiState.uiMode.fullscreen) Modifier.fillMaxSize()
|
||||
else Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(uiState.embeddedUiRatio)
|
||||
), color = Color.Black
|
||||
) {
|
||||
|
||||
exoPlayer?.let { exoPlayer ->
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
PlaySurface(
|
||||
player = exoPlayer,
|
||||
lifecycle = lifecycle,
|
||||
fitMode = uiState.contentFitMode,
|
||||
uiRatio = if (uiState.uiMode.fullscreen) screenRatio
|
||||
else uiState.embeddedUiRatio,
|
||||
contentRatio = uiState.contentRatio
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// the checks if VideoPlayerControllerUI should be visible or not are done by
|
||||
// The VideoPlayerControllerUI composable itself. This is because Visibility of
|
||||
// the controller is more complicated than just using a simple if statement.
|
||||
VideoPlayerControllerUI(
|
||||
viewModel, uiState = uiState
|
||||
)
|
||||
|
||||
AnimatedVisibility(visible = uiState.uiMode.isStreamSelect) {
|
||||
StreamSelectUI(
|
||||
viewModel = viewModel,
|
||||
uiState = uiState,
|
||||
isChapterSelect = false
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(visible = uiState.uiMode.isChapterSelect) {
|
||||
StreamSelectUI(viewModel = viewModel, uiState = uiState, isChapterSelect = true)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue