Since restarting this blog, I haven’t just also restarted work on old projects. I actually have a new one, which is quite far along. In fact I use it pretty much every day, sometimes for hours at a time.

It’s called Thrasher – after the curved-billed thrashers who frequent my yard, and the brown thrasher which is the state bird of my home state, but don’t tell the curved-bills that last part – and it’s my media catalogue and music player.

Music player

The big impetus for this work was simple: wanting to be able to listen to my personal music collection, from anywhere with internet, in the same way that I can listen to music on Spotify. That is: I wanted to be able to listen to anything, on a track-by-track basis, rather than listening to a stream.

So I sat down and figured out how Spotify (likely) does that. And once I had figured out which pieces of the modern web audio API were involved, I was able to find that someone had already written a standalone Javascript library called Howler which does exactly that thing. This meant that I just needed to build the catalogue and UI parts, and didn’t have to worry about the playing-audio-files-directly-via-Javascript part.

Speaking of the UI, there was a secondary impetus to wanting to do this, which is that I had always been annoyed that the ID3 tagging standard only allows a single genre definition for any file. In addition to the fact that I listen to a lot of music which spans genres, I also wanted to be able to apply cross-cutting concerns to my music library. Things like “seen live”, bands from cities I’ve lived in, instumentals, and so on.

And that’s what I did. This part of Thrasher has been in daily use for several months now, with lots of improvements along the way. In fact I made two improvements today, though only one of them is relevant to this side of Thrasher: searching now allows specifying that an attribute’s value can be compared as strictly greater-than or less-than. Previously, due to a mistake in a regexp, only <= or >= were allowed.

Construction

Thrasher has evolved to have three components: the catalog, the tool, and the service.

  • The catalog is where core data models and the code to access and update the backing datastores resides
  • The service is a containerized web app which can query the catalog, display results, and in the case of audio files it also acts as a player
  • The tool is a CLI utility whose primary task is input, but it handles all aspects of data management. This separation was initially just to speed up development, but I’ve maintained it because it fits how I tend to use software, and it allows the service to be read-only

In addition the initial (and current) design of the service is such that it spawns a new instance of itself for each connection. The intent behind this was to allow a fully isolated mTLS setup, where each instance would only know the cert of the client it was supposed to connect to. Over time this has caused some complications, and it may be refactored soon. mTLS is still a design goal, but that can be pushed into nginx rather than having the service handle it internally.

Other media

In the past week, I decided to merge Thrasher and something that I had wanted to write for a long time, but never got around to, which is a catalog of non-music media.

I realized that I was most of the way there, so I quickly sketched out a generic media datastructure, and starting adding capabilities to the tool.

On the music side, the tool uses MP3 files themselves as the input source, by parsing their ID3 tags – so there was no traditional user input. I didn’t want to add something like that for this either; I wanted something that felt smoother and also supported structured inputs. What I settled on was creating a temporary file with a JSON-formatted template of a media entry, which was then handed off to an editor (VISUAL, then EDITOR, then vi) for completion.

So far I’m up to 133 DVDs and Blurays, and will likely finish those today. That’ll just leave me with entry of every book, magazine, and other piece of printed matter in the house. That’ll take some time, but it’s much better than never doing it at all.

Service is so far unaware of the media side of things. I won’t be doing that work until things are more fleshed-out on the tool and catalog sides.

The good news is: that work should go very quickly, as it will largely be cribbing from and/or adapting exiting functions on the music side of things.

It is nice to write about a project that is rather than one that will be.