Artificial truth

The more you see, the less you believe.

[archives] [latest] | [homepage] | [atom/rss]

Airsonic, a self-hosted jukebox that sucks less
Tue 10 March 2020 — download

At my previous job, I used YouTube to listen to music, but this wasn't optimal, especially now that Google™ is trying to push Youtube Red/ Youtube premium/ Youtube Music/ Youtube Music Premium/ Google Play Music/… Moreover, not everything is on YouTube, and I'm not a big fan of Google knowing what kind of music I'm listening to, from where I'm listening to it, when I'm doing it, and being able to arbitrarily delete content that I like.

I wanted something open-source, maintained and maintainable, without gaping security holes, with a web-interface, a nice smartphone client, able to handle ~50.000 tracks on something like a raspberry pi.

Rejected candidates

Sonerezh isn't actively developed, isn't tailored for large music collections.

Koel looks amazing, but it's not comfortably useable on a mobile device yet, and has a ton of dependencies.

Ampache while being maintained, is written in PHP, and with all the changes that are pouring into PHP7/PHP8, I'm not super-confident about its future. Moreover, writing secure php is highly non-trivial, let alone for something like a media player (LAN access, database, transcoding, external processes, files management, user management, …). Finally, on a side note, its user interface looks a bit ugly.

Funkwhale looks nice, but: - it's still a young project: no way to refresh the database, no way to hide artists from compilations, … - it's social-oriented with a ton of scary features that I don't use not like federation, creator profiles, … - the setup and maintenance are beyond awful.

Supysonic looked super-cool, but there is only one client-side web interface for the subsonic API, Jamstash which isn't maintained and uses JPlayer who has seen its last commit 5 years ago.

There is also gonic, which is like supysonic, but more modern and in go. Unfortunately, it also doesn't provide a web interface to play music.

I had a look at Jellyfin, but unfortunately the project is still a bit young: it doesn't handle large collections very well, and lacks a couple of features. Also, it's written in C# :/

Navidrome looks promising, but the webui isn't really useable yet.

Subsonic and madsonic are not open-source, libresonic isn't maintained.


So I settled for airsonic:

  • the deployment is trivial, just download a .war and launch it.
  • the interface is usable and doesn't feel clunky
  • the whole thing is snappy even with multiple clients and a large library
  • it's exposing a subsonic API, meaning that there are a lot of compatible mobile clients available for every platform
  • scanning/cleaning the database is fast and idempotent
  • it written in something that I know: java.

Unfortunately, it's a big pile of steaming old-school Java code running in Tomcat, based on libresonic, which is based on subsonic, which was created in 2004.

Since I've only "managed" java things via meterpreter, it was an interesting opportunity to see things from the other side: how can I make this software more secure, so that I can sleep at night. I also wanted to make it more sustainable, so that I don't have to deploy something else in one year. So this is, amongst other things, what I did during the last year:

  • Added sandboxing via systemd, making the whole filesystem as readonly, blacklisting syscalls, whitelisting sockets types, …
  • Removed external fonts usage, increasing both privacy and response time
  • Bumped a fuckton of dependencies, and removed as much as I could
  • Fixed several low-hanging XSS
  • Fixed the low-entropy password-recovery generation
  • Removed dangerous "features"
  • Removed all traces of Flash.
  • Added noopener and noreferrer to external urls.
  • Changed as much http: to https: as possible.
  • Modernized a bit the codebase, since nobody should run Java5 anymore.
  • Simplified a bit the travis-ci configuration, thus improving the CI feedback time, while also pushing to make airsonic compatible with newer java runtime versions
  • Added the project to coverity and LGTM, then started to fix the most dramatic issues. I also added codecov integration to visualise the testsuite's coverage.
  • Pushed, along with eharris, for more checkstyle rules, to make the review more pleasant/automated/inclusives/…
  • Removed a much javascript library as possible, making use of jQuery instead
  • Simplified a lot of code, and removed unused parts.
  • Replaced all the icons with SVG, to make airsonic look pretty even on high resolutions.
  • Replaced hardcoded strings with constants.
  • Added accessibility attributes everywhere.
  • Fixed a couple of crashes, and gracefully handled those that couldn't be fixed.
  • Removed WAP-related code.
  • Applied (but got rejected) for the Google Summer of Code.

The next big things to do are to refactor the frontend, and to bump the version of Spring, but since I do suck at both, someone else will have to do it.

Anyway, I'm quite happy with airsonic for now, and so are my users, but I'm still looking to get rid of it, and to replace it with something both more simple and modern :/