sorairo

A minimal, local, cross-platform music player built with Avalonia and miniaudio.

Approaches

GUI Framework

My goal was to build a cross-platform music player app that is highly customizable and optimized for resource usage. At this point, any WebView/CEF framework is out of the table. And I went to try a few frameworks in Rust and C# and built POC in each of them.

FrameworkLanguageVerdictDescription
eguiRustA well-known immediate-mode GUI framework in Rust community but it doesn't suit a music player app that is intended for running in the background most of the time. I'm keeping a branch for the egui version of this app and idle CPU usage was the reason why I migrated away from this framework.
fltk-rsRustBest performance (~8mb RAM, ~0% CPU in my POC version with fltk-rs). However, it is hard and troublesome to do layout properly, achieve a modern UI look and a reactive style codebase.
Avalonia UIC#The sweet spot. It is retained, cross-platform, and performant enough that resizing doesn't cause flickering. The app currently stays at 30-70MB memory footprint and ~0.8% idle CPU. And it's future-proofing for my visualizer feature in the future where I need to do low-level rendering. I find it pretty impressive for what it is capable of.

Playback Engine

For the audio playback, I chose miniaudio, a robust cross-platform library in C that supports .mp3, .ogg, .wav at the cost of just a header file. To use it in C#, I'm using an existing C# library that provides bindings to the functions in C.

Roadmap

I've pulled the first usable cross-platform version recently. And there are lots of work to be done still.

  • Responsive GUI with Avalonia
  • Cross-platform playback with miniaudio
  • File metadata read (ATL.NET)
  • File metadata write utilities (ATL.NET)
  • Playback modes: shuffle, repeat.
  • Adding sources from YouTube (yt-dlp on-demand)
  • Basic audio visualization
  • Discord RPC option
  • Drag and drop songs
  • Audio normalization (embedded rsgain)
  • Release packaging (Velopack)
  • Light & dark mode

Performance

Ran on my win-x64 with the following results:

MetricValue
Startup time~1s
Memory usage (startup)~35 MB
Memory usage (20 songs)~43 MB
Memory usage (playback)~50 MB
CPU usage (idle)~0%
CPU usage (playback)~0.5%