Package-level declarations

Types

Link copied to clipboard

The two tiers of the animation upscaler: a port of Anime4K v3.2's CNN x2 networks, by bloc97, under the MIT licence.

Link copied to clipboard

One coherent reading of the selected audio output's presentation clock.

Link copied to clipboard
data class AudioConfig(val preferredLanguages: List<String> = emptyList(), val preservePitch: Boolean = true, val downmix: DownmixConfig = DownmixConfig(), val volumeCeiling: Float = 1.0f, val equalizer: EqualizerSettings = EqualizerSettings.Flat, val replayGain: ReplayGainMode = ReplayGainMode.Off, val replayGainPreampDb: Float = 0.0f, val replayGainFallbackDb: Float = 0.0f, val resampler: AudioResamplerFactory? = null, val upmix: UpmixMode = UpmixMode.Off, val matchOutputChannels: Boolean = false)

How the player handles sound: which track to pick, the pitch law, the downmix, the volume ceiling, the equaliser, ReplayGain and the resampler. A fresh player starts from these values, and the setters on KitePlayer change most of them while it plays.

Link copied to clipboard
class AudioConfigBuilder(from: AudioConfig = AudioConfig())

The fields of an AudioConfig, set in an audio { } block. Each one is the field of that name.

Link copied to clipboard

What an item's sound is, as the platform's own sound processing wants to know it (#446).

Link copied to clipboard
data class AudioOutputDevice(val id: String, val name: String, val isDefault: Boolean)

An audio output device that a player can play through.

Link copied to clipboard
class AudioPlayback(sink: AudioSink, clock: MonotonicClock = MonotonicClock.System, bufferDuration: Duration = 200.milliseconds, onWarning: (PlaybackWarning) -> Unit = {}, downmix: DownmixConfig = DownmixConfig(), resampler: AudioResamplerFactory? = null, upmix: UpmixMode = UpmixMode.Off) : AutoCloseable

The engine's audio half: a device, a ring, and the clock derived from them.

Link copied to clipboard
class AudioScanRange(val from: Pts? = null, val until: Pts? = null)

A stretch of one audio track to scan, in the stream's own timeline.

Link copied to clipboard

What one scanAudio call covered.

Link copied to clipboard
fun interface AudioScanSink

Receives the decoded audio of scanAudio, one block at a time, in media order.

Link copied to clipboard
interface AudioTap

Sees every block of decoded audio on its way to the speaker.

Link copied to clipboard
data class Backends(val backend: MediaBackend? = null, val output: OutputBackend? = null)

The two implementations the engine builds its pipeline from.

Link copied to clipboard
data class BufferPolicy(val readyDuration: Duration = 1.seconds, val readyPackets: Int = 25, val softTarget: Duration = 5.seconds, val totalBytes: Long = 32L * 1024 * 1024, val totalDuration: Duration = 30.seconds, val videoFrameQueue: Int = 4, val stallTimeout: Duration = 30.seconds)

How much to read ahead, when to declare that playback can start, and how long to wait for a source that stopped answering.

Link copied to clipboard
class BufferPolicyBuilder(from: BufferPolicy = BufferPolicy())

The fields of a BufferPolicy, set in a buffer { } block. Each one is the field of that name.

Link copied to clipboard

A screenshot: the newest presented frame, plane-copied at the moment of presentation, owned outright by the caller. This is the documented use of SoftwareReadableFrame: every plane here is a copy taken before the renderer took ownership, so nothing the decoder or the renderer does afterwards can touch it, and close has nothing to release.

Link copied to clipboard
data class Chapter(val index: Int, val start: Duration, val end: Duration?, val title: String?)

One chapter of the current media item, read from the container's own table and surfaced on the facade with io.github.yuroyami.kiteplayer.KitePlayer.chapterAt, seekToChapter and PlayerEvent.ChapterChanged.

Link copied to clipboard

One trace event as one line of JSON, in the Chrome trace event format that Chrome's trace viewer and Perfetto open.

Link copied to clipboard

What the demuxer does with a packet that the container marks as damaged.

Link copied to clipboard
class CoverArt(val bytes: ByteArray, val mimeType: String?)

An item's own cover picture, as its file carries it (#425): the album art of an MP3, an M4A or a FLAC, still encoded, so the one picture serves a lock screen, a notification and an application's own view at whatever size each draws it.

Link copied to clipboard

Whether interlaced video is deinterlaced, which removes the combing that DVD rips and broadcast captures otherwise show on every moving edge.

Link copied to clipboard
data class DemuxPolicy(val probe: ProbeDepth = ProbeDepth.Default, val corruptPackets: CorruptPackets = CorruptPackets.Keep, val generateTimestamps: Boolean = false, val lowLatency: Boolean = false, val skipInitialBytes: Long = 0, val maxBitrate: Long? = null, val maxVideoHeight: Int? = null, val variant: Int? = null, val program: Int? = null, val fit: VariantFit? = null)

Typed settings for opening a container. The backend applies every field, or refuses the open with a typed error. It never ignores one. Each default is the backend's own default, so DemuxPolicy() changes nothing.

Link copied to clipboard
data class DolbyVisionInfo(val profile: Int, val level: Int, val baseLayerCompatibility: Int, val hasEnhancementLayer: Boolean = false)

What a Dolby Vision video stream is, as its container declares it.

Link copied to clipboard
data class DownmixConfig(val normalize: Boolean = false, val includeLfe: Boolean = false)

How a multichannel mix is folded into fewer speakers.

Link copied to clipboard
data class EqualizerSettings(val gainsDb: List<Float> = List(10) { 0f }, val preampDb: Float = 0.0f)

A ten-band graphic equaliser, in dB per band.

Link copied to clipboard
fun interface ExternalClock

A clock the caller owns, which playback follows once it is set with KitePlayer.setExternalClock. Synchronised playback across devices is the use: each player follows the position that its group agreed on.

Link copied to clipboard
data class ExternalClockPolicy(val maxTrim: Double = 0.005)

How playback follows an ExternalClock.

Link copied to clipboard
data class FileGrowth(val endsAfter: Duration = 2.seconds)

How a MediaItem whose file is still being written is played (#430).

Link copied to clipboard
Link copied to clipboard
value class Generation(val value: Long) : Comparable<Generation>

The epoch a piece of state belongs to, within the timeline that produced it.

Link copied to clipboard

How HDR video, with a PQ or HLG transfer, reaches the screen.

Link copied to clipboard

What SubtitleConfig.hearingImpairedNotes does with the notes of hearing-impaired subtitles (#493).

Link copied to clipboard

A hardware decoding API.

Link copied to clipboard
sealed class HwdecPolicy

Whether to decode on a hardware device, and what to do when one is not available.

Link copied to clipboard
sealed class HwdecStatus

How the current video track is being decoded.

Link copied to clipboard
data class IoCachePolicy(val enabled: Boolean = true, val readChunkBytes: Int = 256 * 1024, val backWindowBytes: Long = 8L * 1024 * 1024, val forwardWindowBytes: Long = 32L * 1024 * 1024)

The byte cache: one contiguous RAM window over an MediaIo's bytes. Reads pull readChunkBytes at a time and append to the window; a seek that lands inside the window is served from RAM without touching the source, which is what makes a small seek-back free on a network stream. The window keeps at least backWindowBytes behind the cursor before anything is evicted, and forwardWindowBytes in total; Progress.bufferedRanges reports the window, time-mapped.

Link copied to clipboard
class IoCachePolicyBuilder(from: IoCachePolicy = IoCachePolicy())

The fields of an IoCachePolicy, set in an ioCache { } block. Each one is the field of that name.

Link copied to clipboard

Which keyframe a SeekMode.Keyframe seek lands on, since it does not decode forward to the exact target.

Link copied to clipboard
object KiteLog

The logging policy, as a contract rather than a framework.

Link copied to clipboard

The player.

Link copied to clipboard
@RequiresOptIn(level = RequiresOptIn.Level.ERROR, message = "Raw FFmpeg syntax: parsed by the backend rather than by this library, and meaningless to a non-FFmpeg backend. Opt in with @OptIn(KitePlayerLowLevelApi::class) when you have decided to depend on FFmpeg specifically.")
annotation class KitePlayerLowLevelApi

Marks API that hands FFmpeg's own strings straight through to a backend.

Link copied to clipboard
object KiteTrace

The trace seam: a timeline of what the player did, for a profiler to draw.

Link copied to clipboard

The evidence behind a sink's audio presentation timing.

Link copied to clipboard
Link copied to clipboard
data class Marker(val position: Duration, val id: String)

A position playback announces when it crosses it. Set with io.github.yuroyami.kiteplayer.KitePlayer.setMarkers, announced as PlayerEvent.MarkerReached. id is the application's own name for it and means nothing to the engine.

Link copied to clipboard

Which clock is actually in charge right now, as opposed to which was requested.

Link copied to clipboard

The subtitles SubtitleConfig.withMatchingAudio lets the player choose by itself under audio in a preferred subtitle language (#506). Audio in any other language, or in none it names, is subtitled as ever.

Link copied to clipboard
data class MediaClip(val start: Duration = Duration.ZERO, val end: Duration? = null)

The part of a file a MediaItem plays, from start to end (#456). Both are positions of the whole file, as the item would report them with no clip.

Link copied to clipboard
data class MediaInspection(val duration: Duration?, val tracks: Tracks, val metadata: Map<String, String>, val chapters: List<Chapter>, val seekable: Boolean, val containerBitrateBps: Long? = null)

What a file says about itself, read without playing it.

Link copied to clipboard

Reads media bytes from anywhere Kotlin can reach.

Link copied to clipboard
fun interface MediaIoFactory

Makes a fresh MediaIo for one playback session.

Link copied to clipboard
fun interface MediaIoResolver

Turns a URI into a MediaIo when it knows how, at open time (the Ktor half). Explicitly configured through PlayerConfig.network or supplied by an installed optional provider. The engine consults it when a MediaItem has no MediaItem.io of its own. Returning null from an explicit resolver passes the URI through to the backend untouched, which is what keeps local files on FFmpeg's own fast path.

Link copied to clipboard
data class MediaItem(val uri: String, val headers: Map<String, String> = emptyMap(), val externalSubtitles: List<SubtitleSource> = emptyList(), val videoFilter: String? = null, val startPosition: Duration? = null, val io: MediaIoFactory? = null, val formatHint: String? = null, val openOptions: Map<String, String> = emptyMap(), val demux: DemuxPolicy = DemuxPolicy(), val title: String? = null, val artist: String? = null, val album: String? = null, val audioFilter: String? = null, val audioContent: AudioContent = AudioContent.Automatic, val clip: MediaClip? = null, val growth: FileGrowth? = null, val thumbnails: ThumbnailSource? = null)

What to play.

Link copied to clipboard

Builds a MediaItem one setting at a time. Each call has the name of the field it sets, every call is optional, and each returns this builder.

Link copied to clipboard
data class MediaProgram(val number: Int, val tracks: List<TrackId>, val name: String? = null, val provider: String? = null, val metadata: Map<String, String> = emptyMap())

One programme of the media: tracks that play together, such as one channel of a DVB recording or an IPTV multiplex, which carries several channels in one transport stream (#505).

Link copied to clipboard
interface MonotonicClock

The source of wall time for the engine.

Link copied to clipboard
data class NetworkConfig(val ioResolver: MediaIoResolver? = null, val ioCache: IoCachePolicy = IoCachePolicy(), val autoResolve: Boolean = true)

How media bytes arrive over a network, and how the engine caches them.

Link copied to clipboard
class NetworkConfigBuilder(from: NetworkConfig = NetworkConfig())

The fields of a NetworkConfig, set in a network { } block. Each one is the field of that name.

Link copied to clipboard
data class PictureCrop(val top: Int = 0, val bottom: Int = 0, val left: Int = 0, val right: Int = 0)

Rows and columns at the edges of a stored picture that are not part of the image (#497).

Link copied to clipboard
data class PictureOrientation(val rotationDegrees: Int, val mirrored: Boolean)

How a picture is drawn (#428): mirrored left to right first when mirrored, then turned clockwise by rotationDegrees, 0, 90, 180 or 270, as VideoFrame.mirrored and VideoFrame.rotationDegrees describe a frame's own. See VideoTransform.orient.

Link copied to clipboard
class PipedMediaIo(capacityChunks: Int = 16) : MediaIo

A bounded pipe for bytes that arrive by push: a socket you read yourself, a decryptor, or a download in flight. Your code calls write, then finish or fail. The engine reads.

Link copied to clipboard
sealed class PlaybackError

A failure that stopped playback.

Link copied to clipboard

What a suspending player command throws when playback failed.

Link copied to clipboard

A playback preset as data: one named intent compiled into the two places configuration actually goes, the PlayerConfig this player reads and the decoder option strings a backend passes to its decoders.

Link copied to clipboard
data class PlaybackStats(val decodedVideoFrames: Long = 0, val submittedFrames: Long = 0, val headlessFrames: Long = 0, val droppedFramesLate: Long = 0, val refusedFrames: Long = 0, val droppedFramesDecode: Long = 0, val repeatedFrames: Long = 0, val audioUnderruns: Long = 0, val rebuffers: Long = 0, val droppedEvents: Long = 0, val avDrift: Duration = ZERO, val videoDecodeFps: Double = 0.0, val videoQueueDepth: Duration = ZERO, val audioQueueDepth: Duration = ZERO, val audioLatency: Duration = ZERO, val audioLatencyQuality: LatencyQuality = LatencyQuality.Unreliable, val hardwareDecode: HwdecStatus = HwdecStatus.Software, val ioBytesTotal: Long = 0, val ioBytesPerSecond: Long = 0, val decodeTimeP50: Duration = ZERO, val decodeTimeP95: Duration = ZERO, val presentLatenessP95: Duration = ZERO, val containerBitrate: Long? = null, val syncMode: SyncMode = SyncMode.Auto, val masterClock: MasterClock = MasterClock.None, val audioLimitedFrames: Long = 0)

Diagnostics, for an overlay or a bug report.

Link copied to clipboard

What the player is doing.

Link copied to clipboard
sealed class PlaybackWarning

Something went wrong and playback continued.

Link copied to clipboard
data class PlayerConfig(val renderQuality: RenderQuality = RenderQuality.Off, val syncMode: SyncMode = SyncMode.Auto, val hardwareDecode: HwdecPolicy = HwdecPolicy.Auto, val frameDrop: FrameDropPolicy = FrameDropPolicy.LateOnly, val buffer: BufferPolicy = BufferPolicy(), val audio: AudioConfig = AudioConfig(), val subtitles: SubtitleConfig = SubtitleConfig(), val progressInterval: Duration = 200.milliseconds, val statsInterval: Duration = 1.seconds, val frameEvents: Boolean = false, val backends: Backends = Backends(), val network: NetworkConfig = NetworkConfig(), val videoEnabled: Boolean = true, val deinterlace: DeinterlacePolicy = DeinterlacePolicy.Auto, val queue: QueueConfig = QueueConfig(), val hdrPolicy: HdrPolicy = HdrPolicy.Auto, val externalClock: ExternalClockPolicy = ExternalClockPolicy(), val keyframeChoice: KeyframeChoice = KeyframeChoice.Before)

Everything that is decided when the player is created.

Link copied to clipboard
class PlayerConfigBuilder(from: PlayerConfig = PlayerConfig())

The fields of a PlayerConfig, set in a PlayerConfig { } block. Each one is the field of that name.

Link copied to clipboard
annotation class PlayerConfigDsl

Keeps a block of one config builder from setting the fields of the builder around it.

Link copied to clipboard
sealed interface PlayerEvent

Something that happened, as opposed to something that is.

Link copied to clipboard
data class PlayerMemento(val queue: List<MediaItem>, val queueIndex: Int, val position: Duration, val speed: Double, val preservePitch: Boolean, val volume: Float, val muted: Boolean, val loop: LoopMode, val shuffle: Boolean, val subtitleDelay: Duration, val audioDelay: Duration, val audioLanguage: String?, val subtitleLanguage: String?, val subtitlesOff: Boolean, val secondarySubtitleLanguage: String? = null, val balance: Float = 0.0f, val equalizer: EqualizerSettings = EqualizerSettings.Flat, val subtitleScale: Float = 1.0f, val subtitlePosition: Float = 1.0f, val forcedPicturesOnly: Boolean = false, val subtitleStyle: SubtitleStyleOverride? = null, val videoScale: VideoScale = VideoScale.Fit, val videoTransform: VideoTransform = VideoTransform.Identity, val videoAdjustments: VideoAdjustments = VideoAdjustments.Identity, val renderQuality: RenderQuality = RenderQuality.Off, val videoEnabled: Boolean = true, val queueOrder: List<Int> = emptyList(), val hdrPolicy: HdrPolicy = HdrPolicy.Auto, val stereoMode: StereoMode = StereoMode.Stereo, val nightMode: Boolean = false, val dialogueLevelDb: Float = 0.0f, val pitchSemitones: Double = 0.0, val skipSilence: Boolean = false)

Everything needed to come back to where playback was: the queue, the item, the position and every setting. Taken with KitePlayer.memento, handed back to KitePlayer.restore. A value the application stores however it likes; no serialisation is imposed. asProperties is a flat string form for applications that keep key-value text, and fromProperties reads it back.

Link copied to clipboard
data class PlayerSnapshot(val status: PlaybackStatus = PlaybackStatus.Idle, val media: MediaItem? = null, val duration: Duration? = null, val seekable: Boolean = false, val videoSize: VideoSize? = null, val tracks: Tracks = Tracks.Empty, val chapters: List<Chapter> = emptyList(), val markers: List<Marker> = emptyList(), val metadata: Map<String, String> = emptyMap(), val speed: Double = 1.0, val volume: Float = 1.0f, val muted: Boolean = false, val loop: LoopMode = LoopMode.Off, val videoScale: VideoScale = VideoScale.Fit, val videoAdjustments: VideoAdjustments = VideoAdjustments.Identity, val renderQuality: RenderQuality = RenderQuality.Off, val videoTransform: VideoTransform = VideoTransform.Identity, val subtitleDelay: Duration = Duration.ZERO, val subtitleScale: Float = 1.0f, val subtitleStyle: SubtitleStyleOverride? = null, val subtitlePosition: Float = 1.0f, val forcedPicturesOnly: Boolean = false, val subtitleTypesetter: String? = null, val audioDelay: Duration = Duration.ZERO, val abLoopA: Duration? = null, val abLoopB: Duration? = null, val preservePitch: Boolean = true, val error: PlaybackError? = null, val generation: Generation = Generation.Initial, val queue: List<MediaItem> = emptyList(), val queueIndex: Int = -1, val audioSessionId: Int? = null, val appliedReplayGainDb: Float? = null, val balance: Float = 0.0f, val videoEnabled: Boolean = true, val sleepTimer: SleepTimer? = null, val equalizer: EqualizerSettings = EqualizerSettings.Flat, val shuffle: Boolean = false, val queueOrder: List<Int> = emptyList(), val failedQueueItems: Set<Int> = emptySet(), val playRequested: Boolean = false, val preloadedIndex: Int? = null, val hdrPolicy: HdrPolicy = HdrPolicy.Auto, val videoDynamicRange: VideoDynamicRange = VideoDynamicRange.Standard, val durationIsEstimate: Boolean = false, val stereoMode: StereoMode = StereoMode.Stereo, val lyrics: String? = null, val nightMode: Boolean = false, val dialogueLevelDb: Float = 0.0f, val pitchSemitones: Double = 0.0, val skipSilence: Boolean = false)

Everything about the player that changes rarely, as one immutable value.

Link copied to clipboard
class PlaylistException(message: String, val uri: String) : Exception

A playlist that cannot become a queue: one that cannot be read, that is no playlist, that names nothing, or that names itself, directly or through a list it names. uri is the list's address.

Link copied to clipboard
object Playlists

Playlist files read into queue items (#490): the M3U lists people keep their music in and other players export, PLS lists, XSPF lists, and cue sheets.

Link copied to clipboard
sealed interface ProbeDepth

How far the demuxer reads into a container before playback starts, to find its streams.

Link copied to clipboard
data class Progress(val position: Duration = ZERO, val bufferedAhead: Duration = ZERO, val bufferedRanges: List<ClosedRange<Duration>> = emptyList())

Position and buffered extent, sampled on a timer.

Link copied to clipboard
value class Pts(val micros: Long) : Comparable<Pts>

A presentation timestamp on the media timeline, in microseconds.

Link copied to clipboard
data class QueueConfig(val preloadNext: Duration = 5.seconds, val gapless: Boolean = true, val reshuffleEachLap: Boolean = false, val onItemFailure: QueueItemFailure = QueueItemFailure.Stop)

How the player moves from one queue item to the next. See docs/gapless-queue.md.

Link copied to clipboard
class QueueConfigBuilder(from: QueueConfig = QueueConfig())

The fields of a QueueConfig, set in a queue { } block. Each one is the field of that name.

Link copied to clipboard

What a queue does with an item that cannot be opened. See QueueConfig.onItemFailure.

Link copied to clipboard
data class RenderQuality(val dither: Boolean = false, val deband: Boolean = false, val debandThreshold: Float = 48.0f, val debandRange: Float = 16.0f, val debandGrain: Float = 48.0f, val scaler: VideoScaler = VideoScaler.Bilinear, val linearLight: Boolean = false, val animationUpscaler: AnimationUpscaler = AnimationUpscaler.Off)

How much work a renderer spends on the picture beyond decoding it correctly.

Link copied to clipboard

Which loudness measurement to honour, when the container carries one.

Link copied to clipboard

Where the second subtitle track sits on the picture (#494).

Link copied to clipboard

How exact a seek needs to be, traded against how long it takes.

Link copied to clipboard
sealed interface SleepTimer

When to stop playing on its own.

Link copied to clipboard
data class SourceRefusal(val uri: String, val status: Int)

A server's answer status, 401 or 403, to a request for uri that an open item's reader made (#453). See MediaIo.takeRefusal.

Link copied to clipboard

Which way KitePlayer.stepFrame moves a paused picture.

Link copied to clipboard

What the two front speakers play (#462), as a player's audio menu offers it. It acts on the output after the downmix, so a surround film folded to two speakers obeys it too, and only the first two channels move, as with the balance. A change while playing crossfades, so it never clicks, and it is heard once the audio already buffered has played, as a balance change is.

Link copied to clipboard
class StreamThumbnail(val image: ByteArray, val mimeType: String?, val x: Int, val y: Int, val width: Int, val height: Int, val start: Duration, val end: Duration)

The seek bar picture for a stretch of the item (#433): the region of image at x, y, width by height pixels, which stands for the item from start up to end. image is the whole grid image as the stream serves it, a JPEG, PNG or WebP that mimeType names when the stream says, so the application decodes it with its platform's image decoder and draws that region. A region of 0, 0 and a zero size stands for the whole image, for a stream that does not cut its images into tiles.

Link copied to clipboard
data class StreamVariant(val index: Int, val bitrate: Long, val width: Int? = null, val height: Int? = null, val frameRate: Double? = null, val codecs: String? = null, val hdr: Boolean = false)

One version of the media at another quality, such as one variant of an HLS master playlist. Tracks.variants lists them, and KitePlayer.selectVariant plays one of them.

Link copied to clipboard
data class SubtitleConfig(val preferredLanguages: List<String> = emptyList(), val autoSelectForced: Boolean = true, val autoSelect: Boolean = true, val delay: Duration = Duration.ZERO, val fontScale: Float = 1.0f, val style: SubtitleStyleOverride? = null, val typesetting: Boolean = true, val fonts: List<SubtitleFont> = emptyList(), val hearingImpairedNotes: HearingImpairedNotes = HearingImpairedNotes.Keep, val fallbackEncoding: String? = null, val withMatchingAudio: MatchingAudioSubtitles = MatchingAudioSubtitles.All, val forcedPicturesOnly: Boolean = false, val forcedPicturesWhenOff: Boolean = false, val assColorMatching: Boolean = true, val secondaryLanguages: List<String> = emptyList(), val secondaryPlacement: SecondarySubtitlePlacement = SecondarySubtitlePlacement.Top)

Which subtitle track to pick, when to show its cues, and how large to draw them.

Link copied to clipboard
class SubtitleConfigBuilder(from: SubtitleConfig = SubtitleConfig())

The fields of a SubtitleConfig, set in a subtitles { } block. Each one is the field of that name.

Link copied to clipboard
data class SubtitleSource(val uri: String, val title: String? = null, val language: String? = null, val selectImmediately: Boolean = false, val io: MediaIoFactory? = null, val encoding: String? = null)

An external subtitle file added alongside a media item.

Link copied to clipboard
Link copied to clipboard

Text whose encoding nobody stated, read as the player reads a subtitle file (#423): by its byte-order mark, as UTF-8 when its bytes are valid UTF-8, and otherwise in the single-byte table its bytes read most likely in, such as windows-1251 for Russian or windows-1252 for French. An internet radio station's song titles arrive this way, often not in UTF-8, as mpv found.

Link copied to clipboard
data class ThumbnailSet(val width: Int? = null, val height: Int? = null, val interval: Duration? = null)

The pictures a stream carries for a seek bar's preview (#433): a DASH adaptation set of thumbnail tiles, an HLS image playlist, or a WebVTT thumbnail file the item names in MediaItem.thumbnails. Each image is a grid of tiles, one tile for each stretch of time. Tracks.thumbnails lists the set, and KitePlayer.thumbnailAt gives the tile for a position.

Link copied to clipboard
data class ThumbnailSource(val uri: String, val io: MediaIoFactory? = null)

A WebVTT thumbnail file for an item (#433), as many web players publish: each cue's text names an image, relative to the file, and a region of it, sprite.jpg#xywh=0,0,160,90, for the cue's time. uri is where the file is, and io, when set, reads it instead, as SubtitleSource.io does. The images are read through the file's own reader, or else the player's network, with the item's headers for an image on the item's own server.

Link copied to clipboard
data class TimedWarning(val atNanos: Long, val warning: PlaybackWarning)

One warning, with the engine clock's reading when it was emitted.

Link copied to clipboard
sealed interface TrackChange

What happened to one KitePlayer.selectTrack call.

Link copied to clipboard
value class TrackId(val value: Int)

Identifies one track for the life of one opened media item.

Link copied to clipboard
data class TrackInfo(val id: TrackId, val kind: TrackKind, val codec: String, val language: String? = null, val title: String? = null, val isDefault: Boolean = false, val isForced: Boolean = false, val isAccessibility: Boolean = false, val bitrate: Long? = null, val videoSize: VideoSize? = null, val frameRate: Double? = null, val sampleRate: Int? = null, val channels: Int? = null, val isCoverArt: Boolean = false, val metadata: Map<String, String> = emptyMap(), val dolbyVision: DolbyVisionInfo? = null)

One selectable track.

Link copied to clipboard
Link copied to clipboard
data class Tracks(val all: List<TrackInfo> = emptyList(), val selectedVideo: TrackId? = null, val selectedAudio: TrackId? = null, val selectedSubtitle: TrackId? = null, val selectedSecondarySubtitle: TrackId? = null, val variants: List<StreamVariant> = emptyList(), val selectedVariant: Int? = null, val programs: List<MediaProgram> = emptyList(), val selectedProgram: Int? = null, val thumbnails: ThumbnailSet? = null)

The tracks of the current media item, and which of them are selected.

Link copied to clipboard

Whether a source with fewer channels than the device also fills the device's other speakers.

Link copied to clipboard
data class VariantFit(val drawnWidth: Int? = null, val drawnHeight: Int? = null, val showsHdr: Boolean = false)

What an adaptive stream's picture is drawn into, which the player's choice of variant follows. See DemuxPolicy.fit.

Link copied to clipboard
data class VideoAdjustments(val brightness: Float = 0.0f, val contrast: Float = 1.0f, val saturation: Float = 1.0f, val hueDegrees: Float = 0.0f, val gamma: Float = 1.0f)

The picture controls a viewer expects from a real player: brightness, contrast, saturation, hue and gamma, live, without touching the decoder (mpv's eq). The engine owns the value and every attached renderer is told it, exactly like VideoScale; the renderers apply it per drawn frame, which is why a change is instant and free of pipeline work.

Link copied to clipboard

What the screen shows of the video's dynamic range, as the renderer reports it.

Link copied to clipboard
class VideoPlayback(renderer: VideoRenderer?, clock: MonotonicClock = MonotonicClock.System, containerFrameRate: Double? = null, timestampsMayJump: Boolean = false, queueCapacity: Int = 4, dropPolicy: FrameDropPolicy = FrameDropPolicy.LateOnly) : AutoCloseable

The engine's video half: a frame queue, the presentation schedule, and the drop and repeat decision.

Link copied to clipboard

How the picture occupies the surface it is drawn into.

Link copied to clipboard

The kernel a renderer resamples the picture with when it is not drawn at its own size.

Link copied to clipboard
data class VideoSize(val width: Int, val height: Int, val pixelAspectNumerator: Int = 1, val pixelAspectDenominator: Int = 1)
Link copied to clipboard
data class VideoTransform(val aspectOverride: Float? = null, val zoom: Float = 1.0f, val panX: Float = 0.0f, val panY: Float = 0.0f, val rotationDegrees: Int = 0, val mirrorHorizontal: Boolean = false, val mirrorVertical: Boolean = false)

The viewer's framing controls, on top of VideoScale: force a display aspect the container did not declare (mpv's video-aspect-override), magnify (mpv's video-zoom), and pan the magnified picture (mpv's video-pan-x/-y). The engine owns the value and every renderer is told it, the same delivery law as VideoScale and VideoAdjustments; the renderers fold it into the same one-pass geometry that letterboxes, so it costs nothing per frame.

Functions

Link copied to clipboard
fun SubtitleOverlay.drawOver(rgba: ByteArray, width: Int, height: Int)

Draws this overlay onto RGBA pixels, in place.

Link copied to clipboard

An item read through io, with label used as its URI in logs and on screen. The FFmpeg backend also reads the label's extension to recognise an HLS playlist.

Link copied to clipboard
suspend fun inspect(media: MediaItem, backend: MediaBackend): MediaInspection

Reads what KitePlayer.open would publish about media, through backend alone.

Link copied to clipboard
fun mediaItem(uri: String, block: MediaItemBuilder.() -> Unit = {}): MediaItem

Builds a MediaItem for uri. An empty block builds exactly MediaItem(uri).

Link copied to clipboard

Plays bytes already in memory. Each open has its own cursor and close state, with no array copy. Keep bytes unchanged while any reader is open. Size is known and positions from zero through the array size are seekable. Invalid slices or positions throw IllegalArgumentException; reads and seeks after close throw IllegalStateException. A zero-length read returns zero, even at EOF.

Link copied to clipboard

Builds a PlayerConfig in a block, so a nested setting does not need its type named.

Link copied to clipboard
suspend fun scanAudio(media: MediaItem, backend: MediaBackend, track: TrackId? = null, range: AudioScanRange? = null, sink: AudioScanSink): AudioScanResult

Decodes one audio track of media without an output device, all of it or one range of it.