Title: Airsonic, a self-hosted jukebox that sucks less
Date: 2020-03-10 13:45

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](https://en.wikipedia.org/wiki/YouTube_Red)/
[Youtube premium](https://en.wikipedia.org/wiki/YouTube_Premium)/
[Youtube Music](https://en.wikipedia.org/wiki/YouTube_Music)/
[Youtube Music Premium](https://www.youtube.com/musicpremium)/
[Google Play Music](https://en.wikipedia.org/wiki/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](https://www.sonerezh.bzh/) [isn't actively
developed](https://github.com/Sonerezh/sonerezh/pulse/monthly), isn't tailored
for *large* music collections.
	
[Koel](https://koel.phanan.net/) looks amazing, but it's not comfortably useable on a
mobile device [yet](https://github.com/phanan/koel/issues/1085),
and has a [ton of](https://github.com/phanan/koel/blob/master/yarn.lock)
[dependencies](https://github.com/phanan/koel/blob/master/composer.json).

[Ampache]( http://ampache.org/ ) while [being
maintained](https://github.com/ampache/ampache/commits/develop ), 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](https://funkwhale.audio/) looks nice, but:
- it's still a young project: no way to [refresh the database](https://dev.funkwhale.audio/funkwhale/funkwhale/issues/741),
  no way to [hide artists from compilations](https://dev.funkwhale.audio/funkwhale/funkwhale/issues/736), …
- 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](https://docs.funkwhale.audio/installation/index.html).

[Supysonic]( https://github.com/spl0k/supysonic) looked super-cool, but there
is only one client-side web interface for the subsonic API,
[Jamstash](https://github.com/tsquillario/Jamstash) which isn't maintained
and uses [JPlayer](https://github.com/jplayer/jPlayer/commits/master) who has
seen its last commit 5 years ago.

There is also [gonic](https://github.com/sentriz/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](https://jellyfin.org/), 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#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) :/

[Navidrome](https://github.com/deluan/navidrome) looks promising,
but the webui isn't [really useable
yet](https://github.com/deluan/navidrome/issues/10).

[Subsonic](http://www.subsonic.org/pages/index.jsp) and [madsonic](http://madsonic.org)
are not open-source, [libresonic](https://web.archive.org/web/20170619101432/https://github.com/Libresonic/libresonic) isn't maintained.

# Airsonic

So I settled for [airsonic](https://airsonic.github.io/):

- 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](http://www.subsonic.org/pages/changelog.jsp).

Since I've only "*managed*" java things via
[meterpreter](https://github.com/rapid7/metasploit-framework/wiki/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](https://github.com/airsonic/airsonic/pull/903),
  making the whole filesystem as readonly, blacklisting syscalls, whitelisting sockets types, …
- [Removed](https://github.com/airsonic/airsonic/pull/922) external fonts
	usage, increasing both privacy and response time
- Bumped a fuckton of dependencies, and removed as much as I could
- Fixed [several](https://github.com/airsonic/airsonic/pull/938) low-hanging XSS
- [Fixed](https://github.com/airsonic/airsonic/pull/934) the low-entropy password-recovery generation
- Removed [dangerous](https://github.com/airsonic/airsonic/pull/933) "features"
- Removed all traces of [Flash](https://en.wikipedia.org/wiki/Adobe_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](https://github.com/airsonic/airsonic/pull/928) to make airsonic
	compatible with newer java runtime versions
- Added the project to [coverity](https://scan.coverity.com/projects/airsonic)
	and [LGTM](https://lgtm.com/projects/g/airsonic/airsonic/overview/), then
	started to fix the most dramatic issues. I also added
	[codecov](https://github.com/airsonic/airsonic/commit/135886374a219fba9b7a91ea031338566ea01ec7)
	integration to visualise the testsuite's coverage.
- Pushed, along with [eharris](https://github.com/eharris), for more
	[checkstyle rules](https://github.com/airsonic/airsonic/search?q=checkstyle&type=Commits),
	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](https://github.com/airsonic/airsonic/commit/72e372157a4c28b685ce79b714f13684cdd37aba)-related code.
- Applied (but got rejected) for the [Google Summer of Code](https://summerofcode.withgoogle.com/).

The next big things to do are to refactor the frontend, and to bump the version
of [Spring](https://spring.io/), 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 :/
