PlayerEvent

sealed interface PlayerEvent

Something that happened, as opposed to something that is.

The engine's session core emits these and KitePlayer.events carries them. The division of labour between this and PlayerSnapshot is strict, and it is the fix for the single most common mistake made against player APIs.

  • State goes in the snapshot. A snapshot conflates: a consumer that misses an intermediate value still ends up correct, because the latest value is the truth.

  • Occurrences go here, and only when missing one is harmless or when the occurrence itself is the information. Nothing a consumer must count is delivered as an event. Counters live in PlaybackStats instead, because a consumer can diff two snapshots and cannot recover a lost event.

libmpv publishes everything as events, coalesces them, and documents that one change event does not mean one change. Clients then write incremental logic that is subtly wrong and only fails on slow machines. This split makes that impossible to express.

Inheritors

Types

Link copied to clipboard
data class AudioFormatChanged(val sampleRate: Int, val channels: Int) : PlayerEvent

The audio output format changed, at the start or after a device change.

Link copied to clipboard
data class ChapterChanged(val chapter: Chapter?) : PlayerEvent

A chapter boundary was crossed.

Link copied to clipboard
data object Ended : PlayerEvent

Playback reached the end. Emitted once, before the status becomes Ended.

Link copied to clipboard
data class Failed(val error: PlaybackError) : PlayerEvent

Playback stopped. The same error is on the snapshot.

Link copied to clipboard
data class FirstFrameRendered(val latency: Duration) : PlayerEvent

The first frame of this media item left the schedule. latency is measured from the open.

Link copied to clipboard
data class FramePresented(val pts: Pts, val atNanos: Long, val latency: Duration, val exact: Boolean) : PlayerEvent

A frame was presented. Emitted per frame only when PlayerConfig.frameEvents is on.

Link copied to clipboard
data class MarkerReached(val marker: Marker) : PlayerEvent

Playback crossed marker while advancing.

Link copied to clipboard
data class Opened(val media: MediaItem, val tracks: Tracks) : PlayerEvent

Loading finished and the first frame is ready. Carries the media that opened.

Link copied to clipboard
data class SeekCompleted(val generation: Generation, val landedAt: Duration) : PlayerEvent

A seek finished and the target frame is ready. generation identifies which seek, so a consumer that issued several can tell which one completed.

Link copied to clipboard
data class TrackChosenByPlayer(val kind: TrackKind, val track: TrackId?) : PlayerEvent

The player changed which track of kind plays, on its own rather than because a caller asked; track is the one that plays now, or null for none.

Link copied to clipboard
data class TracksAdded(val tracks: List<TrackInfo>) : PlayerEvent

The media gained tracks after it opened, and they are in the snapshot's tracks from now on (#509).

Link copied to clipboard
data class VideoSizeChanged(val size: VideoSize) : PlayerEvent

The video's size or pixel aspect changed, at the start or mid-stream. size is the picture as it is shown, after any crop its container states. See PictureCrop.

Link copied to clipboard
data class Warning(val warning: PlaybackWarning) : PlayerEvent

Something degraded and playback continued.