Skip to content

KitePlayer 0.0.27

Choose a tag to compare

@yuroyami yuroyami released this 25 Sep 17:07

KitePlayer 0.0.27 now plays in the background on Android with its own media service and notification, and opens media through typed input doors in the new kiteplayer-io module. It ships native libraries for 32-bit ARM Android through KiteFFmpeg 0.3.0, and closes more than seventy issues (78 issues, plus 16 changes that never had one). Ten of them break-change the API or its defaults (they are marked 🔴 below).

Usage

// Native views, no Compose: the engine, FFmpeg, HTTP and HTTPS, libass subtitles and the input doors
implementation("io.github.yuroyami:kiteplayer:0.0.27")

// Compose: everything above, plus both Compose video paths
implementation("io.github.yuroyami:kiteplayer-compose:0.0.27")

// Optional, next to either line
implementation("io.github.yuroyami:kiteplayer-audioviz:0.0.27")      // an audio visualiser for files with no picture, in Compose

// Or build your own player from the parts
implementation("io.github.yuroyami:kiteplayer-core:0.0.27")          // the engine and its service interfaces, with no FFmpeg, Ktor or Compose
implementation("io.github.yuroyami:kiteplayer-ffmpeg:0.0.27")        // the FFmpeg backend (pulls KiteFFmpeg)
implementation("io.github.yuroyami:kiteplayer-output:0.0.27")        // audio sinks and video renderers for each platform
implementation("io.github.yuroyami:kiteplayer-network:0.0.27")       // HTTP and HTTPS through Ktor
implementation("io.github.yuroyami:kiteplayer-io:0.0.27")            // input doors for files, streams, content URIs and assets (new in 0.0.27)
implementation("io.github.yuroyami:kiteplayer-libass:0.0.27")        // libass typesetting for ASS and SSA subtitles
implementation("io.github.yuroyami:kiteplayer-view:0.0.27")          // native video views
implementation("io.github.yuroyami:kiteplayer-compose-ui:0.0.27")    // both Compose video paths, for a player you build yourself

kiteplayer-rt, kiteplayer-subtitles, kiteplayer-view-bindings, kiteplayer-compose-video, kiteplayer-compose-interop and kiteplayer-phone arrive with the lines above. Do not add them yourself.

Changelog

🔴 Breaking changes

Change What to do
#42: Reading MediaItem.openOptions needs @OptIn(KitePlayerLowLevelApi::class) Add the opt-in, or move the option to a typed field
450c61c: VizFamily, Visualization.family, VizCatalog.byFamily() and the category argument of the drawing constructors are gone Use VizCatalog.create(), and fall back when a saved drawing name is gone
#32: PlaybackError has a new SourceStalled subtype Handle SourceStalled in a when that has no else
#96: PlaybackWarning has new SourceReconnecting, RecordingStopped (#86) and ResamplerUnavailable (#87) subtypes Handle them in a when that has no else
c0bb8ab: KiteFFmpeg 0.3.0 names a decoder with DecoderId and an encoder with EncoderId Update your own KiteFFmpeg calls, if you make any
#32: A source that sends nothing for 30 seconds now ends the session (BufferPolicy.stallTimeout) Set stallTimeout = Duration.INFINITE to wait as before
#96: The HTTP reader reconnects up to five times when a connection drops Set HttpReaderPolicy.maxReconnects = 0 to fail on the first drop
#50: A raw open option that a typed field also sets refuses the open with PlaybackError.ConfigurationInvalid Set each option in one place
#104: PlaybackWarning.SubtitleCharsetGuessed.detected names one encoding, such as Shift_JIS or EUC-KR Match on the new names
76010f6: MediaItem.label, printed errors and diagnosticsDump() hide URL queries and header values Read MediaItem.uri for the full URI

The last five still compile, but the player behaves differently.

Everything since 0.0.26

AreaTypeChange
Opening media (11)New Features#44: Added a bounded pipe for media that arrives by push, such as a socket or a decryptor
#45: Added kiteplayer-io, a module of input doors, with doors for JVM files, paths, channels and streams
#46: Added a file path door for Apple and Linux, and a file URL door for Apple
#47: Added Android doors for content URIs and bundled assets (MediaIo.ofUri, MediaIo.ofAsset)
API Changes🔴 #42: Required @OptIn(KitePlayerLowLevelApi::class) to read MediaItem.openOptions, which carries raw FFmpeg syntax
#48: Added typed container-open settings (MediaItem.demux) and the mediaItem { } builder
Fixes#34: Read a caller's descriptor by position, so no open moves its file offset
🔴 #50: Refused an open option that is set both raw and typed, and applied the typed demux settings
#148: Opened an item the same way for playback, thumbnails, waveforms and loudness
#149: Kept each item's demux settings in a saved session
Docs#51: Documented which input door to use for the media an app has, and the item builder
Playback (7)New Features#69: Stepped a paused player back one frame (StepDirection)
#80: Added KiteTrace and ChromeTraceFormat, a timeline of the player that Chrome's trace viewer and Perfetto open
🔴 #86: Added startRecording and stopRecording, which copy what the player reads into a Matroska file without a re-encode, everywhere except the web
Fixes#152: Resumed from the picture after forward frame steps, instead of playing the skipped audio under a still picture
#153: Kept the position from jumping ahead by the paused time after a resume
#156: Showed exactly the next frame on every forward step, even when the schedule runs late
3498eef: Closed every part of an FFmpeg source even when one part fails
Audio (4)New Features🔴 #87: Let an app replace the engine's rate conversion with AudioConfig.resampler, and added KiteFFmpegResampler, which runs FFmpeg's libswresample
f54e46e: Reported a change of the default audio output on macOS as an AudioDeviceChanged warning, and kept playing on the new output
Fixes8a51014: Refused to build the audio ring on a target where its 64-bit counters would take a lock, so it cannot click or drift there
fc819ca: Turned the iOS audio session on again when playback resumes after an interruption, such as a phone call
Video and rendering (6)New Features#70: Reported the display's own presented time for each Metal frame
#72: Added a gamma control to the picture adjustments (VideoAdjustments.gamma)
Fixes#66: Made RenderQuality.linearLight scale the picture in linear light on both GPU renderers
#95: Attached VideoToolbox to FFmpeg's own AV1 decoder on Apple, so hardware AV1 can engage
#129: Converted Identity video as its planes, and warned once about ICtCp
#151: Played video coded as RGB
Subtitles (4)New Features#99: Added an optional safe area for subtitles, and placed them right on letterboxed video
🔴 #104: Read Japanese, Chinese and Korean subtitle files in their own encodings, instead of falling back to windows-1252
Fixes#79: Placed a positioned subtitle in the same spot on every renderer, over the whole output
#194: Placed web subtitles over the whole canvas, at the canvas's own size
Network (5)New Features🔴 #32: Ended a session whose source stops answering after BufferPolicy.stallTimeout (30 seconds by default), with PlaybackError.SourceStalled
🔴 #96: Reconnected a dropped HTTP read at the byte it reached, up to five times, and reported it as a SourceReconnecting warning
Fixes#33: Bounded every network wait, and let an interrupt end a read that waits in a reader
🔴 76010f6: Kept signed URL queries and header values out of every label, message, printout and the diagnostics dump
9945b0d: Let a stop or a cancelled open end an open whose reader hangs
Media session and picture in picture (5)New Features#177: Kept Android playback alive in the background with the library's own KitePlayerMediaService and media notification
#179: Opened a picture in picture window on the desktop JVM and in the browser
257bc94: Showed the app's own title, artist and album on the lock screen, skipped by the session's skipInterval, and held wake locks while the player plays or buffers (WakeLockPolicy)
edf4d22: Showed the session's custom actions in the media notification, so an app passes one list of buttons
Fixes#178: Kept the picture in picture window in step with playback and showed subtitles in it on iOS, and brought it to macOS
Audio visualiser (29)New Features#162: Put Twin Bloom and the ten credited ports in the catalogue, which now holds 24 drawings
#163: Turned Ocean Mist into a moonlit sea under drifting mist
#164: Added Twin Bloom, one drawing that flows between the spoke, the petal and the disc
#165: Made Contour a still map whose islands rise and sink with the music
#166: Kept Alchemy's core centred, struck arcs on snares and turned it gold on a drop
#167: Rebuilt Nebula Field as thin braided filaments lit by a white core star
#168: Rebuilt Kaleidoscope around the stereo figure, coloured like 3D glasses
#169: Drew Pipe as a tunnel of lit cells whose rings are the song's recent spectra
#170: Merged Shatter and Ripple Well into Thin Ice, ripples under black ice that breaks on a drop
#171: Drew Fluctus large and sharp, with a smooth soft shadow
#172: Rebuilt Glitch as a broken broadcast of the music's own signal
#173: Replaced Odyssey's flight with a ringed giant planet made of the music
#174: Reworked Neon Lo-Fi into a dusk drive where every part answers the music
#175: Merged Reaction Diffusion and Smoke Rise into Marble, marbled ink with lace that never blurs
#182: Added Silk, a credited port of Matt DesLauriers' codevember day 21
#183: Added Lines, a credited port of Lines by Silvio Paganini
#184: Added Honeycomb, a credited port of Michael Bromley's Soundcloud Visualizer
#185: Added Fracture, a credited port of Vissonance's Fracture by Tariq Soliman
#186: Added Threads, a credited port of the Silk visualiser of Vissonance by Tariq Soliman
#187: Added Fireworks, a credited port of Fireworks with WebGL by Ondřej Žára
#189: Added Wavy Spiral, a credited port of Audible Visuals by Sonia Boller
#190: Added Musical Spectrum, a credited port of ShowCQTBar by Muhammad Faiz
#191: Added Muser, a credited port of Muser by Jon Shamir
#195: Added Iris, a credited port of the Iris visualiser of Vissonance by Tariq Soliman
API Changes#176: Removed Aurora and Aurora Field from the catalogue
🔴 450c61c: Flattened the catalogue into one list (VizCatalog.create()), removed the categories, and added the Glitch and Fluctus drawings
Fixes#158: Counted the opening drawing as shown, so the first section boundary changes it
#193: Stopped the director from picking the drawing already on screen
Testsd3e91cc: Added a stills tool, a JVM test that renders any drawing at chosen seconds of a real song
Builds and releases (10)New Features#57: Ran the whole of CI before every publish, and wrote an SPDX bill of materials for the native code that kiteplayer-libass bundles
#126: Gave the kiteplayer module macOS, Linux and Windows native variants
🔴 c0bb8ab: Moved to KiteFFmpeg 0.3.0 (FFmpeg 9.0.2), which brings native libraries for 32-bit ARM Android and for the desktop JVM on Linux and Windows
Fixes#27: Picked the newest Android NDK by its version number, not by its folder name
#161: Named GNU libiconv in NOTICE, and shipped the libass licence texts with the web zip
bdc511e: Linked the desktop JVM libass adapter for macOS 12, the same floor as a Kotlin/Native build
e7ba430: Aligned the Android libass libraries for 16 KB pages, whatever NDK builds them
Docs#62: Wrote upgrade notes for every change in this release that a consumer has to act on
#108: Replaced the internal codes in the measurement notes and the sources with plain words
9b0484b: Documented the iOS linker flags for a static framework, the privacy manifest reason and the new media session options
Samples (2)New Features#53: Let the iOS sample play a file the user picks
Docs#160: Said in NOTICE that all five sample songs are CC BY-SA 3.0
Tests and CI (11)Fixes#150: Recorded the ws version that Ktor asks for in the JavaScript lock, so local web test runs pass
#154: Built the Android device tests again, after a shared test name with spaces stopped them
#155: Compiled the FFmpeg backend's iOS simulator tests again
#159: Made the audio event concurrency test report why it failed, instead of timing out
#192: Made the event sources concurrency test report a worker's error, instead of a timeout
Tests#56: Built the README's install lines from Maven Central in a clean consumer with an empty Gradle cache
#82: Built, installed and launched the iOS sample app in CI
#83: Measured every published artifact, and failed CI when one grows more than ten percent past its baseline
#84: Failed the JVM tests when a hot audio or colour path gets ten times slower
5813c6d: Ran the Linux arm64 native tests and the Android device tests in CI
7e85307: Ran the tvOS and watchOS simulator tests in CI

Dependencies

Version
Kotlin 2.4.10
Compose Multiplatform 1.12.0 (the Compose modules and kiteplayer-audioviz)
Android Gradle Plugin 9.4.0 (built with)
Gradle 9.7.1 (built with)
JDK 21
Android SDK compileSdk 36 (37 for the Compose modules and kiteplayer-audioviz), minSdk 26
KiteFFmpeg 0.3.0, with FFmpeg 9.0.2 (kiteplayer-ffmpeg)
Ktor 3.5.2 (kiteplayer-network)
libass 0.17.4, with HarfBuzz 14.2.1, FreeType 2.14.3 and FriBidi 1.0.16 (kiteplayer-libass)
Kite3D 0.2.0 (kiteplayer-audioviz)
kotlinx.coroutines 1.11.0

Targets: kiteplayer builds for Android, JVM, iOS, macOS, Linux, Windows, JS and Wasm, and kiteplayer-core adds tvOS, watchOS and Android Native. kiteplayer-compose and kiteplayer-audioviz build for Android, JVM and iOS. The Linux and Windows native builds have no audio or video output and no HTTPS, by design.

Full changelog: v0.0.26...v0.0.27