just_audio_windows_plus 0.1.0
just_audio_windows_plus: ^0.1.0 copied to clipboard
Thread-safe Windows platform implementation of just_audio using WinRT MediaPlayer. Fixes multi-threading race conditions and 0xC0000005 crashes.
just_audio_windows_plus #
A hardened, thread-safe Windows platform implementation of just_audio utilizing the Windows Media Foundation (WinRT Windows.Media.Playback.MediaPlayer) backend.
This package is a maintained community fork of just_audio_windows designed specifically to eliminate multi-threading race conditions, memory corruption, and fatal Access Violation (0xC0000005) crashes on Windows.
๐ The Problem in Upstream just_audio_windows #
In the original just_audio_windows:
- Threadpool Callback Contention: WinRT Media Foundation delivers playback state notifications (
PlaybackStateChanged,PositionChanged,MediaOpened) asynchronously on background Windows Threadpool worker threads. - Use-After-Free (
0xC0000005): When switching tracks, reciters, or audio sources rapidly in Flutter, the platform/UI thread callsdisposePlayer. The original C++ code resetevent_sink_and deleted the player instance without mutex synchronization. - While
Dispose()was resetting the pointer on Thread A, a background WinRT callback on Thread B was simultaneously callingevent_sink_->Success(...), dereferencing a dangling or null pointer and instantly crashing the desktop application with:Exception Code: 0xC0000005 (Access Violation) Fault Offset: 0x47c7f (just_audio_windows_plugin.dll) Lost connection to device. Exited. - Upstream maintenance of
just_audio_windowshas stalled, leaving open issues and unmerged pull requests.
๐ก๏ธ The Architectural Solution #
just_audio_windows_plus re-engineers the C++ plugin core with robust multi-threaded primitives:
- Thread-Safe EventSink: All
EventSinkemissions are guarded bystd::mutex sink_mutex_. - Atomic Lifecycle Transitions: Introduces
std::atomic<bool> disposed_{false}andstd::recursive_mutex player_mutex_to guarantee that player destruction and background WinRT events never collide. - Synchronized Global Registry: The
players_vector injust_audio_windows_plugin.cppis protected withstd::mutex players_mutex_. During disposal, the target player is moved out of the registry and destroyed safely outside the lock, preventing deadlocks. - Defensive WinRT Property Probing: Wrapped
NaturalDuration,BufferingProgress, andPositiongetters in structured exception handlers to prevent unhandled COM/WinRT exceptions during playlist track transitions.
๐ Getting Started #
Installation #
Add just_audio_windows_plus to your pubspec.yaml:
dependencies:
just_audio: ^0.9.44
just_audio_windows_plus: ^0.1.0
Overriding the Default Windows Plugin #
Because just_audio specifies just_audio_windows as its default Windows package, you can enforce just_audio_windows_plus across your entire project using dependency_overrides:
dependency_overrides:
just_audio_windows:
# Option A: Use git
git:
url: https://github.com/OmarAfifi-CSE/just_audio_windows_plus.git
# Option B: Use local path
# path: packages/just_audio_windows_plus
Or simply register it alongside just_audio in your dependencies:.
๐ป Usage #
Use just_audio exactly as you normally would. No changes to your Dart application code are required:
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final player = AudioPlayer();
await player.setUrl('https://example.com/audio.mp3');
await player.play();
}
Rapid track switching, continuous playlists, seeking, and concurrent audio operations will now execute reliably on Windows without process crashes.
๐งช Verification & Stability #
Tested under rigorous stress scenarios:
- 100+ consecutive track switches under heavy GPU/video load: 0 crashes.
- Verified zero memory leaks during repeated
AudioPlayercreation and disposal loops. - Fully compatible with 64-bit Windows 10 and Windows 11.
๐ Credits & License #
- Built upon the foundational work by Bruno D'Luka (@bdlukaa) and Ryan Heise (@ryanheise).
- Hardened, re-engineered, and maintained by Omar Afifi.
- Licensed under the MIT License. See LICENSE for details.