Jakob Gillich Personal blog

CloudFM

Over the last few months, I’ve been working on a next-generation music player for the age of “servers connected to the internet”, also known as the “cloud”. Because I am bad at naming things, I called it CloudFM.

You don’t actually need to click the link, because there’s nothing to see there. I’m mainly putting this out there because I want to regularly share progress I’ve made. But let’s start with what I’ve done so far.

Why I’m doing this

Long story short, I loved Rdio, then Rdio shut down. Turns out the alternatives aren’t as good as Rdio and a lot of them even require Flash (2016??). I switched to Subsonic, which works ok, but Rdio was just so much better in so many ways. So I’m building my own thing instead.

CloudFM is a music player that integrates a plethora of cloud services (think Spotify, YouTube, Dropbox, SoundCloud and more) into a single player interface. Since mobile internet is expensive and not always available, I want to make it offline-capable as much as possible. And nowadays, you have so much storage space on your phone, meanwhile your tiny SSD on your notebook is constantly running out of space - CloudFM will let you store your music on your phone, and listen to it on your desktop.

Micro-services written in Rust

To be honest, I did not intend to use a micro-service architecture from the start. I actually wrote a monolithic server first, until I realized: I’m going to need a lot of this code at different places. For example, indexing code will have to run on the server side, but also as part of a GUI desktop app. That is why I turned my server into a library that compiles to a couple of binaries:

  • indexd: The indexing daemon, it indexes music from various online services (and local files).
  • proxyd: Give it a track ID, it will respond with a audio file, not matter where it is stored. In the future, it will also do things like on the fly re-encoding of files, and more.
  • manager: A desktop app, to index and serve local files. Will probably use the excellent GTK bindings for Rust. Or maybe the Qt Quick bindings, because GTK isn’t actually that great on platforms other than Linux. Ideally, both.

Web app written in TypeScript/React/Redux

Initially, I started writing it in Elm. It was an interesting experiment, and there are a lot of things I like about the language, but the cons didn’t quite outweight the pros. The short version: The language has a few shortcomings even in its domain (web apps), the ecosystem is rather small, integrating existing JavaScript libraries and APIs is a lot of work.

Searching for an alternative, I decided to use TypeScript first. I treat it as a very powerful linter, if your code passes the linter (compiles), it’s very likely correct. Less edit-tab-reload-tab-edit, more instant feedback through your editor. While the type system is not as good as Rust’s, and Redux is not very TypeScript-friendly, I do not regret it at all, partially because of the awesome TypeScript integration in Visual Studio Code.

Choosing a front-end framework was a really straightforward process: I knew I wanted a native mobile app, because hybrid apps just aren’t that great. And since we bascially require PouchDB for offline availability of the database, React and React Native are pretty much the only viable option. Together with Redux, we’ve got a pretty nice and Elm-like stack with a big ecosystem.

What works

It’s been a bit over a week since I started rewriting the web app, and here’s what it looks like:

This is just a very early prototype, expect things to change, a lot. A lot of the features you’d expect from any player aren’t there, yet. The design will also definitely change in the future.

What’s not visible on the screenshot is that the music is not just local, but also from Jamendo. In the future, a lot more backends will follow.

What’s next

My goals for this week:

  • Continue work on my WebDAV client for Rust and then implement the WebDAV backend
  • Make the web app usable for everyday listening
  • Start working on a Musicbrainz client
  • Read Design for Hackers