Systems
Melofin - Native Linux YouTube Music Client
Melofin is what happens when you want YouTube Music on Linux but refuse to use Electron. Built from scratch in Rust with GTK4 and libadwaita, it uses yt-dlp for search, mpv for gapless playback controlled via JSON IPC, and full MPRIS integration so your keyboard media keys and desktop widgets just work. The architecture runs the player in a separate tokio thread communicating with the UI via async channels — keeping the interface responsive even during buffering.

Project Goals
- Build a YouTube Music client that feels native on GNOME, not a web wrapper.
- Get gapless playback working reliably — YouTube's audio stream segmentation makes this hard.
- Integrate with MPRIS so media controls, notifications, and desktop widgets work automatically.
- Learn Rust properly by building something real, not just tutorials.
My Process
Started with the mpv IPC controller — proved I could start, stop, seek, and get position updates from mpv via JSON commands. Then built the GTK4 UI around it, connecting the two with tokio async channels. Features were added one at a time: search, playback, home feed, liked songs, and finally MPRIS. Each feature was a mini-project that taught me something new about Rust's ownership model.
Challenges & Solutions
Challenge:
YouTube's InnerTube API is undocumented and reverse-engineered — it changes without notice and breaks authentication.
Solution:
Built a resilient InnerTube client with automatic cookie refresh from the browser using the `rookie` crate, and fallback search via yt-dlp.
Challenge:
mpv sends JSON IPC responses on a single file descriptor, so you have to demux commands and responses yourself.
Solution:
Created a command-response mapping system with oneshot channels — each IPC command gets a unique ID, and the response handler routes it back to the caller.
Challenge:
GTK4's signal system doesn't play well with Rust's borrow checker — every callback needs careful lifetime management.
Solution:
Used `glib::spawn_future_local` to bridge tokio futures into GTK's event loop, with `Rc<RefCell<>>` for shared state across signal handlers.
Key Learnings
- Rust's ownership model forces you to think about data flow upfront — it's annoying at first but catches real bugs at compile time.
- GTK4 with Rust is viable but underdocumented — most examples are in Python or C, so you end up reading the C API docs and translating.
- MPRIS is surprisingly simple once you understand D-Bus — it's just a set of well-defined properties and methods.
Gallery



