mpv_audio_kit 0.1.1
mpv_audio_kit: ^0.1.1 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.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.