diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt index 5f51eaf..79bcdda 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerUIState.kt @@ -34,6 +34,7 @@ data class VideoPlayerUIState( val embeddedUiRatio: Float, val contentFitMode: ContentScale, val seekerPosition: Float, + val bufferedPercentage: Float, val isLoading: Boolean, val durationInMs: Long, val playbackPositionInMs: Long @@ -44,10 +45,11 @@ data class VideoPlayerUIState( fullscreen = false, uiVissible = false, uiVisible = false, - contentRatio = 16 / 9F, - embeddedUiRatio = 16F / 9F, + contentRatio = 16 / 9f, + embeddedUiRatio = 16f / 9f, contentFitMode = ContentScale.FIT_INSIDE, - seekerPosition = 0F, + seekerPosition = 0f, + bufferedPercentage = 0f, isLoading = true, durationInMs = 0, playbackPositionInMs = 0 diff --git a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt index fb935e9..15cfea5 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/model/VideoPlayerViewModelImpl.kt @@ -34,7 +34,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import javax.inject.Inject -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -230,12 +229,15 @@ class VideoPlayerViewModelImpl @Inject constructor( private fun updateProgressOnce() { val progress = player?.currentPosition ?: 0 val duration = player?.duration ?: 1 + val bufferedPercentage = (player?.bufferedPercentage?.toFloat() ?: 0f) / 100f val progressPercentage = progress.toFloat() / duration.toFloat() + mutableUiState.update { it.copy( seekerPosition = progressPercentage, durationInMs = duration, - playbackPositionInMs = progress + playbackPositionInMs = progress, + bufferedPercentage = bufferedPercentage ) } } diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt index 6964e4b..bc57ea0 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/VideoPlayerControllerUI.kt @@ -61,6 +61,7 @@ fun VideoPlayerControllerUI( isLoading: Boolean, durationInMs: Long, playbackPositionInMs: Long, + bufferedPercentage: Float, play: () -> Unit, pause: () -> Unit, prevStream: () -> Unit, @@ -158,6 +159,7 @@ fun VideoPlayerControllerUI( durationInMs = durationInMs, playbackPositionInMs = playbackPositionInMs, seekPosition = seekPosition, + bufferedPercentage = bufferedPercentage, switchToFullscreen = switchToFullscreen, switchToEmbeddedView = switchToEmbeddedView, seekPositionChanged = seekPositionChanged, @@ -203,6 +205,7 @@ fun VideoPlayerControllerUIPreviewEmbedded() { isLoading = false, durationInMs = 9*60*1000, playbackPositionInMs = 6*60*1000, + bufferedPercentage = 0.4f, play = {}, pause = {}, prevStream = {}, @@ -229,6 +232,7 @@ fun VideoPlayerControllerUIPreviewLandscape() { isLoading = true, durationInMs = 9*60*1000, playbackPositionInMs = 6*60*1000, + bufferedPercentage = 0.4f, play = {}, pause = {}, prevStream = {}, @@ -256,6 +260,7 @@ fun VideoPlayerControllerUIPreviewPortrait() { isLoading = false, durationInMs = 9*60*1000, playbackPositionInMs = 6*60*1000, + bufferedPercentage = 0.4f, play = {}, pause = {}, prevStream = {}, 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 0ed15f3..32f362b 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,7 +28,6 @@ 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.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -152,6 +151,7 @@ fun VideoPlayerUI( isLoading = uiState.isLoading, durationInMs = uiState.durationInMs, playbackPositionInMs = uiState.playbackPositionInMs, + bufferedPercentage = uiState.bufferedPercentage, play = viewModel::play, pause = viewModel::pause, prevStream = viewModel::prevStream, diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/seeker/SeekerDefaults.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/seeker/SeekerDefaults.kt index 71892b7..37c9d80 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/seeker/SeekerDefaults.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/seeker/SeekerDefaults.kt @@ -21,6 +21,7 @@ */ package net.newpipe.newplayer.ui.seeker +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable @@ -49,16 +50,16 @@ object SeekerDefaults { */ @Composable fun seekerColors( - progressColor: Color = VideoPlayerColorScheme.primary, + progressColor: Color = MaterialTheme.colorScheme.primary, trackColor: Color = TrackColor, - disabledProgressColor: Color = VideoPlayerColorScheme.onSurface.copy(alpha = DisabledProgressAlpha), + disabledProgressColor: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = DisabledProgressAlpha), disabledTrackColor: Color = disabledProgressColor .copy(alpha = DisabledTrackAlpha) - .compositeOver(VideoPlayerColorScheme.onSurface), - thumbColor: Color = VideoPlayerColorScheme.primary, - disabledThumbColor: Color = VideoPlayerColorScheme.onSurface + .compositeOver(MaterialTheme.colorScheme.onSurface), + thumbColor: Color = MaterialTheme.colorScheme.primary, + disabledThumbColor: Color = MaterialTheme.colorScheme.onSurface .copy(alpha = 0.0F) - .compositeOver(VideoPlayerColorScheme.surface), + .compositeOver(MaterialTheme.colorScheme.surface), readAheadColor: Color = ReadAheadColor ): SeekerColors = DefaultSeekerColor( progressColor = progressColor, diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt index fc7b40a..05c9264 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/theme/Color.kt @@ -58,7 +58,9 @@ val video_player_onSurface = Color(0xFFF8F8F8) // The color of the menu Icons val video_player_onSurfaceVariant = Color(0xFFF8F8F8) +// The background color of the seekbar val video_player_surfaceVariant = Color(0xFF4F4539) + val video_player_outline = Color(0xFF9C8F80) val video_player_inverseOnSurface = Color(0xFF1F1B16) val video_player_inverseSurface = Color(0xFFEAE1D9) @@ -80,6 +82,7 @@ fun VideoPlayerControllerUIPreviewEmbeddedColorPreview() { isLoading = false, durationInMs = 9*60*1000, playbackPositionInMs = 6*60*1000, + bufferedPercentage = 0.4f, play = {}, pause = {}, prevStream = {}, diff --git a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt index fb598b1..90e672d 100644 --- a/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt +++ b/new-player/src/main/java/net/newpipe/newplayer/ui/videoplayer/BottomUI.kt @@ -29,6 +29,7 @@ import androidx.compose.material.icons.filled.Fullscreen import androidx.compose.material.icons.filled.FullscreenExit import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -41,7 +42,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.core.os.ConfigurationCompat import net.newpipe.newplayer.R +import net.newpipe.newplayer.ui.seeker.DefaultSeekerColor import net.newpipe.newplayer.ui.seeker.Seeker +import net.newpipe.newplayer.ui.seeker.SeekerColors +import net.newpipe.newplayer.ui.seeker.SeekerDefaults import net.newpipe.newplayer.ui.theme.VideoPlayerTheme import java.util.Locale import kotlin.math.min @@ -53,6 +57,7 @@ fun BottomUI( seekPosition: Float, durationInMs: Long, playbackPositionInMs: Long, + bufferedPercentage: Float, switchToFullscreen: () -> Unit, switchToEmbeddedView: () -> Unit, seekPositionChanged: (Float) -> Unit, @@ -68,7 +73,9 @@ fun BottomUI( Modifier.weight(1F), value = seekPosition, onValueChange = seekPositionChanged, - onValueChangeFinished = seekingFinished + onValueChangeFinished = seekingFinished, + readAheadValue = bufferedPercentage, + colors = customizedSeekerColors() ) //Slider(value = 0.4F, onValueChange = {}, modifier = Modifier.weight(1F)) @@ -85,6 +92,20 @@ fun BottomUI( } } +@Composable +private fun customizedSeekerColors() : SeekerColors { + val colors = DefaultSeekerColor( + progressColor = MaterialTheme.colorScheme.primary, + thumbColor = MaterialTheme.colorScheme.primary, + trackColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.7f), + readAheadColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f), + disabledProgressColor = MaterialTheme.colorScheme.primary, + disabledThumbColor = MaterialTheme.colorScheme.primary, + disabledTrackColor = MaterialTheme.colorScheme.primary + ) + return colors +} + @Composable @ReadOnlyComposable fun getLocale(): Locale? { @@ -136,6 +157,7 @@ fun VideoPlayerControllerBottomUIPreview() { seekPosition = 0.4F, durationInMs = 90 * 60 * 1000, playbackPositionInMs = 3 * 60 * 1000, + bufferedPercentage = 0.4f, switchToFullscreen = { }, switchToEmbeddedView = { }, seekPositionChanged = {} diff --git a/test-app/src/main/res/values/test_streams.xml b/test-app/src/main/res/values/test_streams.xml index fde2163..5533eb9 100644 --- a/test-app/src/main/res/values/test_streams.xml +++ b/test-app/src/main/res/values/test_streams.xml @@ -22,6 +22,5 @@ https://ftp.fau.de/cdn.media.ccc.de/congress/2010/mp4-h264-HQ/27c3-4159-en-reverse_engineering_mos_6502.mp4 https://ftp.fau.de/cdn.media.ccc.de/congress/2010/ogg-audio-only/27c3-4159-en-reverse_engineering_mos_6502.ogg - https://ftp.fau.de/cdn.media.ccc.de/congress/2023/h264-hd/37c3-11929-eng-deu-swe-Turning_Chromebooks_into_regular_laptops_hd.mp4 https://videos.pexels.com/video-files/5512609/5512609-hd_1080_1920_25fps.mp4 \ No newline at end of file