androidandroid-jetpack-composeandroid-jetpack-compose-tv

Hook Compose Slider to MediaPlayer


I have the MediaPlayer configured inside my ViewModel. All I want is a way to observe the mediaPlayer.currentPosition in a Composable. However, I cannot find a way to store it in a MutableState<T> value for Compose to observe. I just have a simple slider:

Slider(value = someMutableStateValue, onValueChange = { someMutableStateValue = it }

In my ViewModel, I declare var someMutableStateValue by mutableStateOf(0f)

Now, this app is being built for TV so I cannot provide touch input whatsoever. I don't think it would be required anyway, but I'm informing just in case.

All I want, is a method that will update the value of someMutableStateValue every time the MediaPlayer.currentPosition changes. Maybe there is some listener, but I can't find it as of now. I'm comfortable with using LiveData too, but I'd like to avoid that if possible.

PS: I actually do not even need to pass anything to the onValueChange listener, since it would never be called on a TV.

PS MArk II: Also, I cannot find out why the Slider take up all the width of my Screen? Is it the default implementation? Even hardcoding the width or for that matter, using the fillMaxWidth(...) Modifier with a restricted fraction doesn't seem to work.


Solution

  • It appears MediaPlayer doesn't offer a callback mechanism for the playback progress. I would guess this is because technically the progress would change with every frame but running a callback on every frame would impose a lot of CPU overhead, so they just omitted it alltogether. Instead, you need to resort to polling the progress. If you want to do this on the composable side, you could use LaunchedEffect:

    var progress by remember { mutableStateOf(0f) }
    LaunchedEffect(Unit){
        while(isActive){
            progress = mediaPlayer.currentPosition / mediaPlayer.duration
            delay(200) // change this to what feels smooth without impacting performance too much
        }
    }