Files
Android-247-Radio/app/src/main/java/xyz/cottongin/radio247/service/RadioPlayerAdapter.kt

123 lines
3.9 KiB
Kotlin
Raw Normal View History

package xyz.cottongin.radio247.service
import android.os.Looper
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player
import androidx.media3.common.SimpleBasePlayer
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import xyz.cottongin.radio247.audio.IcyMetadata
import xyz.cottongin.radio247.data.model.Station
class RadioPlayerAdapter(
private val onPlay: () -> Unit,
private val onStop: () -> Unit,
) : SimpleBasePlayer(Looper.getMainLooper()) {
@Volatile
private var _playbackState: Int = Player.STATE_IDLE
@Volatile
private var _playWhenReady: Boolean = false
@Volatile
private var _mediaMetadata: MediaMetadata = MediaMetadata.EMPTY
@Volatile
private var _currentMediaItem: MediaItem? = null
private val commands = Player.Commands.Builder()
.add(Player.COMMAND_PLAY_PAUSE)
.add(Player.COMMAND_STOP)
.add(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)
.add(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)
.build()
override fun getState(): SimpleBasePlayer.State {
val mediaItem = _currentMediaItem
val playlist = if (mediaItem != null) {
listOf(getPlaceholderMediaItemData(mediaItem))
} else {
emptyList()
}
return SimpleBasePlayer.State.Builder()
.setAvailableCommands(commands)
.setPlaybackState(_playbackState)
.setPlayWhenReady(_playWhenReady, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
.setCurrentMediaItemIndex(if (mediaItem != null) 0 else 0)
.setContentPositionMs(0L)
.setIsLoading(false)
.setPlaylist(playlist)
.build()
}
override fun handleSetPlayWhenReady(playWhenReady: Boolean): ListenableFuture<*> {
_playWhenReady = playWhenReady
if (playWhenReady) {
onPlay()
} else {
onStop()
}
return Futures.immediateVoidFuture()
}
override fun handleStop(): ListenableFuture<*> {
_playWhenReady = false
onStop()
return Futures.immediateVoidFuture()
}
fun updatePlaybackState(state: PlaybackState) {
val (newPlayerState, newPlayWhenReady) = when (state) {
is PlaybackState.Idle -> Player.STATE_IDLE to false
is PlaybackState.Connecting -> Player.STATE_BUFFERING to true
is PlaybackState.Playing -> Player.STATE_READY to true
is PlaybackState.Paused -> Player.STATE_READY to false
is PlaybackState.Reconnecting -> Player.STATE_BUFFERING to true
}
_playbackState = newPlayerState
_playWhenReady = newPlayWhenReady
invalidateState()
}
fun updateStation(station: Station) {
_currentMediaItem = MediaItem.Builder()
.setMediaId("station:${station.id}")
.setMediaMetadata(
MediaMetadata.Builder()
.setTitle(station.name)
.setIsPlayable(true)
.build()
)
.build()
invalidateState()
}
fun updateMetadata(
station: Station,
metadata: IcyMetadata?,
artworkUri: android.net.Uri? = null
) {
_mediaMetadata = MediaMetadata.Builder()
.setStation(station.name)
.setTitle(metadata?.title ?: station.name)
.setArtist(metadata?.artist)
.setArtworkUri(artworkUri)
.setIsPlayable(true)
.build()
_currentMediaItem = MediaItem.Builder()
.setMediaId(_currentMediaItem?.mediaId ?: "station:${station.id}")
.setMediaMetadata(_mediaMetadata)
.build()
invalidateState()
}
fun clearState() {
_currentMediaItem = null
_mediaMetadata = MediaMetadata.EMPTY
_playbackState = Player.STATE_IDLE
_playWhenReady = false
}
}