mpv_audio_kit 0.1.2
mpv_audio_kit: ^0.1.2 copied to clipboard
Flutter audio player built on top of libmpv. Supports audio filters, pitch control, equalizer, and all mpv audio features. Targets macOS, Windows, Linux, iOS and Android.
0.1.2 7-05-2026 #
Changed #
Player()returns immediately during cold start: the heavy libmpv init (library open, handle creation and initialisation, ~80 property observers) now runs on the background event isolate instead of the host isolate.- The background event isolate now blocks on
mpv_wait_eventinstead of polling every 50 ms, eliminating ~20 spurious wake-ups per second during idle playback. dispose()is robust against being called beforePlayer()finishes coming up: it waits for init to settle (or fail) before issuing the cooperative quit and tearing down the streams, so the safety timeout never fires on construction-then-dispose patterns.
Fixed #
Media.httpHeadersnow validate keys and values and throwArgumentErroron inputs that would corrupt the outgoing HTTP request.Player.add()andPlayer.replace()now wait for the bundled CA file before emittingloadfile, matchingPlayer.open(). The first HTTPS append issued immediately after construction no longer races peer verification.- The Player finalizer now issues a cooperative quit instead of tearing down the handle directly, eliminating a possible crash when a Player is garbage-collected without
dispose().
0.1.1 6-05-2026 #
Changed #
- Numeric setters now validate at the wrapper boundary and throw
ArgumentErrorwith a precise stack trace instead of waiting for a round-tripMpvException. AffectssetVolume,setRate,setPitch,setVolumeMax. SpectrumSettingsrejects out-of-range values at construction (FFT size must be a power of two in[256, 4096], smoothing in[0, 1],bandHighHz > bandLowHz, etc.) instead of letting them surface as visually-broken output downstream.
Fixed #
Media.httpHeadersnow reach mpv on every track, including the first one. Previously they were silently dropped on the firstopen()and applied to the wrong file on subsequent calls.replace()on the currently-playing entry is now seamless instead of briefly stopping playback before resuming on the new track.setNetworkTimeouthonours sub-second precision; durations below 1s no longer collapse to "no timeout".setTlsCaFile('')restores the bundled CA default instead of silently disabling peer verification.setTlsCaFileis now declared on the publicPlayerApiinterface.setReplayGain,setCache, andsetLoopare now atomic: if any partial write fails, the previous values are restored before the error is rethrown.dispose()no longer falls through its safety timeout when racing an in-flightopen().state.positionis cleared synchronously onopen()so a UI reading the playhead on track-change no longer briefly shows the previous track's value.state.chaptersandstate.currentChapterare now refreshed after every load. Two consecutive files with structurally-identical chapter lists previously left both fields stranded at the prior track's value.
Build #
- Added AudioToolbox decoders for macOS and iOS.
- Fixed TLS on macOS and iOS (now aligned with the others).
- Updated libmpv to
libmpv-r6across all platforms.
0.1.0 5-05-2026 #
Major release. The Dart API has been redesigned for type safety, ergonomics, and atomic state mutations.
Added #
- A new
AudioEffectsbundle covering equalizer, compressor, loudness, pitch, tempo, bass, treble, stereo width, headphone crossfeed, silence trim, and raw lavfi effects applied atomically through one setter. - A-B loop and chapter navigation.
- Aggregate playback-state stream (idle, loading, buffering, playing, paused, completed) for one-line UI bindings.
- 20+ new observable streams covering timing, file metadata, cache, demuxer, and version info.
- Typed
Hookenum for the file-loading lifecycle. - New
MpvPrefetchState.failedvariant for when background prefetch fails. - Typed errors via the
MpvPlayerErrorhierarchy and a publicMpvExceptionfor raw-API failures. - Real-time FFT spectrum and raw PCM streams (
Player.stream.spectrum/Player.stream.pcm) captured post-DSP for visualizers. setTlsCaFile(path)with custom root-CA bundle.
Changed #
- DSP effects, ReplayGain, and cache settings now live in atomic config objects applied in one call instead of multiple granular setters.
- Track selection, format, channel layout, S/PDIF passthrough, log levels, and hooks are now typed enums and sealed classes instead of free-form strings.
- Embedded cover art is exposed as raw codec bytes through a dedicated
state.coverArt+stream.coverArtpair, with Flutter conveniences (art.imagereturns anImageProvider, plusart.extension,art.isPng,art.isJpeg, …). setAudioDisplay,setImageDisplayDuration, and theDisplayenum are removed - they controlled mpv's video pipeline, which the audio-only build no longer ships. Cover bytes are surfaced regardless viastate.coverArt.- Raw-API escape hatches (
getRawProperty,setRawProperty,sendRawCommand) are nowFuture<...>and surface mpv-side errors asMpvExceptioninstead of silently no-oping.getRawPropertystill returnsnullon failure. - Every typed setter (
setVolume,setRate,setAudioEffects,setCache, …) now throwsMpvExceptionwhen mpv rejects the write, instead of silently advancing the optimistic state. Player.openPlaylistrenamed toPlayer.openAll(matches Dart'saddAll/removeAllconvention).- See the Migration section in the README for the full 0.0.9 → 0.1.0.
Fixed #
- The initial player state (volume, format, channels, params, …) is now reliably populated before the first
await. A startup race could previously leave one or more state fields at their default until the next user-driven setter. - Calling
dispose()immediately after construction no longer throws. - Player instances that get garbage-collected without an explicit
dispose()now release their native handle automatically. Always preferawait player.dispose(); this is just a safety net. Player.dispose()completes in milliseconds instead of falling through a 2-second timeout.- HTTP headers no longer leak across
open()calls; per-file headers stay scoped to theirMedia. - Android
content://file descriptors are released on aborted loads, including when anopenAll([...])fails mid-batch. state.coverArtnow mirrors the lateststream.coverArtemit synchronously (was permanentlynulldespite being documented).print(state)andprint(audioEffects)now render the actual values instead of placeholder text.- Hot-Restart cleanup is hardened against false positives so a long-lived dev process can't have it trip on memory belonging to other tools.
- Several correctness fixes around playlist equality, hook idempotency, cache precision, and lifecycle stream synchronisation.
- HTTPS streams now connect on Android out of the box; previously TLS verification had no trust roots and every handshake failed.
Example #
- Spectrum visualizer in the Player tab driven by
Player.stream.spectrum, plus a Settings page exposing everySpectrumSettingsknob (FFT size, window, band count, range, emit rate, attack, release smoothing, dB range) for live exploration. - Filters page reorganised into category sub-pages covering every filter shipped with the build, plus a dedicated 18-band visualizer for
superequalizer.
Build #
- Patched prefetch to also support
.failedstate. - Patched audio output state to report AO immediately.
- Patched audio frames to extract PCM streams (visualizer).
- Fixed Android
audiotrackdriver not working. - Bundled libmpv binaries reduced by ~55% (e.g. macOS 29 MB → 13 MB).
- Bumped minimum deployment targets to iOS 15.0 and macOS 12.0.
- iOS Simulator is now Apple Silicon only (dropped x86_64).
- Added arm64 support for Linux and Windows.
- Updated libmpv to
libmpv-r5across all platforms.
0.0.9 27-04-2026 #
Fixed #
- Lifecycle streams (
stream.playing/stream.buffering/stream.completed) silently desynced fromstateon file boundaries -stream.completednever fired on natural EOF andstream.bufferingnever emitted at all. All three now stay in sync withstateacross every lifecycle transition. dispose()leaked four stream controllers (audio display, cover-art auto, image display duration, prefetch state). All now closed on teardown.- Use-after-dispose hazards on
open()/openPlaylist(): disposing the player while URI normalisation was still in flight could SIGSEGV on Androidintent://loads. Added disposed re-checks after every async boundary. - Defensive disposal guards on the position polling and embedded-cover pipelines so in-flight work bails instead of writing to closed controllers.
setEqualizerGains()now respects the disposal contract.setAudioFilters()andsetEqualizerGains()now route state mutation through the same path as every other setter.openPlaylist(medias, index: N)no longer silently no-ops whenN >= medias.length; the index is clamped tomedias.length - 1.
Changed #
- Reordered the
dispose()teardown sequence so the event loop exits cleanly without ever callingmpv_wait_eventon a freed handle.
0.0.8 24-04-2026 #
Added #
stream.prefetchState- observable lifecycle of mpv's background playlist-prefetch (MpvPrefetchState:idle,loading,ready,used).stream.seekCompleted- authoritative "seek finished" signal that fires exactly once per seek or initial file load.
Changed #
on_loadhook now runs for prefetched tracks, so custom URL schemes resolve uniformly whether mpv is opening the current track or pre-opening the next one.- DASH segment downloads now reuse a single TCP connection across segment GETs (matches HLS persistent-HTTP behaviour).
Fixed #
- Spurious
position = 0no longer emits onstream.positionduring seek / playback-restart. - Audible click at every segment boundary on well-formed fragmented-MP4 / DASH streams (AAC encoder priming edit lists are now respected on fMP4).
Example #
- Rewrote the seek slider to release its drag value via
stream.seekCompletedinstead of a fixed delay.
Build #
- Updated libmpv binaries to
libmpv-r4across all platforms.
0.0.7 12-04-2026 #
0.0.6 08-04-2026 #
Added #
- SMB2/3 protocol support (
smb2://) for Samba (CIFS) network shares via libsmb2. - Typed error stream -
Stream<MpvPlayerError>(sealed:MpvEndFileError,MpvLogError) replacesStream<String>. stream.endFile(MpvFileEndedEvent) for all file-end events, including premature EOF detection.stream.pausedForCacheandstream.demuxerViaNetworkfor network state monitoring.- Optional
timeoutparameter onregisterHookfor automatic safety continuation.
Fixed #
- Incorrect name for the audio-stream-silence property.
Build #
- Updated libmpv binaries from
libmpv-r1tolibmpv-r2across all platforms.
0.0.5 24-03-2026 #
0.0.4 23-03-2026 #
0.0.3+1 21-03-2026 #
Build #
- New tag system for versioning libmpv binaries (
libmpv-r1,libmpv-r2, …) to avoid conflicts with the pub version number on GitHub Releases.
0.0.3 21-03-2026 #
Changed #
- Linux: bumped minimum supported OS version to Ubuntu 24.04 - required because mpv 0.41.0 enforces a strict dependency on
libpipewire-0.3 >= 0.3.57for its native PipeWire backend.
Docs #
- Added a detailed Troubleshooting section in the README explaining how to correctly satisfy Linux system dependencies when building on containers.
Example #
- Fixed AO menu not showing the default driver automatically.
0.0.2+3 20-03-2026 #
Build #
- Updated Linux libmpv: ALSA, PipeWire, and PulseAudio now all work without external dependencies.