115 lines
2.9 KiB
Kotlin
115 lines
2.9 KiB
Kotlin
package it.vfsfitvnm.vimusic.utils
|
|
|
|
import android.os.Handler
|
|
import android.os.Looper
|
|
import androidx.compose.runtime.*
|
|
import androidx.media3.common.*
|
|
import kotlin.math.absoluteValue
|
|
|
|
@Stable
|
|
class PlayerState(private val player: Player) : Player.Listener, Runnable {
|
|
private val handler = Handler(Looper.getMainLooper())
|
|
|
|
var currentPosition by mutableStateOf(player.currentPosition)
|
|
|
|
var duration by mutableStateOf(player.duration)
|
|
private set
|
|
|
|
val progress: Float
|
|
get() = currentPosition.toFloat() / duration.absoluteValue
|
|
|
|
var playbackState by mutableStateOf(player.playbackState)
|
|
private set
|
|
|
|
var mediaItemIndex by mutableStateOf(player.currentMediaItemIndex)
|
|
private set
|
|
|
|
var mediaItem by mutableStateOf(player.currentMediaItem)
|
|
private set
|
|
|
|
var mediaMetadata by mutableStateOf(player.mediaMetadata)
|
|
private set
|
|
|
|
var playWhenReady by mutableStateOf(player.playWhenReady)
|
|
private set
|
|
|
|
var repeatMode by mutableStateOf(player.repeatMode)
|
|
private set
|
|
|
|
var error by mutableStateOf(player.playerError)
|
|
|
|
var mediaItems by mutableStateOf(player.currentTimeline.mediaItems)
|
|
private set
|
|
|
|
var volume by mutableStateOf(player.volume)
|
|
private set
|
|
|
|
override fun onVolumeChanged(volume: Float) {
|
|
this.volume = volume
|
|
}
|
|
|
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
|
this.playbackState = playbackState
|
|
}
|
|
|
|
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
|
|
this.mediaMetadata = mediaMetadata
|
|
}
|
|
|
|
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
|
|
this.playWhenReady = playWhenReady
|
|
}
|
|
|
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
|
this.mediaItem = mediaItem
|
|
mediaItemIndex = player.currentMediaItemIndex
|
|
}
|
|
|
|
override fun onRepeatModeChanged(repeatMode: Int) {
|
|
this.repeatMode = repeatMode
|
|
}
|
|
|
|
override fun onPlayerError(playbackException: PlaybackException) {
|
|
error = playbackException
|
|
}
|
|
|
|
override fun onTimelineChanged(timeline: Timeline, reason: Int) {
|
|
mediaItems = timeline.mediaItems
|
|
mediaItemIndex = player.currentMediaItemIndex
|
|
}
|
|
|
|
override fun run() {
|
|
duration = player.duration
|
|
currentPosition = player.currentPosition
|
|
handler.postDelayed(this, 500)
|
|
}
|
|
|
|
fun init() {
|
|
player.addListener(this)
|
|
handler.post(this)
|
|
}
|
|
|
|
fun dispose() {
|
|
player.removeListener(this)
|
|
handler.removeCallbacks(this)
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun rememberPlayerState(
|
|
player: Player?
|
|
): PlayerState? {
|
|
val playerState = remember(player) {
|
|
player?.let(::PlayerState)
|
|
}
|
|
|
|
playerState?.let {
|
|
DisposableEffect(Unit) {
|
|
playerState.init()
|
|
onDispose(playerState::dispose)
|
|
}
|
|
}
|
|
|
|
return playerState
|
|
}
|