A simple cross-platform audio playback library with SimpleAudioPlayer.Native (LGPL-2.1+) backend, supporting multiple audio formats and streaming protocols.
- 🎵 Common audio formats support (via FFmpeg decoding)
- 📁 Multi-protocol handling: local files, HTTP streams, custom streams
- ⏯️ Basic playback controls: Play/Stop/Pause/Seek
- ⏲️ Track duration and progress monitoring
- 🔧 Extensible stream handling system (custom data sources)
- Native dependency updated to SimpleAudioPlayer.Native 2.3.1.
- Restored ARM/ARM64 NEON assembly on Linux and Android (via
-Bsymbolic).
- Native dependency updated to SimpleAudioPlayer.Native 2.3.0.
- FFmpeg assembly optimizations enabled (x86_64 SSE/AVX via nasm on macOS/Windows).
- Fixed tail-of-file residual data being reported as a decode error instead of natural EOF.
- Added
AudioPlayerOptionsfor output usage, content type, latency preference, sharing mode, and buffer tuning. - Defaults now use the device-native sample rate and a stable Media/Music playback configuration.
- Native dependency updated to SimpleAudioPlayer.Native 2.2.0.
- Playback failures now surface through
PlaybackFailedandPlaybackState.Error. - HTTP stream handlers report I/O failures instead of silently treating broken streams as EOF.
ProgressiveHttpStreamHandlesupports play-while-downloading to a final local file.DiskCachedStreamHandlecaches streamed data on disk to avoid holding large files in memory.
Install-Package SimpleAudioPlayer -Version 2.3.1// Create player instance
var player = new AudioPlayer();
// Use file stream (local path)
player.Load(new FileStreamHandler("song.mp3"));
// Get total duration in seconds
var duration = player.GetDuration();
// Playback controls
player.Play();
player.Stop();
player.Pause();
// Progress operations
var currentTime = player.GetTime();
player.Seek(30);The defaults target stable music playback with the device's native sample rate, media usage, music content, and shared output. Real-time workloads can opt into low latency:
var player = new AudioPlayer(new AudioPlayerOptions
{
LatencyMode = AudioLatencyMode.LowLatency,
Usage = AudioPlaybackUsage.Game,
ContentType = AudioContentType.Sonification,
SampleRate = 0, // Use the device's native sample rate.
ShareMode = AudioShareMode.Shared
});Usage and ContentType map to backend settings where supported and safely retain platform defaults elsewhere. PeriodSizeInMilliseconds and Periods are available for advanced buffer tuning; leave them at 0 to use backend defaults.
player.PlaybackStateChanged = state =>
{
Console.WriteLine($"Playback state: {state}");
};
player.PlaybackFailed = args =>
{
Console.WriteLine($"Playback failed: {args.Result}");
Console.WriteLine(args.Exception);
};var handle = await ProgressiveHttpStreamHandle.CreateAsync(
"https://example.com/song.mp3",
"song.mp3",
overwrite: true);
handle.ProgressChanged += (downloaded, total) =>
{
Console.WriteLine($"{downloaded}/{total}");
};
handle.DownloadStateChanged += (_, args) =>
{
Console.WriteLine($"Download state: {args.State}");
};
player.Load(handle);
player.Play();ProgressiveHttpStreamHandle keeps incomplete data in song.mp3.part and writes a compact binary song.mp3.part.idx index. By default resume: true reuses valid cached ranges, including ranges downloaded after seeking. If the URL identity or remote validators do not match, the partial cache is discarded and rebuilt.
using var input = await httpClient.GetStreamAsync("https://example.com/song.mp3");
using var handle = new DiskCachedStreamHandle(input);
player.Load(handle);
player.Play();DiskCachedStreamHandle is the stream-based play-while-downloading path. When no cache path is provided, it writes to a temporary .part file and deletes it on dispose. It advertises seek support when the source stream itself is seekable. For non-seekable streams, pass enableSeek: true only when cache-backed seeking after data has arrived is required.
To keep a completed stream as a cache file, pass a final cache path and enable commit-on-complete:
using var handle = new DiskCachedStreamHandle(
input,
totalSize: contentLength,
cacheFilePath: "song.mp3",
commitCacheOnComplete: true);This writes to song.mp3.part while reading. Only a complete stream is moved to song.mp3; failed or incomplete streams delete the temporary .part file.
| Handler Type | Description |
|---|---|
FileStreamHandler |
Local file stream |
HttpStreamHandle |
HTTP network stream |
StreamHandle |
Generic stream (requires Stream object) |
CustomHandle |
Fully customizable implementation |
CachedStreamHandle |
Caching support for network streams |
DiskCachedStreamHandle |
Disk-backed cache for large streams |
ProgressiveHttpStreamHandle |
HTTP play-while-downloading with a final local file |
- Audio playback via miniaudio
- Audio decoding via FFmpeg
- Native component: SimpleAudioPlayer.Native 2.3.1 (LGPL-2.1+)
License - Main project: MIT License
- Native component: LGPL-2.1+
Important Compliance Notice:
When distributing software using this library, you MUST:
- Provide access to LGPL-licensed component's source code
- Allow end-users to replace the LGPL component
- Include full license texts
- Steps to reproduce issues
- Relevant logs/error messages
- Environment details (OS/.NET version etc.)