Skip to navigation

Listen to playback events

Learn how to observe playback state changes, buffering, seek events, and more using the PlaybackListener interface.

All callbacks are invoked on the main thread.

Attach a playback listener

val listener = object : PlaybackListener {
override fun onPlay() {
// Playback started or resumed
}
override fun onPause() {
// Playback paused (not called for ended/idle transitions)
}
override fun onPlaybackStateChanged(isPlaying: Boolean) {
// Unified play/pause state change
}
override fun onPlayerReady(durationMs: Long) {
// Called once per media item when the player reaches READY the first time
}
override fun onTimeUpdate(currentPositionMs: Long, durationMs: Long, bufferedPositionMs: Long) {
// Periodic time updates during active playback (default ~500ms)
}
override fun onSeekStart(currentPositionMs: Long) {
// Fired when a seek begins (user scrub or programmatic seekTo)
}
override fun onSeekEnd(fromPositionMs: Long, toPositionMs: Long, durationMs: Long) {
// Fired when seek completes
}
override fun onBufferingStart() {
// Transition to buffering state
}
override fun onBufferingEnd() {
// Transition from buffering to ready
}
override fun onFirstFrameRendered() {
// First video frame is on screen (hide your poster)
}
override fun onVolumeChanged(volumeLevel: Float) {
// Device volume changed (0.0..1.0)
}
override fun onMuteStateChanged(isMuted: Boolean) {
// Mute state changed
}
override fun onPlaybackRateChanged(rate: Float) {
// Playback speed updated
}
override fun onCompleted() {
// Reached end of media (still called even if loop=true, before repeating)
}
override fun onError(error: PlaybackException) {
// Playback or validation error
}
}
player.addPlaybackListener(listener)

Callback details

  • onPlayerReady(durationMs) fires once per media item when the player reaches READY for the first time, not on every rebuffer or seek.
  • onTimeUpdate(...) fires periodically during active playback (default ~500ms) and stops automatically when paused, ended, or when no listeners remain.
  • onSeekStart / onSeekEnd trigger for both user scrubs and programmatic seekTo calls.
  • onBufferingStart / onBufferingEnd fire on buffering transitions. Use these to show or hide a loading spinner.
  • onCompleted() fires when reaching the end of media. If loop = true, this callback still fires before the video repeats.
  • onFirstFrameRendered() fires when the first video frame is on screen. Use it to hide a poster or placeholder image.

For video quality changes, the onVideoQualityChanged(quality, source) callback is covered in Switch video quality.

Remove the listener

Remove the listener when it’s no longer needed to avoid leaks:

player.removePlaybackListener(listener)

Frequently asked questions

What playback events can I listen to in the FastPix Android player?

The PlaybackListener interface delivers onPlay, onPause, onPlaybackStateChanged, onPlayerReady, onTimeUpdate, onSeekStart, onSeekEnd, onBufferingStart, onBufferingEnd, onFirstFrameRendered, onVolumeChanged, onMuteStateChanged, onPlaybackRateChanged, onCompleted, and onError.

How do I detect buffering?

Implement onBufferingStart and onBufferingEnd. They fire on buffering transitions, so use them to show a loading spinner when buffering begins and hide it when playback resumes.

How do I know when playback finished?

The onCompleted callback fires when playback reaches the end of the media. It still fires even when loop = true, called just before the video repeats.

On which thread are the callbacks invoked?

All PlaybackListener callbacks are invoked on the main thread, so you can update your UI directly from inside them without switching threads.

What’s next