Fix media seeking flicker (#6434)
This commit is contained in:
@@ -121,6 +121,7 @@ private fun ExoPlayerMediaAudioView(
|
||||
durationInMillis = 0,
|
||||
canMute = false,
|
||||
isMuted = false,
|
||||
seekingToMillis = null,
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -171,15 +172,21 @@ private fun ExoPlayerMediaAudioView(
|
||||
LaunchedEffect(exoPlayer.isPlaying) {
|
||||
if (exoPlayer.isPlaying) {
|
||||
while (true) {
|
||||
val position = exoPlayer.currentPosition
|
||||
val seekingTo = mediaPlayerControllerState.seekingToMillis
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
progressInMillis = exoPlayer.currentPosition,
|
||||
progressInMillis = position,
|
||||
seekingToMillis = if (seekingTo != null && position >= seekingTo) null else seekingTo,
|
||||
)
|
||||
delay(200)
|
||||
}
|
||||
} else {
|
||||
// Ensure we render the final state
|
||||
val position = exoPlayer.currentPosition
|
||||
val seekingTo = mediaPlayerControllerState.seekingToMillis
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
progressInMillis = exoPlayer.currentPosition,
|
||||
progressInMillis = position,
|
||||
seekingToMillis = if (seekingTo != null && position >= seekingTo) null else seekingTo,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -294,6 +301,9 @@ private fun ExoPlayerMediaAudioView(
|
||||
exoPlayer.togglePlay()
|
||||
},
|
||||
onSeekChange = {
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
seekingToMillis = it.toLong(),
|
||||
)
|
||||
exoPlayer.seekToEnsurePlaying(it.toLong())
|
||||
},
|
||||
onToggleMute = {
|
||||
|
||||
@@ -18,7 +18,16 @@ data class MediaPlayerControllerState(
|
||||
val durationInMillis: Long,
|
||||
val canMute: Boolean,
|
||||
val isMuted: Boolean,
|
||||
val seekingToMillis: Long?,
|
||||
) {
|
||||
/**
|
||||
* The progress in milliseconds to display. When [seekingToMillis] is non-null (during a seek operation),
|
||||
* this returns the target seek position. Once the player catches up to the seek position,
|
||||
* [seekingToMillis] is cleared (set to null) and this returns [progressInMillis] again.
|
||||
*/
|
||||
val displayProgressInMillis: Long
|
||||
get() = seekingToMillis ?: progressInMillis
|
||||
|
||||
@FloatRange(from = 0.0, to = 1.0)
|
||||
val progressAsFloat = (progressInMillis.toFloat() / durationInMillis.toFloat()).coerceIn(0f, 1f)
|
||||
val progressAsFloat = (displayProgressInMillis.toFloat() / durationInMillis.toFloat()).coerceIn(0f, 1f)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ private fun aMediaPlayerControllerState(
|
||||
durationInMillis: Long = 83_000,
|
||||
canMute: Boolean = true,
|
||||
isMuted: Boolean = false,
|
||||
seekingToMillis: Long? = null,
|
||||
) = MediaPlayerControllerState(
|
||||
isVisible = isVisible,
|
||||
isPlaying = isPlaying,
|
||||
@@ -42,4 +43,5 @@ private fun aMediaPlayerControllerState(
|
||||
durationInMillis = durationInMillis,
|
||||
canMute = canMute,
|
||||
isMuted = isMuted,
|
||||
seekingToMillis = seekingToMillis,
|
||||
)
|
||||
|
||||
@@ -126,7 +126,7 @@ fun MediaPlayerControllerView(
|
||||
modifier = Modifier
|
||||
.widthIn(min = 48.dp)
|
||||
.padding(horizontal = 8.dp),
|
||||
text = state.progressInMillis.toHumanReadableDuration(),
|
||||
text = state.displayProgressInMillis.toHumanReadableDuration(),
|
||||
textAlign = TextAlign.Center,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
style = ElementTheme.typography.fontBodyXsMedium,
|
||||
@@ -135,7 +135,9 @@ fun MediaPlayerControllerView(
|
||||
Slider(
|
||||
modifier = Modifier.weight(1f),
|
||||
valueRange = 0f..state.durationInMillis.toFloat(),
|
||||
value = lastSelectedValue.takeIf { it >= 0 } ?: state.progressInMillis.toFloat(),
|
||||
value = lastSelectedValue.takeIf { it >= 0 }
|
||||
?: state.seekingToMillis?.toFloat()
|
||||
?: state.progressInMillis.toFloat(),
|
||||
onValueChange = {
|
||||
lastSelectedValue = it
|
||||
},
|
||||
|
||||
@@ -108,6 +108,7 @@ private fun ExoPlayerMediaVideoView(
|
||||
durationInMillis = 0,
|
||||
canMute = true,
|
||||
isMuted = false,
|
||||
seekingToMillis = null,
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -225,6 +226,9 @@ private fun ExoPlayerMediaVideoView(
|
||||
},
|
||||
onSeekChange = {
|
||||
autoHideController++
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
seekingToMillis = it.toLong(),
|
||||
)
|
||||
exoPlayer.seekToEnsurePlaying(it.toLong())
|
||||
},
|
||||
onToggleMute = {
|
||||
@@ -242,15 +246,21 @@ private fun ExoPlayerMediaVideoView(
|
||||
LaunchedEffect(exoPlayer.isPlaying) {
|
||||
if (exoPlayer.isPlaying) {
|
||||
while (true) {
|
||||
val position = exoPlayer.currentPosition
|
||||
val seekingTo = mediaPlayerControllerState.seekingToMillis
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
progressInMillis = exoPlayer.currentPosition,
|
||||
progressInMillis = position,
|
||||
seekingToMillis = if (seekingTo != null && position >= seekingTo) null else seekingTo,
|
||||
)
|
||||
delay(200)
|
||||
}
|
||||
} else {
|
||||
// Ensure we render the final state
|
||||
val position = exoPlayer.currentPosition
|
||||
val seekingTo = mediaPlayerControllerState.seekingToMillis
|
||||
mediaPlayerControllerState = mediaPlayerControllerState.copy(
|
||||
progressInMillis = exoPlayer.currentPosition,
|
||||
progressInMillis = position,
|
||||
seekingToMillis = if (seekingTo != null && position >= seekingTo) null else seekingTo,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user