So You Wanna Scrobble
- 12 minutes read - 2420 wordsNow some of you may be asking, what the hell does “scrobble” mean? Well, it’s a nonsense word for the most part, but it means “to submit your currently playing song to a service which tracks your listening history.” Back in the early 2000s (2002 per a search just now), a service spun up called Audioscrobbler. The idea was that you’d play music, and your music player would send metadata about the song you were playing to Audioscrobbler’s site, and eventually it would build up a sort of personal listening profile of you. You could share it with friends and say “hey, look at all the cool music I listen to! You should too!” or whatever. Or you could learn about others’ music taste in turn, and discover new artists. It all started out very inauspiciously and homebrew, very chill. Eventually the venture capitalists and music industry took notice, and well, y’all know what that means. It became corporate and boring and annoying. The service rebranded as Last.fm, which was a more suitable name for the service, probably, but it was never the same. I don’t like it anymore.
I was on Audioscrobbler/Last.fm for years and years, with thousands and thousands of playcounts. Eventually I left it, though, and decided to go with a more smallweb solution called Libre.fm. That site is fine, but it’s very barebones, and I’m still having to submit data to somewhere I don’t control. In an age where we have very little control over our data floating about in the world, I try to retain as much as I can. Hence this server, and its services, and whatever other smallweb things I use that largely circumvent the easy access, data-hungry corporations everywhere.
When looking for a Libre.fm alternative, I found ListenBrainz, which seems to be a pretty non-corporate, nice site for submitting listening data and such. It’s associated with MusicBrainz, which in general is focused on correctly cataloguing music metadata. All for that. I found out that my music player of choice, Strawberry Music Player, is able to scrobble to ListenBrainz. Awesome! I just have to put in my API key for ListenBrainz (easily available in your user settings on the site, known as the “user token”). So that’s pretty cool. I highly recommend it if you want a no-fuss alternative to Last.fm.
However, I was talking to one of my friends, and she said she self-hosts a software package called Koito which does pretty much the same thing. I looked at her Koito instance and thought it was super, super cool. And if you know anything about me, you know I’m down for self-hosting just about anything I can shake a stick at. Why not host it myself and keep all the data somewhere I control, rather than sending it elsewhere? So I thought, awesome, let’s do this!
As you may know from perusing elsewhere on my site, I run my server on YunoHost, which is lovely. They have apps for most of the things I want, but unfortunately not everything. I found that the recommended easiest quickstart for Koito is via Docker, a system which, as far as I can tell, lets you create little “containers” for webapps to run on your server. Not dissimilar from YunoHost, but works a little differently. YunoHost has some limited documentation on installing “custom apps,” but it was not very helpful. As usual, I found a YunoHost forum post, which, while it bumbled through things a bit, still helped me get started. I spent part of a weekend day setting up Koito according to those instructions, and then found that I couldn’t set a custom ListenBrainz API URL for Strawberry. That’s on me; I put the cart before the proverbial horse. So back to ListenBrainz I went, but I still wanted to find a way to use Koito, whether that meant changing music players or what.
I had an idea: what if I could get another intermediate program to “listen to” (i.e., track) what I was listening to in Strawberry, and then pass it along to Koito? That way I could set up a custom ListenBrainz API url and point it at Koito, rather than the official ListenBrainz site. And then we’d be all good. I really lucked out, because I found a small but mighty program called rescrobbled which uses MPRIS (Music Player Remote Interfacing Specification) to read the currently playing track. And Strawberry definitely uses MPRIS, since you can control it with a widget on the panel. So I think I found my pipeline: Strawberry -> MPRIS -> Koito! Now, if you’re using a music player that allows a custom ListenBrainz URL, you can certainly omit the rescrobbled step.
Installing Docker & Koito
Now, I can only speak for my experience using YunoHost (on Debian Linux). Your installation steps for Docker may be way different. Basically, install Docker on your system, whether it’s local or on a VPS. If you’ve already installed it, and set up the Docker daemon to start on boot (these instructions are for systemd on Linux; YMMV), then move on.
If you’re running Koito on a domain or subdomain, set that up, either on your computer, or in your DNS settings on your VPS. Everyone’s installation is a bit different, so I can’t provide for all those permutations. However, if you’re setting it up on YunoHost, set up a domain/subdomain, then do the following:
- Install the YunoHost Redirect app on your Koito domain.
- Point the Redirect app, using the Reverse proxy mode, at http://127.0.0.1:4110 (I use 4110 because that’s the default Koito port; if you change it [see below], use a different port here)
- That’s it, you’re done on the YunoHost side; the domain/subdomain should be able to reach Koito once it’s up and running, which we’ll do next.
Once Docker is installed and ready to go, you’re ready to start installing Koito. Koito’s quickstart suggests using Docker Compose, which seems to be an easier way to set up a Docker app container. Docker Compose uses a .yaml file for its configuration. I am really unfamiliar with yaml, except for using it a bit with Hugo, but it seems easy enough to follow. And the sample compose.yaml (I called it docker-compose.yaml on my installation) is an easy skeleton you can modify. Here’s mine:
services:
koito:
image: gabehf/koito:latest
container_name: koito
depends_on:
- db
environment:
- KOITO_DATABASE_URL=postgres://postgres:<PostgreSQL password>@db:5432/koitodb
- KOITO_ALLOWED_HOSTS=<your Koito instance URL>,127.0.0.1:<4110, or your Koito port>,<your Navidrome instance URL>
<note: optional parameters>
- KOITO_ENABLE_LBZ_RELAY=true
- KOITO_LBZ_RELAY_URL=https://api.listenbrainz.org/1
- KOITO_LBZ_RELAY_TOKEN=<your ListenBrainz user token>
<note: end optional parameters>
ports:
- "4110:4110" <note: you can use whatever port you prefer, but Koito defaults to 4110; use this above in KOITO_ALLOWED_HOSTS also>
volumes:
- ./koito-data:/etc/koito
restart: always <note: I set this to "always" instead of "unless-stopped" so it would start on boot with Docker>
db:
image: postgres:16
container_name: psql
restart: unless-stopped
environment:
POSTGRES_DB: koitodb
POSTGRES_USER: postgres
POSTGRES_PASSWORD: <PostgreSQL password>
volumes:
- ./db-data:/var/lib/postgresql/data
So that’s my Docker Compose config file. A few notes on some of the parameters within (please remove any <> part with note: at the start of it from your file!):
- KOITO_DATABASE_URL is a PostgreSQL URL pointing to the PostgreSQL database holding Koito’s data. Think of it like an oldschool URL for username/password, like if you were logging into a FTP server in your browser. <login>:<password>@<domain>:<Koito port>/<Koito database name> is the URL scheme.
- Make up a strong password for after the postgres: username, then make sure to keep the “domain” as “db”; Docker does its own internal networking stuff, and it’ll get the traffic routed to the right place.
- PostgreSQL defaults to port 5432, so you can easily keep that the same.
- KOITO_ALLOWED_HOSTS does exactly that: specifies what hosts are allowed to connect to the Koito instance.
- The first item in there should be your Koito instance URL; the domains/subdomain URL should be fine, go ahead and use https:// for it
- It also doesn’t hurt to specify the localhost:port URL: https://127.0.0.1:<your Koito port>
- If you’re planning on running Navidrome, an elegant self-hosted music streamer, you can also have Navidrome scrobble to Koito. See below for more info. I find it helpful to also do the localhost:port for Navidrome, which defaults to 29579: https://127.0.0.1:29579 – but please check your Navidrome config for that port.
- The following are optional settings I’ve enabled; feel free to omit them if they don’t apply:
- KOITO_ENABLE_LBZ_RELAY=true means to enable relaying Koito submissions to ListenBrainz; either the main site, or another ListenBrainz-compatible server (it could even be gasp another Koito server!)
- KOITO_LBZ_RELAY_URL=<ListenBrainz API URL>: This is the URL to relay to; the main ListenBrainz URL is, at least at the time of writing, https://api.listenbrainz.org/1 (see here for more instructions). Here are the ListenBrainz API docs too.
- KOITO_LBZ_RELAY_TOKEN=<ListenBrainz user token>: This sets your ListenBrainz user token, which you can find here in ListenBrainz user settings. This allows Koito to authenticate to ListenBrainz and submit on your behalf.
- ports: sets the port Koito will listen on; as far as I know, both halves of the port:port pair should ideally be the same. They suggest 4110.
- POSTGRES_DB sets the PostgreSQL database name, which must match the <Koito database name> set above in the database URL.
- POSTGRES_USER sets the PostgreSQL username, which must match the <login> set above in the database URL.
- POSTGRES_PASSWORD sets the PostgreSQL password, which must match the <password> set above in the database URL.
Once you’ve set everything up within, you’re ready to spin up the Koito instance:
- On Linux, make sure you’re in the same directory as your Koito (docker-)compose.yaml file, and type:
docker compose up -d- This command will start the Docker container and keep it running in the background (-d for daemon).
- Go ahead and fire up a web browser to check out your Koito instance!
- Make sure to go into Settings -> Account, and “login” to your Koito instance with the default login & password “admin” and “changeme”. Then immediately change the password to something secure.
- From there, go into Settings -> API Keys, and generate an API key for your music player. Keep this tab open after you generate it.
Setting Up Your Music Player
So now we’ve got Koito set up. But we need to set our music player up to submit its plays to the Koito instance. As I mentioned above, if you have a music player that will accept a custom ListenBrainz API URL, go ahead and set it to the following: https://<your Koito instance>/apis/listenbrainz/1/
- We also need to set an API key so that we can authenticate from the music player to Koito. Copy the API key from your Koito settings and use it in your music player.
However, if your music player, like mine, will only allow scrobbling to the main ListenBrainz server, then we need to take a different tack. This is where the little program rescrobbled comes in.
-
Install rescrobbled by following the instructions on the site; it is written in Rust, AFAIK, so it can be installed easily using the crates system.
-
Once rescrobbled is installed, we need to set up a configuration file so it knows where to send its plays; at least on Linux, this file will be located in ~/.config/rescrobbled/config.toml. The program doesn’t ship with this, though, so we’ll have to create the rescrobbled directory and its config file.
-
Now you need to decide whether you want rescrobbled to track all plays through MPRIS, or just through your main music player. I only want it to count plays through Strawberry, so I put this line at the top of the config file:
player-whitelist = [ "strawberry" ] -
Per the documentation, the ListenBrainz info needs to be at the bottom of the config file, below all the other options:
[[listenbrainz]] url = "https://<your Koito instance>/apis/listenbrainz/1/" token = "<your Koito API key>"
Make sure you pull your Koito API key from the Koito instance in Settings -> API Keys.
I also highly recommend setting up rescrobbled as a systemd service; the service file is provided by the author, and needs to be placed in ~/.config/systemd/user. Go ahead and follow the rescrobbled instructions here under Usage to set up the systemd service. That way you can have it start every time you fire up your computer.
Now, go ahead and play your music; it should all send to your Koito instance (and ListenBrainz, if desired, via the relay), either directly from your music player, or via rescrobbled!
Koito & Navidrome
Let’s say you, like me, are super geeky about all of this. Not only do you want to track music played on your computer through Koito, but also through Navidrome, if you’ve set it up. I listen to Navidrome via my phone a lot while I’m working, since I don’t have my (personal) laptop running during that time. Navidrome will allow you to access it through a Subsonic-compatible client, so I use DSub2000 (available on F-Droid) personally. DSub2000 will let you set it to Scrobble to Last.fm (Settings -> Playback), which of course can use ListenBrainz as well.
In Navidrome, we have to do a few things before we can set up scrobbling to Koito or another ListenBrainz-compatible instance. This involves manually editing the navidrome.toml file, which is the configuration file. There are a ton of options within, but only one that we care about for our purposes.
-
Open the Navidrome configuration file; in YunoHost, it is typically located at /home/yunohost.app/navidrome/navidrome.toml
-
Add the following lines, set off by a line between other options:
# ListenBrainz for Koito ListenBrainz.BaseURL = "https://<your Koito instance>/apis/listenbrainz/1/" -
Restart Navidrome (in YunoHost, use
sudo yunohost service restart navidrome). Now the API URL is set so we can authenticate. -
This is optional, but I would recommend going into your Koito instance, then Settings -> API Keys, and generating a new API Key specifically for Navidrome. Copy it.
-
Login to Navidrome, and go to Settings -> Personal, and click “Scrobble to ListenBrainz”
-
Navidrome will then ask you for the API key. Paste the one you just generated. If it is all set up correctly, you’ll get a green banner saying Navidrome and ListenBrainz are linked!
You should be all set now! Go and enjoy sharing your music taste with the rest of the world, and also enjoy looking back at trends in your listening habits! I’m happy to try to answer any questions I can otherwise. I’ve spent a good chunk of two weekends figuring this out, but I think I’m now at a good place with everything, which feels very nice. Thanks for reading, friends! <3