just_audio_windows_plus 0.5.3
just_audio_windows_plus: ^0.5.3 copied to clipboard
Hardened native Windows audio engine for Flutter: files, assets, streams, and playlists over WinRT MediaPlayer with full just_audio compatibility and a C++20 core.
0.5.3 #
- Completion Lifecycle Re-arm on Restart: Calling play() after a natural end now clears the native completed_ flag, so the plugin reports completed -> ready transitions instead of staying parked in completed forever. This lets just_audio re-arm completion listeners (fixing second-pass completion/repeat counting stalls in apps that restart from the completed state).
- Event Sink Delivery Retry: A transient exception while pushing a state/data event to Dart no longer silently drops that event - the send is retried once, and if the retry is also lost, a deduplicated full-state Broadcast() is scheduled on the player's dispatcher, re-delivering every field so Dart's belief always converges with the engine.
0.5.2 #
- Asynchronous Seek Position Integrity: WinRT applies
PlaybackSession.Position()asynchronously, so the previously-broadcast position after a seek (or the zero broadcast right after opening a media item with an initial position) reported stale or zero values that corrupted Dart-side verse/repeat bookkeeping. While a seek is landing on the media pipeline,Broadcast()now reports the requested target position instead of the stale one, matching ExoPlayer/AVPlayer behavior. SeekCompletedEvent Subscription: Subscribed to the official WinRTMediaPlaybackSession.SeekCompletedevent; it fires once the seek has officially settled, clears the in-flight flag, and rebroadcasts the truthful position.- Seek Flag Lifecycle Safety: The in-flight seek flag is reset on every new
load()and onMediaFailed, preventing a lostSeekCompleted(interrupted item switch, pipeline abort, disposal) from freezing position broadcasts forever. A 2-second safety deadline also re-enables truthful reporting if the completion event is lost. - Index-Changing Seek Protection: Seeks that switch playlist items (
seek(index: ...)) now mark the seek as in flight beforeMoveTo(), closing the window whereCurrentItemChangedbroadcast a zero position for the freshly opened item before the seek landed. - Root-Cause Fix for Repeated-Verse & Off-Target-Seek Bugs: Together, these fixes eliminate the Windows-only symptoms reported by Quran-style apps (first verse repeating 4x instead of 2x during repeat seeks, and seeking to a verse starting playback from the previous verse), caused by stale position broadcasts racing the asynchronous native seek.
0.5.1 #
- Documentation & Presentation: Refined visual styling, resized showcase screenshot for optimal desktop viewports, and ensured objective, neutral architectural comparison language in
README.md. - CI Quality Gate: Fixed GitHub Actions CI branch reference (
main) and streamlined the workflow to compile the Windows desktop runner and execute all 39 native C++ unit tests cleanly in headless cloud environments.
0.5.0 #
- Reliable Source Loading & Error Reporting: Pending loads now complete with the real duration or an actionable failure, including replacement and disposal; asynchronous playback failures surface through the playback event contract, so missing files and HTTP 404s no longer leave callers waiting.
play()Completion Semantics:await play()now resolves when playback pauses or finishes instead of returning immediately, andplayingstays true across buffering and completion untilpause(), matchingjust_audio's contract.- Teardown & Ownership Hardening: Native WinRT callbacks capture weak owners and post to the platform thread, and player ownership is scoped to the plugin registration; disposal settles pending loads and play futures exactly once.
- Loop, Nested Sources & Shuffle Correctness:
LoopMode.allconfigured before loading now advances through every item; nested concatenating/looping/clipping source trees load and mutate correctly; shuffle orders supplied with loads and mutations are honored in automatic progression. - Native Error Integrity & Unsupported Operations: Exception messages are owned so text survives to Dart unchanged; pitch and silence skipping return errors for unsupported values instead of silently succeeding, and direct custom request headers fail clearly with guidance toward
just_audio's proxy. - Empty-Playlist Mutations Attach the Source: Inserting into a playlist that was loaded empty now attaches the playback list to the player, so the first added item actually plays instead of staying silent.
- Truthful Index Broadcasting: While the initial load is pending, the requested initial index is reported instead of a transient native default, and an unknown current index is reported as null rather than a spurious
0, keeping Dart's sequence state synchronized from the first event. - Windows Playback Regression Runner: Added
tool/test_windows.ps1executing 25 playback scenarios against the compiled Windows plugin on real channels (Debug and Release), plus native C++ helper tests and CI execution. - Honest Documentation: Documented codec/deployment requirements, unsupported operations, and verification limits; removed unverified crash-free, gapless, and frame-rate claims.
0.4.0 #
- Linear Permutation Shuffle Engine: Replaced quadratic index-shifting with an $O(N)$ permutation mapping (
ReorderByShuffleOrder). Validates bounds, enforces element uniqueness, and rejects malformed shuffle arrays without corrupting playlist state. - Buffering Progress Clamping & NaN Defense: Introduced
ClampBufferedPositionwithstd::isfinitevalidation. Safely bounds buffer calculations within[0, duration], eliminating C++ undefined behavior and Dart assertion failures caused by transientNaNor>1.0progress values during live streaming. - Atomic Concurrency Synchronization: Upgraded
source_set_,loop_mode_, andshuffle_mode_tostd::atomicinplayer.hpp, eliminating data races between background WinRT threadpool callbacks and Flutter UI thread method calls. - Negative Seek Protection: Enforced
std::max<int64_t>(0, microseconds)inseekToPositionto prevent native WinRTE_INVALIDARG(0x80070057) exceptions. - Observable Native Error Logging & Brand Modernization: Modernized all native diagnostic logs and error reporting macros to
[just_audio_windows_plus], replacing silent emptycatch (...) {}blocks across primary playback and playlist operations (play,pause,stop,setVolume,setSpeed,setLoopMode,setShuffleMode,setShuffleOrder,seekToItem,seekToPosition) withJAW_ERRORmacros logging tostd::cerrfor clear diagnostic visibility without crashing. - Method Arguments Null Safety: Added defensive null-check guards across all parameterized method calls (
load,seek,setVolume,setSpeed,setLoopMode,setShuffleMode,setShuffleOrder,concatenatingInsertAll,concatenatingRemoveRange,concatenatingMove), returning descriptive channel errors instead of crashing from native null pointer dereferences. - Source State Transition Integrity: Deferred
source_set_state settlement until after source loading and initial seek settle successfully, with guaranteed rollback tofalseon any failure or disposal to prevent the player from getting stuck inloading(state 1). - Thread-Safe Dispatcher Teardown & Worker Thread Isolation: Synchronized window teardown and queue clearing under mutex in
~PlatformThreadDispatcher(). HardenedOnPlatformThreadto safely drop and trace events if the dispatcher is unavailable, strictly preventing background WinRT worker threads from invoking Flutter binary messenger or event sinks off the UI platform thread. - Unified Sovereign C++ Architecture: Renamed internal implementation to
windows/just_audio_windows_plus_plugin.cppand class toJustAudioWindowsPlusPlugin. Cleaned legacy exports to export exclusivelyJustAudioWindowsPlusPluginRegisterWithRegistrar. - Native C++ CI Quality Gate: Added automated Windows debug build (
flutter build windows --debug) in GitHub Actionsci.ymlto continuously verify MSVC compilation and C++ linkage. - Native Unit Test Suite: Added GoogleTest test cases in
uri_utils_test.cppcovering shuffle permutations, duplicate rejection, and buffer clamping edge cases.
0.3.0 #
- 64-bit Timestamp Safety: Introduced
TryGetInt64across all seeking, duration, and playlist mutations. StandardMessageCodec encodes timestamps exceeding 35.7 minutes ($2^{31}-1$ microseconds) asint64_t, which previously failed silently under 32-bitstd::get_if<int>. - Exact Microsecond Precision: Replaced lossy truncated millisecond arithmetic with exact 64-bit microsecond conversions (
TimeSpanToMicroseconds), preserving sub-millisecond timeline accuracy. - Event Channel Teardown Hygiene: Explicitly unregistered binary message handlers in
JustAudioEventSinkdestructor to eliminate dangling callbacks and post-disposal access violations (0xC0000005). - Defensive Playlist Mutations & Bounds: Fully bounds-checked
concatenatingMove,concatenatingInsertAll, andconcatenatingRemoveRangeto eliminate native WinRTE_BOUNDSexceptions during rapid playlist modifications. - Accurate Looping & Shuffling: Ensured
LoopMode.allloops single tracks seamlessly and synchronized internalloopModeandshuffleModestate broadcasts back to Flutter. - Native MediaEnded Event: Subscribed to WinRT
MediaPlayer.MediaEndedfor instantaneouscompletedstate signaling upon track finish. - Clipping Audio Source Hardening: Enforced non-negative start offsets and validated duration boundaries for
ClippingAudioSource. - Clean Codebase Hygiene: Removed obsolete legacy files (
url_code.hpp) and unused methods (GetPlayerByPlayerId). - Pub.dev Package Showcase: Added official package screenshots metadata in
pubspec.yaml.
0.2.0 #
- Platform Thread Dispatcher: Marshals all WinRT event callbacks (
PlaybackStateChanged,MediaFailed,CurrentItemChanged,ItemFailed) onto Flutter's UI platform thread via a Win32 message-only window (HWND_MESSAGE). Completely eliminates engine warnings:channel sent a message from native to Flutter on a non-platform thread. - C++20 Toolchain Upgrade: Built with
CMAKE_CXX_STANDARD 20to fix compilation errorC2338 / STL1011under Visual Studio 2026 / MSVC 14.51 where experimental coroutines are deprecated. - Defensive Playlist Transitions: Eliminates crashes and buffering errors when skipping tracks rapidly in
ConcatenatingAudioSource. Removed prematurebroadcastState()inseekToItem()and defensively guardedNaturalDuration,Position, andBufferingProgressWinRT property queries. - Source Swap Interruption Fix: Fixes
PlayerInterruptedException('Loading interrupted')on source swaps by preventing gaps during playlist clearing from being falsely reported asidle. - Duration Gated Completion: Requires
NaturalDuration() > 0before emittingcompleted(state 4), preventing freshly loaded clips from prematurely reporting completed. - Robust Exception Handling: Catches
winrt::hresult_errorandstd::exceptioninloadand method calls, returning proper Dart errors instead of crashing the process viastd::terminate. - SMTC De-conflict: Disables
mediaPlayer.CommandManager().IsEnabled(false)to prevent blank OS media overlays and desynchronized hardware media keys. - Debug-Gated Tracing: Verbose method call logging is gated behind
JAW_TRACEunder#ifndef NDEBUG, preventing console flood in production. - Thread-Safe Mutex Hardening: Added
std::mutex players_mutex_for the global player registry andstd::mutex sink_mutex_for event sinks. Safely destroys players outside lock to eliminate0xC0000005Access Violations on player disposal, stop, and hot restart. - Full Drop-in Compatibility: Fully implements the
just_audioplatform interface for Windows.
0.1.0 #
- Initial release of
just_audio_windows_plus. - Thread-Safe EventSink: Synchronized Flutter
EventSinkcalls viastd::mutexto prevent concurrent writes from background WinRT threadpool worker threads. - Atomic Player Lifecycle: Introduced
std::atomic<bool> disposed_andstd::recursive_mutex player_mutex_to safely coordinate player destruction and prevent Use-After-Free Access Violations (0xC0000005). - Safe Plugin Registrar: Protected the global player registry (
players_vector) with a dedicated mutex during concurrent creations and disposals. - Defensive WinRT Property Probing: Wrapped
NaturalDuration,BufferingProgress, andPositionaccess in exception handlers to gracefully handle transient states during playlist transitions. - Full Drop-in Compatibility: Fully implements the
just_audioplatform interface for Windows.
