Repository navigation
KitePlayer 0.2.0
Closing 180 issues.
Usage
// Native views, no Compose: the engine, FFmpeg, HTTP and HTTPS, libass subtitles and the input doors
implementation("io.github.yuroyami:kiteplayer:0.2.0")
// Compose: everything above, plus both Compose video paths
implementation("io.github.yuroyami:kiteplayer-compose:0.2.0")
// Optional, next to either line
implementation("io.github.yuroyami:kiteplayer-audioviz:0.2.0") // 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.2.0") // the engine and its service interfaces, with no FFmpeg, Ktor or Compose
implementation("io.github.yuroyami:kiteplayer-ffmpeg:0.2.0") // the FFmpeg backend (pulls KiteFFmpeg)
implementation("io.github.yuroyami:kiteplayer-output:0.2.0") // audio sinks and video renderers for each platform
implementation("io.github.yuroyami:kiteplayer-network:0.2.0") // HTTP and HTTPS through Ktor
implementation("io.github.yuroyami:kiteplayer-io:0.2.0") // input doors for files, streams, content URIs and assets
implementation("io.github.yuroyami:kiteplayer-libass:0.2.0") // libass typesetting for ASS and SSA subtitles
implementation("io.github.yuroyami:kiteplayer-view:0.2.0") // native video views
implementation("io.github.yuroyami:kiteplayer-compose-ui:0.2.0") // both Compose video paths, for a player you build yourselfkiteplayer-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 |
|---|---|
#75: PlaybackWarning has a new GaplessFallback value |
Handle GaplessFallback in a when that has no else |
| #75: Queue items now follow each other without a gap, and the status stays Playing between items | Set PlayerConfig.queue to QueueConfig(gapless = false) to keep the old path |
#71: PlaybackWarning has a new DeinterlaceUnavailable value |
Handle DeinterlaceUnavailable in a when that has no else |
#71: PlayerConfig.deinterlace is Auto by default, so an interlaced stream now decodes in software |
Pass DeinterlacePolicy.Off to keep hardware decoding |
0e003dc: PlaybackWarning has a new SubtitlesNotDrawn value |
Handle SubtitlesNotDrawn in a when that has no else |
0e003dc: The engine holds every subtitle rasterizer to the limits in the SubtitleRasterizer companion object, and cues past a limit are not drawn |
Throw SubtitleOverlayLimitException from a custom rasterizer to show part of an overlay |
e54f920: AudioSinkEvent has a new Failed value |
Handle Failed in a when that has no else |
#228: RendererEvent has a new ColorApproximated value |
Handle ColorApproximated in a when that has no else |
#92: PlaybackError.AudioDeviceUnavailable now takes device and detail |
Pass both arguments |
#97: KiteFFmpegVideoFrame.frame and AudioSamples are internal |
Draw web frames with KiteFFmpegWebPainter instead of WebRgbaConverter |
#218: MasterClock.External, PlaybackError.DecoderUnavailable, OutputBackend.videoRenderer and AudioSinkBuffer.writePlane are removed |
Delete the when branches, and delete the overrides of the last two |
#218: KitePlayer.create refuses SyncMode.ExternalMaster with ConfigurationInvalid |
Use another SyncMode |
#220: AudioPlayback.submit is internal |
Call submitDecoded |
#274: XmlMini and XmlElement are internal |
Use DashManifestParser.parse for a DASH manifest |
#217: setSleepTimer throws IllegalArgumentException for a negative fade or an After that is not in the future |
Pass a valid fade and time |
#256: openQueue refuses a session that is not Idle, Ended or Failed |
Call stop() first |
#219: setAudioDelay, setSubtitleDelay, SubtitleConfig.delay and restore refuse a value that is not finite or is beyond KitePlayer.DELAY_MAX |
Keep delays within one hour either way |
#203: ReplayGain no longer raises a track whose tags carry no peak, and AudioConfig.volumeCeiling no longer widens its clamp |
Raise the volume to make such a track louder |
#280: InterruptionPolicy.duckVolume is now a factor on the listener's volume, not an absolute volume |
Set it as a share, for example 0.2 for a fifth |
#214: PlayerMemento.FORMAT_VERSION is 4, and an older build refuses a memento that this one wrote |
Update every reader of stored mementos |
#204: Every KitePlayer call that can fail declares @Throws, and KitePlayer.create throws a checked PlaybackException for Java |
Call them with try in Swift, and handle PlaybackException in Java |
#240: Dash.mediaItemFor throws DashUnsupportedException for audio in its own adaptation set, live manifests and several Periods |
Catch it and fall back to another source |
#237: On macOS the desktop JVM decodes with VideoToolbox under HwdecPolicy.Auto, and such frames report PlayerPixelFormat.Opaque |
Read planes through planeFormat, or pass HwdecPolicy.Off |
#238: keepDisplayAwake is true by default, so the display no longer dims while video plays |
Pass keepDisplayAwake = false to manage the display yourself |
#309: KitePlayerVideo has new trailing parameters, so a trailing lambda now binds to accessibilityStateFormat |
Pass onRendererAttached by name |
264fbf6: The DASH door applies DashUrlPolicy to every redirect and follows at most five. Under DashUrlPolicy.SameOrigin a redirect to another scheme, host or port fails with DashUrlRefusedException |
Use DashUrlPolicy.Default for a CDN that redirects to another host |
d2b315d: An external subtitle gets the item's headers only when it has the item's scheme, host and port |
Give its SubtitleSource its own io to send headers to another server |
The rows about a default or a behaviour (the gapless queue, deinterlace, keepDisplayAwake, ReplayGain, ducking, redirects and subtitle headers) still compile. A by wrapper of VideoDecoderFactory that overrides only the old create also misses its new overload.
Everything since 0.0.27
| Area | Type | Change |
|---|---|---|
| Playback (16) | API Changes | 🔴 #217: setSleepTimer now throws IllegalArgumentException at the call for a bad fade or an After that is not in the future, and a refused A-B loop is published as CommandRefused. |
🔴 #218: KitePlayer.create refuses SyncMode.ExternalMaster with ConfigurationInvalid. Removed MasterClock.External, PlaybackError.DecoderUnavailable, OutputBackend.videoRenderer and AudioSinkBuffer.writePlane, which nothing used. | ||
#264: Thumbnail and Waveform now compare and hash their arrays by content. | ||
| Performance | #245: Stopped a paused player from waking about 700 times a second. | |
| Fixes | #30: Made every read of the player's own doors interruptible and every wait bounded. | |
| #31: Passed a cancel into FFmpeg's own protocols, so a stop or close ends an open that reads through the URL fallback or a file descriptor. | ||
| #200: Kept playing at the old position when a seek aborts because a worker could not park. | ||
#202: Made inspect resolve readers the way open does, fail with a typed error and run off the caller's thread. | ||
#213: Made restore check every setting before it changes anything, so a refused setting no longer leaves a half restored player. | ||
🔴 #214: Kept item titles and the shuffle order in a PlayerMemento, and made fromProperties refuse a queue.size larger than its keys. PlayerMemento.FORMAT_VERSION is now 4. | ||
#216: Stopped SleepTimer.After from counting paused time, and made SleepTimer.EndOfItem end a repeating item. | ||
#226: Made the interruption and background guards pause or duck a buffering player, and one that opens the next queue item while playing. PlayerSnapshot gained playRequested. | ||
#255: Left position() at its old value when a seek is refused or a seekLater is dropped. | ||
#276: Let stop and close end a stream or Android pipe read that waits for bytes. | ||
| #277: Fixed a video track change at position zero that left the player discarding all output. | ||
#278: Made a guard resume only a pause it made itself, by comparing the new KitePlayer.transportMark count. | ||
| Queue and gapless (4) | New Features | 🔴 #75: Made queue items follow each other without a gap. The next item opens five seconds before the current one ends and plays on the same audio device, with QueueConfig(gapless = false) to keep the old path. |
| #304: Let a video queue on Android follow item to item without a gap in the sound. | ||
| API Changes | 🔴 #256: openQueue now refuses to replace a session that is not Idle, Ended or Failed, as open always did. | |
| Performance | #306: Played a preloaded item without opening it a second time after next() or a gapless fallback. | |
| Audio (18) | New Features | 🔴 #92: Added audioOutputDevices() and withAudioOutputDevice(id) to DesktopOutputBackend and AppleOutputBackend, to list output devices and bind a player to one. |
#181: Added AudioConfig.upmix with UpmixMode.Surround, which plays a mono or stereo source from every speaker of a surround device. | ||
#239: Added MediaItem.audioFilter, an FFmpeg audio filter chain that every decoded audio buffer runs through. | ||
| API Changes | 🔴 #220: Made AudioPlayback.submit internal, so submitDecoded is the one public feed and it runs every stage. | |
| Performance | 2a0b364: Decoded audio buffers straight into the engine's interleaved array, which cuts the bytes allocated per buffer by half or more. | |
| Fixes | #199: Derived every downmix from the speakers with FFmpeg's rules, so layouts such as 5.0 side, 3.0, 4.0 and side quad keep their centre in a stereo downmix. | |
🔴 #203: Stopped ReplayGain from raising a track whose tags carry no peak, and stopped AudioConfig.volumeCeiling from widening its clamp. | ||
| #210: Matched FFmpeg's downmix gains for 6.1, 7.1 folds, mono and 2.1 targets. | ||
#211: Made LoudnessMeter weight each channel by its speaker, so the LFE of 2.1 and 6.1 no longer counts as programme. | ||
🔴 #219: Corrected the sign in the setAudioDelay KDoc, and refused an audio or subtitle delay that is not finite or is beyond KitePlayer.DELAY_MAX, one hour either way. | ||
| #221: Kept the Kotlin audio ring's device callback from waiting on the feeder on Android and the desktop JVM. | ||
| #222: Made the end-of-media drain stop at the engine's deadline on the desktop JVM and Android. | ||
| #257: Ran the equaliser, balance and ReplayGain over the audio tail at the end of a stream. | ||
| #260: Wrote 16-bit desktop audio with FFmpeg's scale and rounding, so unity-gain audio is bit-exact. | ||
| #261: Read the Android driver timestamp under one lock for both of its readers. | ||
🔴 #280: Made a duck a multiplier on the listener's volume, so it can only make the sound quieter. KitePlayer.setDuckLevel is the new call, and InterruptionPolicy.duckVolume is now a factor. | ||
| #288: Applied the new track's ReplayGain on an in-place audio track switch. | ||
| #292: Signaled an audio seek landing only after the straddling buffer is trimmed. | ||
| Video and rendering (10) | New Features | 🔴 #71: Deinterlaced interlaced video with FFmpeg's bwdif. PlayerConfig.deinterlace takes a DeinterlacePolicy, and Auto is the default. |
| Performance | #247: Converted native software frames in four row slices, as the JVM does. | |
| #8293638: Reused one RGBA array per renderer on the JVM and Android instead of allocating 8.3 MB for each 1080p frame. | ||
| Fixes | #197: Made captureFrame return when the media has ended or a teardown interrupts it. | |
| #198: Timed the frame after a late drop from the dropped frame's slot, so a drop no longer costs a whole extra frame period. | ||
🔴 #228: Added RendererEvent.ColorApproximated, which the web canvas publishes for HDR shown without tone mapping and for YCgCo and FCC video. | ||
| #258: Converted FCC-tagged video with the FCC matrix instead of the BT.709 matrix. | ||
| #263: Closed the first decoded frame when a video filter graph cannot be built. | ||
| #293: Reported a native view attachment once per player, not on every recomposition. | ||
#299: Made captureFrame and encode work while VideoToolbox decodes. SoftwareReadableFrame gained planeFormat. | ||
| Subtitles (14) | New Features | #98: Showed Blu-ray, DVB, DVD and XSUB image subtitles from the container. |
29e6980: Played caption tracks stored on their own, such as a MOV c608 track, as selectable subtitle tracks. | ||
| Fixes | #212: Kept an applied external subtitle, both selections and the typesetter across a video track switch and a hardware decoder recovery. | |
| #215: Made the external subtitle loader wait when a reader answers that no bytes are ready yet, instead of reading it as the end of the file. | ||
| #223: Cleared the subtitle overlay only after the raster job it replaces, so a late job no longer leaves stale text. | ||
#229: Anchored a WebVTT line percentage at the cue's top edge unless its line alignment names the centre or the end, and kept positioned cues inside the picture. | ||
| #230: Placed positioned subtitle cues on iOS and macOS by their alignment, as the other platforms do. | ||
#231: Read SubRip {\anN} and other brace tags as ASS override tags instead of showing them as text. | ||
| #243: Refused a local subtitle file over the size limit before reading it, on the JVM and Android. | ||
| #287: Scaled bitmap subtitle regions in size as well as in position. | ||
| #291: Bounded what the web libass engine holds while its module loads. | ||
🔴 0e003dc: Held every subtitle rasterizer to the limits in the SubtitleRasterizer companion object. Cues past a limit are not drawn and PlaybackWarning.SubtitlesNotDrawn says so, and playback continues when a rasterizer or renderer throws. | ||
9719dd9: Moved the kiteplayer-libass chain to libass 0.17.5, with FriBidi 1.0.17, FreeType 2.14.3 and HarfBuzz 14.5.0, from KiteFFmpeg's ass-chain-r2 release. A typeset ASS line can shift by a pixel. | ||
🔴 d2b315d: Sent the item's headers to an external subtitle only when it has the same scheme, host and port as the item's uri. | ||
| Visualiser (56) | API Changes | #297: Let rememberAudioVizState(player) compile without the drawing toolkit opt-in, because SongScanPolicy and SongMapStore lost @AudioVizAuthoringApi. |
| Performance | #316: Closed the shader wrappers of older frames on desktop and iOS. | |
| #331: Reused padded mesh arrays on desktop and iOS instead of allocating exact copies. | ||
| #332: Tested the Neon Lo-Fi floor cells without allocating a range for each cell on every frame. | ||
| #333: Read only the sampled pixels when making a palette from a cover. | ||
| #351: Built the Musical Spectrum note ruler once for one size instead of on every frame. | ||
| Fixes | #227: Ignored a closed player when the visualiser leaves the screen. | |
| #244: Created every missing directory level for the song map store on iOS. | ||
| #285: Kept scanning later songs after one song scan fails. | ||
| #286: Stepped both visualiser surfaces on one clock that follows the current director and analysis source. | ||
| #289: Applied the song scan policy before scanning starts and followed later changes to it. | ||
| #296: Gave the desktop and iOS samples every song in the shared media folder. | ||
| #298: Kept Honeycomb and Pipe within three flashes a second on a drum loop. | ||
| #311: Kept the waveform, the hits and the pause live under reduced motion. | ||
| #312: Gave each reader of the visualiser state its own event cursor, so a frame rate cap no longer drops events. | ||
| #313: Scaled the light of Bars and Alchemy by what the flash guard allows. | ||
| #314: Passed the reduced motion setting to the drawing browser tiles. | ||
| #315: Stopped the director from changing drawings with the strobe while reduced motion is on. | ||
| #317: Made the Neon Lo-Fi controls follow the sliders while the player is paused. | ||
| #318: Rebuilt the Iris background when the canvas width or height changes. | ||
| #321: Held every drawing still while the player is paused. | ||
| #322: Fixed how song map parts join, so a gap between two scan parts is no longer filled with the next part's level. | ||
| #323: Spaced key-change boundaries at least four seconds apart. | ||
| #324: Treated a stored song map with an unusable number as a cache miss. | ||
| #325: Showed the empty picture when the visualiser state gets a closed player. | ||
| #326: Gave the settings panel controls roles and values for a screen reader. | ||
| #327: Scaled the lane cut and the light speed of Pipe by reduced motion. | ||
| #330: Accepted a decoder block longer than a quarter of a second when the analysis queue is empty. | ||
| #334: Asked for linear filtering of the lookup pictures of Android runtime shaders. | ||
| #336: Restarted the song scan analysis when the timestamps jump, so events after a jump are no longer placed too early. | ||
| #337: Replaced a song map file with one move on desktop and Android. | ||
| #338: Checked the close and ordered files by nanoseconds in the iOS song map store. | ||
| #339: Adapted the level reference when the loudness meter cannot read the layout. | ||
| #342: Kept the calm reading gliding when the same frame comes back on a new step. | ||
| #343: Kept the cycle length and counted heard time through a pause. | ||
| #344: Fell back to the plain fade under reduced motion, and made the settings panel show the real choice. | ||
| #345: Scaled the ground and detail layers by what the flash guard allows. | ||
| #346: Rejected a stored song map with a value outside its range. | ||
#349: Kept the surface clocks in Double, so they never stop advancing after long runs at high refresh rates. | ||
| #350: Scaled the floors of Thin Ice and Ocean Mist by the allowed light. | ||
| #352: Slowed the view moves and turns of Odyssey under reduced motion. | ||
| #353: Held the tear of the finishing pass while paused. | ||
| #354: Kept the glow of the finishing pass calm under reduced motion. | ||
| #355: Wrote the spectrum histories by heard time instead of by display step. | ||
| #356: Installed the events of a song map that holds more than 4096 of them, keeping the first 4096. | ||
| #357: Held every rise at the flash limit, so a slow fade can no longer open the flash guard. | ||
| #358: Cleared the palette turn of the ground and detail layers on reset. | ||
| #359: Faded a choice on from where the picture is when a second change lands. | ||
| #360: Kept the Thin Ice rings on their wells when the screen turns. | ||
| #361: Carried the tuned 60 Hz spring and envelope step over to any step length. | ||
| #362: Damped the snare shove and the drop fling of the flying camera under reduced motion. | ||
| #365: Filled the triangles of the mesh path before Android 10 with their mean colour, so a soft spot is no longer a solid disc. | ||
#368: Removed two ShaderProgram functions that nothing called. | ||
| #369: Let the spring step reach heavy damping and steps longer than 50 ms. | ||
| #370: Turned the Thin Ice cracks with the rings when the screen turns. | ||
| #371: Started the tear of the finishing pass from valid strips. | ||
| Network and streaming (9) | New Features | 🔴 #240: Made Dash.mediaItemFor refuse a manifest whose audio sits in its own adaptation set, and stream a representation that is one file with range requests. It throws DashUnsupportedException. |
| API Changes | 🔴 #274: Made XmlMini and XmlElement internal, and wrote KDoc for the service package, AudioConfig and the DASH surface. | |
| Fixes | #232: Followed the DASH hierarchy for BaseURL elements and merged segment templates from the Period down. | |
| #241: Kept the whole URL out of reconnect warnings and of the messages of the reader, the DASH door and subtitle refusals. | ||
#242: Limited the waits of Dash.manifest and every segment fetch with an HttpReaderPolicy. | ||
| #262: Published the byte cache window as one pair, so a buffered-range sample after a far seek is consistent. | ||
| #283: Accepted an HTTP answer only when it proves its byte position, its file size and its entity tag. | ||
| #284: Resolved DASH URLs against the base path only, so a slash in a manifest URL's query no longer joins the directory. | ||
🔴 264fbf6: Applied DashUrlPolicy to every DASH redirect before following it, with at most five redirects. Under DashUrlPolicy.SameOrigin a redirect to another scheme, host or port fails with DashUrlRefusedException. | ||
| Views and Compose UI (6) | New Features | 🔴 #238: Added keepDisplayAwake, true by default, to KitePlayerVideo, KitePlayerSurface, KitePlayerView and KitePlayerUIView, so the display stays awake while video plays. |
| API Changes | #266: Made the notification, screen reader and desktop menu text configurable, with the same English default. | |
#267: Named installMobileRenderer() in the deprecation messages of the old phone views. | ||
🔴 #309: Added accessibilityVideoLabel and accessibilityStateFormat to KitePlayerVideo and KitePlayerSurface, so an app can translate what a screen reader says. | ||
| Fixes | #307: Gave the Compose canvas path of KitePlayerVideo a screen reader name and state, and made the platform views update their state by themselves. | |
#310: Gave KitePlayerAwtView an accessible name and description, with accessibilityVideoLabel, accessibilityStateFormat and updateAccessibilityState(). | ||
| Android (7) | Fixes | #201: Dropped remote presses that the player refuses, instead of crashing on a refused lock-screen seek or a remote play after close. |
#205: Made attachMediaNotification hold no wake lock instead of refusing a manifest without WAKE_LOCK. KiteLog.log is now public. | ||
| #281: Made background handling that attaches after an Activity started see every transition. | ||
| #282: Held Android audio focus only when it is granted, and asked for it again after a loss. | ||
| #300: Drew the paused picture again when the Android view gets a new surface. | ||
41197ac: Applied a change of secure to a view that already shows video by recreating its surface. | ||
d2c38ad: Routed the three direct android.util.Log calls through KiteLog, so the player prints nothing until an app installs a sink. | ||
| Apple (4) | API Changes | 🔴 #204: Declared @Throws on every KitePlayer call that can fail, so Swift catches the failure instead of ending the app. |
| Performance | #207: Copied native frame planes and libass packs with one memcpy instead of one byte at a time. | |
| Fixes | #259: Scaled ten-bit video by four in the Metal renderer instead of dividing by 1023. | |
🔴 e54f920: Failed a macOS player bound to an output device with PlaybackError.AudioDeviceUnavailable when that device disappears. AudioSinkEvent gained Failed. | ||
| Desktop JVM (5) | New Features | 🔴 #237: Decoded H.264 and HEVC with VideoToolbox on macOS under HwdecPolicy.Auto, and AV1 on a Mac with AV1 hardware. |
| Fixes | #224: Finished every software frame conversion even when all Dispatchers.Default threads convert. | |
| #225: Painted the desktop AWT view from one thread at a time. | ||
| #279: Turned rotated video in the desktop AWT view instead of squeezing it sideways. | ||
| #290: Reported an AWT frame as presented only after it reached the screen. | ||
| Build and packaging (6) | API Changes | 🔴 #97: Made KiteFFmpegVideoFrame.frame and AudioSamples internal, so the media library's Frame is gone from kiteplayer-ffmpeg. Every Android half now compiles against SDK 37, and all four modules with an expect class pass -Xexpect-actual-classes. |
| #268: Emitted Java 11 bytecode from every JVM and Android half, so Java 11 apps can use the library. | ||
| Fixes | #248: Named the bundled licences in the kiteplayer-libass and subtitles POMs. | |
| #250: Shipped the licence notices of the ported visualiser drawings in NOTICE and in the JVM and Android artifacts. | ||
| #265: Gave each published module its own POM description. | ||
| #270: Retried the libass chain download after a transient failure. | ||
| Tests and CI (21) | Fixes | #249: Pinned the third-party workflow actions to commit SHAs. |
| #251: Made the test tasks outside the gate pass. | ||
| #305: Compiled the device test sources in the emulator job's early build step. | ||
| Tests | #12: Measured the five Android subtitle styling cases on the images the rasterizer draws, on the CI emulator. | |
| #19: Checked the secure video surface in a screenshot on the CI emulator. | ||
| #20: Entered picture in picture from the sample's direct view on the CI emulator, with an upright and a quarter-turned clip. | ||
| #28: Ran the tvOS and watchOS simulator tests of core, subtitles, io and rt in CI. | ||
| #29: Ran the linuxArm64 tests on an arm64 runner and the Android native tests on the emulator, with test counts in the run summary. | ||
| #59: Ran the format matrix in a headless browser, with each row naming its video decoder. | ||
| #81: Ran the Android device tests on every push in an emulator job. | ||
| #196: Recorded the test clips with FFmpeg 9, the major the player decodes with. | ||
| #269: Made the libass end-to-end test poll for its result instead of sleeping a fixed time. | ||
| #271: Ran the common tests of audioviz, phone and sample-shared on the Android host. | ||
| #302: Made the CoreAudio real-time test wait for the device instead of sleeping. | ||
| #328: Rendered every drawing on a one-pixel and a sliver canvas in a test. | ||
| #329: Checked that a restarted drawing draws like a fresh one. | ||
| #341: Made the audioviz tests skip honestly and fail when they should. | ||
| #348: Tested that every drawing looks and moves the same at other refresh rates. | ||
| #364: Made the visualiser tests that could not fail able to fail. | ||
| #366: Asked the contact sheet test for the catalogue the library has, which is 24 drawings. | ||
| #367: Tested every drawing against a shuffle of what happens to a real surface. | ||
| Docs (14) | Docs | #206: Named the file timestamp category in the README's iOS privacy manifest note. |
| #252: Stated the three LGPL duties in the README and corrected the component list in NOTICE. | ||
| #253: Rebuilt the README's target table from what CI and the scripts run. | ||
| #254: Gave the flash safety paragraph the counts of the current 24 drawings. | ||
#272: Added kiteplayer-libass to the API reference and fixed 43 unresolved KDoc links. | ||
| #273: Corrected doc statements and KDoc samples that the code contradicted. | ||
| #275: Opened the README with a runnable example and a target table per artifact. | ||
| #303: Said in the README that network media does not play in the browser yet. | ||
| #319: Described Marble as it is in the rendering document. | ||
| #335: Corrected the audio visualiser documents against the code. | ||
| #340: Named the visualiser settings for reduced motion, rate and visibility in the README. | ||
| #347: Stated the real numbers and lifetimes in the visualiser comments and documents. | ||
| #363: Corrected the Kaleidoscope comment about the bar clock under a pause. | ||
| #372: Stated the current values in comments and removed an unused helper. |
Dependencies
| Version | |
|---|---|
| Kotlin | 2.4.20 |
| Compose Multiplatform | 1.12.1 (the Compose modules and kiteplayer-audioviz) |
| Android Gradle Plugin | 9.4.1 (built with) |
| Gradle | 9.8.0 (built with) |
| JDK | 21 (built with), JVM bytecode 11 |
| Android SDK | compileSdk 37, minSdk 26 |
| KiteFFmpeg | 0.4.0, with FFmpeg 9.0.2 (kiteplayer-ffmpeg) |
| Ktor | 3.6.0 (kiteplayer-network) |
| libass | 0.17.5, with HarfBuzz 14.5.0, FreeType 2.14.3 and FriBidi 1.0.17 (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.27...v0.2.0