Cluster Player

Coding, 2019 - present

While working, my wife and I often listen to music. We had a shared playlist with work-appropriate music, but even with large playlists, the shuffle algorithm is not very good at creating what you can consider a “good mix”. Alternatively, Spotify has a lot of nice curated playlists, but those often contain a bit too many tracks we don’t like, or that are inappropriate (i.e. distracting) during work.

So I’ve been working on a tool that generates playlists which are a combination of familiar songs (i.e. from our own “collection”) and songs from curated playlists (either manually or automatically created). Also, I wanted to be able to have some influence over the overall mood of the playlist; sometimes you need a bit extra excitement, whereas other days you’re fine with calmer stuff.

I called it cluster player. It looks something like this:

When I was younger, I was really into radio as an industry, and my basic knowledge of how radio formats work inspired my approach for this project. I wanted to create a nice listening experience that wouldn’t play the same style of music the entire time, but also wouldn’t make an awkward jump from one genre to the next every time.

I also wanted the playlists to occasionally play sequential tracks from an album, as if you put on the album for a while.

Clusters of tracks

The tool requires you to add a few playlists from your Spotify library. You can set these up to fit specific moods, for example.

When you want to start listening, you move a few sliders to set up how much of each playlist/moods you want to hear. The tool then takes this into account when generating the playlist.

The resulting playlist is composed of “clusters” of tracks fitting the same mood.

You can create a few mood-specific playlists (like upbeat, whacky, and other favourites) from music in your own collection, but the cool part is that because you can basically add any playlist in your Spotify library to the tool, you can also add curated playlists and dynamic playlists. This means that you can still discover new music by adding Spotify’s “discover weekly”, playlists curated by your favourite artists, everyone’s favourite chillhop YouTube channel or some of the impressively-specific genre playlists from Every Noise at Once 1.

It keeps track of how often certain artists and tracks are played, and will prevent them from being played too often. This is obviously better than regular shuffle, where it might play the same artist many times if you have a lot of tracks by them in a playlist.

ban
If it turns out that you don't like a track, or if you have heard too much from the same artist recently, you can also manually remove a track from the source playlist, or 'ban' it for a limited time.

Tech stack

The entire app is written in Typescript. The backend is a Node app using the Express framework. The frontend is your typical Webpack + React + Redux app. There is some custom UI in there, but most of the UI is built with Tachyons.

Because the app only really has one user, and I wanted to iterate quickly, the data is just stored on the filesystem as JSON files. I wrote a small abstraction on top of it so I can switch it out for a proper database at some point, but I’m not sure if that would really make any sense.

Future plans

I’m thinking of making the app open source at some point, but there are still some features for which I have to finish the UI. That’s not high on my todo list as it’s working great for me now, but I hope to finish them at some point.

Conclusion

It’s great to have an idea for a tool and to be able to just make it, even if it’s just for yourself. We’ve been using it basically every day since its creation, and it was even used in one of my favourite cafes!