Kodio 0.1.1 Help

PlayerState

PlayerState is a Compose state holder for audio playback. It tracks playback state, handles loading, and triggers recomposition when the player state changes.

Basic usage

Create a play button that reacts to state changes:

@Composable fun AudioPlayer(recording: AudioRecording) { val playerState = rememberPlayerState(recording) Button( onClick = { playerState.toggle() }, enabled = playerState.isReady ) { Text( when { playerState.isPlaying -> "⏸ Pause" playerState.isFinished -> "🔄 Replay" else -> "▶️ Play" } ) } }

Load dynamically

Load recordings after the composable is created:

@Composable fun DynamicPlayer() { val playerState = rememberPlayerState() var recording by remember { mutableStateOf<AudioRecording?>(null) } // Load when recording changes LaunchedEffect(recording) { recording?.let { playerState.load(it) } } Column { // Some UI to select/create a recording... Button( onClick = { playerState.toggle() }, enabled = playerState.isReady ) { Text(if (playerState.isPlaying) "Pause" else "Play") } } }

Record then play

Common pattern: record audio, then immediately enable playback:

@Composable fun RecordAndPlay() { val recorderState = rememberRecorderState() val playerState = rememberPlayerState() // Auto-load recording into player LaunchedEffect(recorderState.recording) { recorderState.recording?.let { playerState.load(it) } } Column { // Record button Button(onClick = { recorderState.toggle() }) { Text(if (recorderState.isRecording) "⏹ Stop" else "🎙 Record") } // Play button (only when recording available) if (recorderState.hasRecording) { Button( onClick = { playerState.toggle() }, enabled = playerState.isReady ) { Text(if (playerState.isPlaying) "⏸ Pause" else "▶️ Play") } } } }

Error handling

Handle playback errors:

playerState.error?.let { error -> AlertDialog( onDismissRequest = { playerState.clearError() }, title = { Text("Playback Error") }, text = { Text(error.message ?: "Unable to play audio") }, confirmButton = { TextButton(onClick = { playerState.clearError() }) { Text("OK") } } ) }

Complete example

A full playback UI with state indicators:

@Composable fun CompletePlayer(recording: AudioRecording) { val playerState = rememberPlayerState(recording) Column( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { // Status indicator Text( text = when { !playerState.isReady -> "⏳ Loading..." playerState.isPlaying -> "🔊 Playing" playerState.isPaused -> "⏸️ Paused" playerState.isFinished -> "✅ Finished" else -> "⏹️ Ready" }, style = MaterialTheme.typography.bodyLarge ) Spacer(Modifier.height(16.dp)) // Control buttons Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { // Play/Pause Button( onClick = { playerState.toggle() }, enabled = playerState.isReady ) { Text(if (playerState.isPlaying) "⏸" else "▶️") } // Stop Button( onClick = { playerState.stop() }, enabled = playerState.isPlaying || playerState.isPaused ) { Text("⏹") } } // Error display playerState.error?.let { error -> Spacer(Modifier.height(8.dp)) Text( text = "⚠️ ${error.message}", color = MaterialTheme.colorScheme.error ) } } }

API reference

Properties

isPlaying: Boolean

Currently playing audio.

isPaused: Boolean

Playback is paused (can resume).

isReady: Boolean

Audio is loaded and ready to play.

isFinished: Boolean

Playback has completed.

recording: AudioRecording?

The currently loaded recording.

error: AudioError?

Current error, if any.

Methods

load(recording)

Load an AudioRecording for playback.

play()

Start or resume playback.

pause()

Pause playback.

stop()

Stop playback and reset to beginning.

toggle()

Play if stopped/paused, pause if playing.

clearError()

Clear the current error state.

Last modified: 13 January 2026