just_audio_windows_plus 0.4.0 copy "just_audio_windows_plus: ^0.4.0" to clipboard
just_audio_windows_plus: ^0.4.0 copied to clipboard

PlatformWindows

High-performance, seamless audio player for Flutter on Windows. Effortlessly play audio files, live streams, and playlists powered by native C++20 WinRT MediaPlayer.

just_audio_windows_plus #

pub package pub points License: MIT Platform: Windows Standard: C++20 GitHub

High-performance, seamless native audio player for Flutter on Windows desktop.

Play internet audio streams, local audio files, sound effects, and gapless playlists effortlessly in your Flutter desktop applications. Powered by native Windows Media Foundation (WinRT Windows.Media.Playback.MediaPlayer) and modern C++20, just_audio_windows_plus gives you a fast, reliable, and production-grade audio experience right out of the box.

just_audio_windows_plus Showcase


πŸ“‹ Windows Platform Feature Matrix #

Feature Windows Support Notes / Underlying Architecture
Audio from URL βœ… HTTP / HTTPS progressive streams
Audio from File βœ… Absolute local disk paths with Unicode handling
Audio from Asset βœ… Flutter bundled package assets
HLS Streams (.m3u8) βœ… Native Media Foundation HLS tag support
DASH Streams (.mpd) βœ… Windows native DASH profile playback
Gapless Playlists βœ… Native MediaPlaybackList with zero transition delay
Play / Pause / Seek βœ… Frame-accurate seeking with reactive position stream
Buffering Progress βœ… Real-time bufferingProgress event stream
Variable Playback Speed βœ… 0.5x to 2.0x pitch-corrected playback
Volume Adjustment βœ… 0.0 (silent) to 1.0 (full scale)
Looping & Shuffling βœ… LoopMode.off, one, all & custom shuffle algorithms
Error Handling βœ… Structured PlayerException mapped from WinRT HRESULT
Permutation Shuffling βœ… Exclusive to Plus: $O(N)$ bounds-checked shuffle engine
Buffering NaN Protection βœ… Exclusive to Plus: Guaranteed bounded buffer progress
UI Platform Thread Safety βœ… Exclusive to Plus: Marshals to UI thread (HWND_MESSAGE)
Modern C++20 Toolchain βœ… Exclusive to Plus: Seamless MSVC 14.40+ / VS 2026 build
Atomic Player Lifecycle βœ… Exclusive to Plus: Zero 0xC0000005 access violations
Clean SMTC Separation βœ… Exclusive to Plus: Conflict-free with audio_service

⚑ 30-Second Quickstart #

Using just_audio_windows_plus is as simple as it gets. You use the standard, beloved just_audio API:

import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final player = AudioPlayer();
  
  // Play an internet audio stream or local file in two lines
  await player.setUrl('https://server10.mp3quran.net/minsh/001.mp3');
  await player.play();
}

🌟 What You Can Build #

  • πŸ”Š All Modern Audio Formats: Native support for MP3, AAC, WAV, FLAC, M4A, as well as live HTTP/HTTPS, HLS, and DASH streams.
  • πŸ“‘ Dynamic Playlists: Next/previous track navigation, shuffling, looping, and gapless transitions with ConcatenatingAudioSource.
  • ⏩ Smooth Seeking & Scrubbing: High-precision timeline scrubbing with reactive position streams.
  • 🎚️ Fine-Grained Controls: Variable playback speed (0.5x to 2.0x), volume adjustment, looping modes, and silence skipping.
  • πŸ–₯️ Native Windows Architecture: Uses Windows Media Foundation built directly into Windows 10 and 11. Zero extra DLLs or runtimes to package.
  • πŸ›‘οΈ Rock-Solid Stability: Fully hardened with thread-safe mutexes and platform-thread dispatching to ensure your desktop app never stutters, locks up, or crashes.

πŸ“¦ Installation #

Path 1: For New Flutter Projects #

Add just_audio_windows_plus alongside just_audio in your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  just_audio: ^0.10.6 # Full compatibility with ^0.10.x and ^0.9.x
  just_audio_windows_plus: ^0.4.0

Path 2: Instant Upgrade for Existing Projects #

If your project already uses just_audio, simply add just_audio_windows_plus to your dependencies. Flutter's federated plugin system automatically selects just_audio_windows_plus as the Windows platform implementation, giving you full C++20 reliability and zero crashes with zero changes to your existing Dart code:

dependencies:
  just_audio: ^0.10.6
  just_audio_windows_plus: ^0.4.0

Tip (Testing via Git): If you wish to track the latest unreleased developments from GitHub:

dependencies:
  just_audio_windows_plus:
    git:
      url: https://github.com/OmarAfifi-CSE/just_audio_windows_plus.git

πŸ› οΈ Code Recipes & Examples #

1. Continuous Playlists & Track Navigation #

Easily queue multiple tracks, navigate between recordings, and listen for index changes:

// Works natively with modern just_audio 0.10.x setAudioSources
await player.setAudioSources([
  AudioSource.uri(Uri.parse('https://server10.mp3quran.net/minsh/001.mp3')),
  AudioSource.uri(Uri.parse('https://server10.mp3quran.net/minsh/112.mp3')),
  AudioSource.uri(Uri.parse('https://server10.mp3quran.net/minsh/113.mp3')),
]);
await player.play();

// Smoothly skip tracks without UI stutter
await player.seekToNext();
await player.seekToPrevious();

2. Local Audio Files & Flutter Assets #

// Local file paths (handles spaces and international Unicode characters cleanly)
await player.setFilePath(r'C:\Audio\Recordings\01 Surah Al-Fatihah.mp3');

// Flutter bundled assets
await player.setAsset('assets/audio/notification.wav');

3. Playback Controls & Speed #

// Volume control (0.0 silent to 1.0 full)
await player.setVolume(0.8);

// Variable playback speed (e.g. 0.75x, 1.25x, 1.5x)
await player.setSpeed(1.25);

// Loop modes (off, one, all)
await player.setLoopMode(LoopMode.all);

// Shuffle mode
await player.setShuffleModeEnabled(true);

4. Complete Ready-to-Copy Player Widget #

Here is a full Flutter widget featuring a seek bar, real-time position timestamps (01:23 / 03:45), and play/pause controls:

class DesktopAudioBar extends StatelessWidget {
  final AudioPlayer player;

  const DesktopAudioBar({super.key, required this.player});

  String _formatDuration(Duration? d) {
    if (d == null) return '--:--';
    final minutes = d.inMinutes.remainder(60).toString().padLeft(2, '0');
    final seconds = d.inSeconds.remainder(60).toString().padLeft(2, '0');
    return '$minutes:$seconds';
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<Duration?>(
      stream: player.durationStream,
      builder: (context, durationSnapshot) {
        final duration = durationSnapshot.data ?? Duration.zero;

        return StreamBuilder<Duration>(
          stream: player.positionStream,
          builder: (context, positionSnapshot) {
            var position = positionSnapshot.data ?? Duration.zero;
            if (position > duration) position = duration;

            return Row(
              children: [
                StreamBuilder<PlayerState>(
                  stream: player.playerStateStream,
                  builder: (context, snapshot) {
                    final isPlaying = snapshot.data?.playing ?? false;
                    return IconButton(
                      icon: Icon(isPlaying ? Icons.pause_circle_filled : Icons.play_circle_filled),
                      iconSize: 42,
                      onPressed: () => isPlaying ? player.pause() : player.play(),
                    );
                  },
                ),
                Text(_formatDuration(position)),
                Expanded(
                  child: Slider(
                    min: 0.0,
                    max: duration.inMilliseconds.toDouble(),
                    value: position.inMilliseconds.toDouble().clamp(0.0, duration.inMilliseconds.toDouble()),
                    onChanged: (value) {
                      player.seek(Duration(milliseconds: value.round()));
                    },
                  ),
                ),
                Text(_formatDuration(duration)),
              ],
            );
          },
        );
      },
    );
  }
}

πŸ”¬ Under the Hood: Built for Production Reliability #

Developing desktop audio on Windows requires handling native COM/WinRT events and background threads gracefully. just_audio_windows_plus was engineered specifically to address common desktop audio pitfalls:

  • Platform Thread Dispatcher (platform_thread.hpp): WinRT Media Foundation delivers playback callbacks on background threadpools. We marshal these events onto Flutter's UI platform thread via a dedicated Win32 message window (HWND_MESSAGE). This ensures zero non-platform thread engine warnings and zero dropped events.
  • Thread-Safe Mutex & Concurrency Hardening: All internal player registries and event sinks are synchronized with std::mutex and atomic variables (std::atomic<bool> source_set_, loop_mode_, shuffle_mode_), preventing data races and Access Violations (0xC0000005) during rapid track changes, hot-reload, and teardown.
  • Permutation-Safe Playlist Shuffling (native_utils.hpp): Employs a linear $O(N)$ permutation mapping (ReorderByShuffleOrder) with strict validation to prevent index corruption, out-of-bounds access, and duplicate item insertion during playlist shuffles.
  • Live-Stream Buffering Defense: Guards progress calculations with ClampBufferedPosition, preventing NaN and out-of-range floats from triggering assertion failures in Dart during dynamic network changes.
  • Modern C++20 Standard: Built with CMAKE_CXX_STANDARD 20, ensuring seamless compilation with Visual Studio 2026 and modern MSVC toolchains (eliminating STL1011 coroutine deprecation errors).
  • Clean System Media Separation: Disables automatic lockscreen flyout hijacking (mediaPlayer.CommandManager().IsEnabled(false)), allowing apps to optionally manage media keys via audio_service without conflicts.
  • Diagnostic Native Logging: Replaced silent empty catch blocks with structured JAW_ERROR diagnostics, while tracing logs are gated behind JAW_TRACE under #ifndef NDEBUG, preventing console flood in production.

πŸ›οΈ Architectural Comparison #

How just_audio_windows_plus compares to legacy implementations:

Feature / Capability Legacy just_audio_windows (0.2.3) just_audio_windows_plus
Platform Thread Dispatching ❌ Background Threadpool (Engine warnings) βœ… Win32 Message Window (HWND_MESSAGE)
C++ Toolchain Standard ❌ C++17 (Fails on MSVC 14.51 / VS 2026 STL1011) βœ… C++20 Native Coroutine Standard
Concurrency & Thread Safety ❌ Unguarded raw pointers (Fatal 0xC0000005) βœ… std::mutex + std::atomic Lifecycle
Playlist Shuffling Engine ❌ $O(N^2)$ erase-insert (corrupts indices) βœ… $O(N)$ Permutation-Safe Engine (native_utils.hpp)
Buffering Progress Defense ❌ Unchecked float (NaN/Inf crashes Dart) βœ… Guarded ClampBufferedPosition
Playlist Rapid Skipping ❌ Freezes BufferingProgress / Crashes βœ… Defensive WinRT Probing (Zero-Crash)
Source Swap Handling ❌ Falsely signals idle mid-swap (Aborts load) βœ… Protected source_set_ State Guard
Initial Load Duration ❌ Falsely evaluates 0 == 0 as completed βœ… NaturalDuration > 0 Gating
Exception Resiliency ❌ catch(char*) escapes to std::terminate βœ… Structured hresult_error & std::exception
Native Error Visibility ❌ Empty catch(...) (Silent runtime failure) βœ… Diagnostic JAW_ERROR Logging
System Media Flyout ❌ Hijacks lockscreen with blank info βœ… Clean Separation (De-conflicted SMTC)
Release Log Overhead ❌ Floods terminal on every volume/seek βœ… Silent Release Builds (JAW_TRACE)
Maintenance Status ⚠️ Abandoned (>2 years without pub update) πŸš€ Actively Maintained & Production Ready

❓ Frequently Asked Questions (FAQ) #

Q: Do my users need to install any external C++ runtimes or codecs?

No. just_audio_windows_plus uses Windows Media Foundation (WinRT Windows.Media.Playback.MediaPlayer), which is pre-installed on every Windows 10 and 11 machine. It compiles directly into your Flutter executable.

Q: What audio formats are supported?

All standard formats supported by Windows Media Foundation: MP3, AAC, WAV, FLAC, M4A, WMA, as well as HTTP/HTTPS, HLS, and DASH streams.

Q: Can I run multiple AudioPlayer instances simultaneously?

Yes. All internal state, channels, and event sinks are fully isolated and thread-safe per player instance.

Q: How do I handle background audio or keyboard media keys?

Because just_audio_windows_plus cleanly opts out of automatic SMTC hijacking, you can use audio_service to manage keyboard media keys and OS lock screen widgets with complete control.


πŸ§ͺ Stress Benchmarks & Verification #

  • 100+ Rapid Consecutive Seeks & Track Switches: 0 crashes, 0 unhandled COM exceptions, 0 deadlocks.
  • Resource Leak Audits: Verified complete destruction of WinRT objects and Flutter channels upon player disposal.
  • 120 FPS Zero-Jank Conformance: Background media notifications do not block the Windows UI message loop.

πŸ“œ Author & License #

  • Engineered, hardened, and maintained by Omar Afifi (@OmarAfifi-CSE).
  • Foundational heritage credited to Bruno D'Luka and Ryan Heise.
  • Licensed under the MIT License. See LICENSE for details.
2
likes
160
points
--
downloads
screenshot

Documentation

API reference

Publisher

verified publisheromar-afifi.com

Weekly Downloads

High-performance, seamless audio player for Flutter on Windows. Effortlessly play audio files, live streams, and playlists powered by native C++20 WinRT MediaPlayer.

Repository (GitHub)
View/report issues

Topics

#audio #windows #just-audio #audio-player #media-player

License

MIT (license)

Dependencies

flutter

More

Packages that depend on just_audio_windows_plus

Packages that implement just_audio_windows_plus