Update Jetpack Compose Slider Progress based on ExoPlayer playing audio position
Asked Answered
E

1

5

I have created a custom UI for player an audio file and I am using Exoplayer to get the file and play it. I am not using the custom controller for exoplayer and my UI has a Slider that needs to update based on the current audio position. How can I achieve this? Please help.

  var currentValue by remember { mutableStateOf(0f) }
  currentValue = mediaPlayer.getCurrentPosition()
  Slider(
            modifier = Modifier.weight(1f),
            value = currentValue ,
            onValueChange = {currentValue = it },
            valueRange = 0f.. mediaPlayer.contentDuration()
        )
               
Engineer answered 14/4, 2022 at 7:42 Comment(0)
J
13

According to your code, you're expecting mediaPlayer.getCurrentPosition() to trigger recomposition somehow.

Compose can only track State object changes, which a special type created to trigger recompositions.

When you need to work with some non Compose library, you need to search for the way to track changes. In most of old libraries there're some listeners for such case.

In case of ExoPlayer there's no direct listener. In this issue you can see suggestion to use the listener to track isPlaying state. In Compose to work with listeners you can use DisposableEffect so when the view disappears you can remove the listener.

And then when it's playing - call currentPosition repeatedly with some interval. As Compose is built around Coroutines, it's pretty easy to do it with LaunchedEffect:

var currentValue by remember { mutableStateOf(0L) }
var isPlaying by remember { mutableStateOf(false) }

DisposableEffect(Unit) {
    val listener = object : Player.Listener {
        override fun onIsPlayingChanged(isPlaying_: Boolean) {
            isPlaying = isPlaying_
        }
    }
    mediaPlayer.addListener(listener)
    onDispose {
        mediaPlayer.removeListener(listener)
    }
}
if (isPlaying) {
    LaunchedEffect(Unit) {
        while(true) {
            currentValue = mediaPlayer.currentPosition
            delay(1.seconds / 30)
        }
    }
}
Juggernaut answered 14/4, 2022 at 8:15 Comment(5)
Thank you @Pylyp your response :) and useful links shared has helped me have an understanding of how to trigger recomposition of the Slider based on the ExoPlayer media event. What I can't be able to achieve now is have the Slider value change, captured and used to update(forward/rewind) the audio playing depending on where in the slider progress the user clicks/drags. Can this event be used to control the media playing?Engineer
@Engineer you need to use AndroidView update parameter, it'll be called each time your mutableStateOfs are changing - there you can call seek method (not sure how exactly it's called) using your slider valueJuggernaut
what is Player here?Amado
@MohsenMashkour it's com.google.android.exoplayer2.PlayerJuggernaut
how should i set the value of the slider to media player after changes?Amado

© 2022 - 2024 — McMap. All rights reserved.