Skip to content

Stateful PlayerScreen guide

This is a guide on how to use the stateful PlayerScreen with your own implementation of PlayerRepository.

Basic usage

1. Implement PlayerRepository

class PlayerRepositoryImpl : PlayerRepository {
    // implement required properties and functions
}

In the sample implementation below, the repository listens to the events of Media3's Player and update its property values accordingly (see onIsPlayingChanged). Its operations are also called on the Player (see setPlaybackSpeed).

class PlayerRepositoryImpl(
    private val player: Player
) : PlayerRepository {

    private val _currentState: MutableStateFlow<PlayerState> = MutableStateFlow(PlayerState.Idle)
    override val currentState: StateFlow<PlayerState> = _currentState

    private val listener = object : Player.Listener {

        override fun onIsPlayingChanged(isPlaying: Boolean) {
            _currentState.value = if (isPlaying) { 
                PlayerState.Playing
            } else {
                PlayerState.Ready
            }
        }
    }

    init {
        player.add(listener)
    }

    fun setPlaybackSpeed(speed: Float) { 
        player.setPlaybackSpeed(speed) 
    }
}

2. Extend PlayerViewModel

Pass your implementation of PlayerRepository as constructor parameter.

class MyCustomViewModel(
    playerRepository: PlayerRepositoryImpl
): PlayerViewModel(playerRepository) {
    // add custom implementation
}

3. Add PlayerScreen

Pass your PlayerViewModel extension as value to the constructor parameter.

PlayerScreen(playerViewModel = myCustomViewModel)

Class diagram

The following diagram shows the interactions between the classes.