mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 15:32:01 +00:00
fix: adjust screen awake behaviour when playback error throws
fixes #877
This commit is contained in:
parent
f7e9778ca4
commit
b941717dd9
5 changed files with 27 additions and 7 deletions
|
|
@ -179,6 +179,10 @@ actual fun PlatformPlayerSurface(
|
||||||
var currentSubtitleStyle by remember { mutableStateOf(SubtitleStyleState.DEFAULT) }
|
var currentSubtitleStyle by remember { mutableStateOf(SubtitleStyleState.DEFAULT) }
|
||||||
var subtitleSelectionJob by remember { mutableStateOf<Job?>(null) }
|
var subtitleSelectionJob by remember { mutableStateOf<Job?>(null) }
|
||||||
|
|
||||||
|
fun syncPlayerViewKeepScreenOn() {
|
||||||
|
playerViewRef?.keepScreenOn = exoPlayer.shouldKeepPlayerScreenOn()
|
||||||
|
}
|
||||||
|
|
||||||
DisposableEffect(exoPlayer) {
|
DisposableEffect(exoPlayer) {
|
||||||
PlayerPictureInPictureManager.registerPausePlaybackCallback {
|
PlayerPictureInPictureManager.registerPausePlaybackCallback {
|
||||||
exoPlayer.pause()
|
exoPlayer.pause()
|
||||||
|
|
@ -186,6 +190,7 @@ actual fun PlatformPlayerSurface(
|
||||||
|
|
||||||
val listener = object : Player.Listener {
|
val listener = object : Player.Listener {
|
||||||
override fun onPlayerError(error: PlaybackException) {
|
override fun onPlayerError(error: PlaybackException) {
|
||||||
|
syncPlayerViewKeepScreenOn()
|
||||||
latestOnError.value(error.localizedMessage ?: runBlocking { getString(Res.string.player_unable_to_play_stream) })
|
latestOnError.value(error.localizedMessage ?: runBlocking { getString(Res.string.player_unable_to_play_stream) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,10 +207,12 @@ actual fun PlatformPlayerSurface(
|
||||||
latestOnError.value(null)
|
latestOnError.value(null)
|
||||||
exoPlayer.logCurrentTracks("STATE_READY")
|
exoPlayer.logCurrentTracks("STATE_READY")
|
||||||
}
|
}
|
||||||
|
syncPlayerViewKeepScreenOn()
|
||||||
latestOnSnapshot.value(exoPlayer.snapshot())
|
latestOnSnapshot.value(exoPlayer.snapshot())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
|
syncPlayerViewKeepScreenOn()
|
||||||
latestOnSnapshot.value(exoPlayer.snapshot())
|
latestOnSnapshot.value(exoPlayer.snapshot())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,6 +242,7 @@ actual fun PlatformPlayerSurface(
|
||||||
onDispose {
|
onDispose {
|
||||||
PlayerPictureInPictureManager.registerPausePlaybackCallback(null)
|
PlayerPictureInPictureManager.registerPausePlaybackCallback(null)
|
||||||
exoPlayer.removeListener(listener)
|
exoPlayer.removeListener(listener)
|
||||||
|
playerViewRef?.keepScreenOn = false
|
||||||
subtitleSelectionJob?.cancel()
|
subtitleSelectionJob?.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -264,6 +272,7 @@ actual fun PlatformPlayerSurface(
|
||||||
|
|
||||||
LaunchedEffect(exoPlayer, playWhenReady) {
|
LaunchedEffect(exoPlayer, playWhenReady) {
|
||||||
exoPlayer.playWhenReady = playWhenReady
|
exoPlayer.playWhenReady = playWhenReady
|
||||||
|
syncPlayerViewKeepScreenOn()
|
||||||
latestOnSnapshot.value(exoPlayer.snapshot())
|
latestOnSnapshot.value(exoPlayer.snapshot())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,7 +433,7 @@ actual fun PlatformPlayerSurface(
|
||||||
useController = useNativeController
|
useController = useNativeController
|
||||||
layoutParams = android.view.ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
layoutParams = android.view.ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||||
player = exoPlayer
|
player = exoPlayer
|
||||||
keepScreenOn = true
|
keepScreenOn = exoPlayer.shouldKeepPlayerScreenOn()
|
||||||
this.resizeMode = resizeMode.toExoResizeMode()
|
this.resizeMode = resizeMode.toExoResizeMode()
|
||||||
setShutterBackgroundColor(android.graphics.Color.BLACK)
|
setShutterBackgroundColor(android.graphics.Color.BLACK)
|
||||||
playerViewRef = this
|
playerViewRef = this
|
||||||
|
|
@ -441,6 +450,7 @@ actual fun PlatformPlayerSurface(
|
||||||
playerView.useController = useNativeController
|
playerView.useController = useNativeController
|
||||||
playerView.resizeMode = resizeMode.toExoResizeMode()
|
playerView.resizeMode = resizeMode.toExoResizeMode()
|
||||||
playerViewRef = playerView
|
playerViewRef = playerView
|
||||||
|
syncPlayerViewKeepScreenOn()
|
||||||
playerView.syncLibassOverlay(
|
playerView.syncLibassOverlay(
|
||||||
player = exoPlayer,
|
player = exoPlayer,
|
||||||
enabled = useLibass,
|
enabled = useLibass,
|
||||||
|
|
@ -469,6 +479,11 @@ private fun ExoPlayer.snapshot(): PlayerPlaybackSnapshot =
|
||||||
playbackSpeed = playbackParameters.speed,
|
playbackSpeed = playbackParameters.speed,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun ExoPlayer.shouldKeepPlayerScreenOn(): Boolean =
|
||||||
|
playerError == null &&
|
||||||
|
playWhenReady &&
|
||||||
|
playbackState in setOf(Player.STATE_BUFFERING, Player.STATE_READY)
|
||||||
|
|
||||||
private fun PlayerResizeMode.toExoResizeMode(): Int =
|
private fun PlayerResizeMode.toExoResizeMode(): Int =
|
||||||
when (this) {
|
when (this) {
|
||||||
PlayerResizeMode.Fit -> AspectRatioFrameLayout.RESIZE_MODE_FIT
|
PlayerResizeMode.Fit -> AspectRatioFrameLayout.RESIZE_MODE_FIT
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ actual fun LockPlayerToLandscape() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
actual fun EnterImmersivePlayerMode() {
|
actual fun EnterImmersivePlayerMode(keepScreenAwake: Boolean) {
|
||||||
val activity = LocalContext.current.findActivity() ?: return
|
val activity = LocalContext.current.findActivity() ?: return
|
||||||
|
|
||||||
DisposableEffect(activity) {
|
DisposableEffect(activity) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ data class PlayerAudioLevel(
|
||||||
expect fun LockPlayerToLandscape()
|
expect fun LockPlayerToLandscape()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
expect fun EnterImmersivePlayerMode()
|
expect fun EnterImmersivePlayerMode(keepScreenAwake: Boolean)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
expect fun ManagePlayerPictureInPicture(
|
expect fun ManagePlayerPictureInPicture(
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,6 @@ fun PlayerScreen(
|
||||||
initialProgressFraction: Float? = null,
|
initialProgressFraction: Float? = null,
|
||||||
) {
|
) {
|
||||||
LockPlayerToLandscape()
|
LockPlayerToLandscape()
|
||||||
EnterImmersivePlayerMode()
|
|
||||||
val playerSettingsUiState by remember {
|
val playerSettingsUiState by remember {
|
||||||
PlayerSettingsRepository.ensureLoaded()
|
PlayerSettingsRepository.ensureLoaded()
|
||||||
PlayerSettingsRepository.uiState
|
PlayerSettingsRepository.uiState
|
||||||
|
|
@ -195,6 +194,9 @@ fun PlayerScreen(
|
||||||
var playerController by remember { mutableStateOf<PlayerEngineController?>(null) }
|
var playerController by remember { mutableStateOf<PlayerEngineController?>(null) }
|
||||||
var playerControllerSourceUrl by remember { mutableStateOf<String?>(null) }
|
var playerControllerSourceUrl by remember { mutableStateOf<String?>(null) }
|
||||||
var errorMessage by remember { mutableStateOf<String?>(null) }
|
var errorMessage by remember { mutableStateOf<String?>(null) }
|
||||||
|
val keepScreenAwake = errorMessage == null &&
|
||||||
|
(playbackSnapshot.isPlaying || (shouldPlay && playbackSnapshot.isLoading))
|
||||||
|
EnterImmersivePlayerMode(keepScreenAwake = keepScreenAwake)
|
||||||
var scrubbingPositionMs by remember { mutableStateOf<Long?>(null) }
|
var scrubbingPositionMs by remember { mutableStateOf<Long?>(null) }
|
||||||
var pausedOverlayVisible by remember { mutableStateOf(false) }
|
var pausedOverlayVisible by remember { mutableStateOf(false) }
|
||||||
var gestureFeedback by remember { mutableStateOf<GestureFeedbackState?>(null) }
|
var gestureFeedback by remember { mutableStateOf<GestureFeedbackState?>(null) }
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.nuvio.app.features.player
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.SideEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.unit.IntSize
|
import androidx.compose.ui.unit.IntSize
|
||||||
import platform.Foundation.NSNotificationCenter
|
import platform.Foundation.NSNotificationCenter
|
||||||
|
|
@ -32,10 +33,12 @@ actual fun LockPlayerToLandscape() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
actual fun EnterImmersivePlayerMode() {
|
actual fun EnterImmersivePlayerMode(keepScreenAwake: Boolean) {
|
||||||
|
SideEffect {
|
||||||
|
UIApplication.sharedApplication.setIdleTimerDisabled(keepScreenAwake)
|
||||||
|
}
|
||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
// Request idle timer disabled to keep screen awake during playback
|
|
||||||
UIApplication.sharedApplication.setIdleTimerDisabled(true)
|
|
||||||
onDispose {
|
onDispose {
|
||||||
UIApplication.sharedApplication.setIdleTimerDisabled(false)
|
UIApplication.sharedApplication.setIdleTimerDisabled(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue