Setting up your own Spotify
Have you read one of my previous articles — Music streaming services? If so, then you already know, that music is my passion. Music helps to relax, change a mindset, go through tough moments in life. I’m so used to having music around me, that it’s hard to imagine life without it.
Due to the high-speed development of the Internet, we have moved away from listening to offline music and switched to online — streaming. We have stopped ‘own’ music. All songs with artists and albums are now stored on a cloud of one of tech companies. Services, such as Spotify and Apple Music represent the music streaming standard.
Streaming services are indeed powerful. From my point of view, they have 2 unbeatable features:
- To provide access to new songs, albums as soon as they come out
- To recommend songs, similar to what you like, utilizing the listening history of millions and millions of users
Everything comes with its cost. Nothing is free and streaming services are not an exception. A subscription model is tightly coupled with them: an infinite amount of payments, every month, every year, until you abolish it. Once you cancel you lose access to playlists collected for years.
Don’t take me wrong — there is nothing wrong with using such services, but we should always ask ourselves if we use the right tool for our objectives.
If you don’t necessarily need the 2 features, that I mentioned earlier out of the box, and you are interested in saving a fortune, I’m glad to offer you an alternative — self-hosted music streaming service.
Our goal in the article is to set up a music streaming service with our songs, available from a mobile phone app anywhere.
Choosing a self-hosted streaming service
First of all, we need to define where we will host our service. For me, it isn’t a question — I have a Raspberry Pi, that I successfully use for other projects (take a look at my other article — Your cloud storage at home), but you can rent, for example, an AWS EC2 instance or even host on an old laptop, which maybe gathers dust idle.
While searching on the Internet, I found 2 popular solutions:
For the full overview with the comparison, I can recommend the analysis on github. They both are free and have source code, that you can modify if needed. I’ve decided to start with the Navidrome, mainly for two reasons:
- Lyrics are supported with Navidrome
- Jellyfin is considered a Media System and covers not only music, but also movies, books, and more. I wanted to start small, avoiding Raspberry Pi performance issues, that could happen with such a beast as Jellyfin
As a mobile phone client, you are free to choose one of several options. Navidrome is a Subsonic-API compatible server, which means, that any App, that supports the API fits, such as:
- iOS: play:Sub, substreamer, Amperfy, iSub
- Android: Symfonium, DSub, Tempo, substreamer, Subtracks, Ultrasonic
Setting up Navidrome-based streaming on Raspberry Pi
Although the process to install Navidrome is straightforward and you can follow the official manual: Navidrome/Installation/Linux (If you’ve just bought a Raspberry Pi computer unit, then, the prerequisite is to install Raspberry Pi OS), I’d like to give a couple of notes below.
While you are following the manual, you should change <user> and <group> to point to a user:
- <user> can be a user, that you created when installing RaspberryPi
- <group> can be safely changed to users
For example ($USER references my username with which I logged in):
sudo install -d -o $USER -g users /opt/navidrome
sudo install -d -o $USER -g users /var/lib/navidrome
When you execute wget
command to retrieve a Navidrome asset, you have to specify an architecture (which asset to download). I recommend checking it explicitly with the command uname -m
, which gives me armv7l. It means, that I should install the navidrome_0.xx.0_linux_armv7.tar.gz asset.
MusicFolder field in navidrome.toml file references where our music is stored. For the Raspberry Pi, it has to be an external storage device, as internal memory won’t be enough for all the music that we could upload. I suggest using an external hard drive and mounting it on the start-up:
- Plug in the hard drive with music
- Use blkid command-line utility to locate block device attributes
- Create with mkdir command a folder where to mount the hard drive (I name the folder yellowhd, as the HD has a yellow case)
- Give permissions for this folder to be accessed by you with the chown command
- Add a line to automount the hard drive to the created folder (/etc/fstab file) with vim or any other editor
>sudo blkid
...
/dev/sdc1: LABEL_FATBOOT="KINGSTON" LABEL="KINGSTON" UUID="34AC-211B" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="01143cd2-01"
>sudo mkdir /media/yellowhd
>sudo chown -R <user>:<group> /media/yellowhd
>sudo vim /etc/fstab # or use any other editor, i.e. nano
/etc/fstab file:
# ...
UUID=34AC-211B /media/yellowhd vfat defaults 0 1
After setting up the automount to the specific folder we can point MusicFolder to “/media/yellowhd”.
As the last step, according to the manual, when you validate that the Navidrome service started successfully, don’t forget to run sudo systemctl enable navidrome.service
, as it adds the service to start it on startup (it is helpful in case of a power outage, for example).
One week of using Navidrome
I set the streaming service up one week ago and during this week I constantly use it to listen to music.
I have a collection of about 150 GB of songs and on the first launch, it took a while for the Raspberry Pi to index all of them. While it scanned, it was almost impossible to use the service for listening to music, so I caution you to wait a while.
As a client app, I chose the substreamer, although I plan to try and compare others.
One of the cons is that the substreamer doesn’t shuffle my songs. In addition, there is a setting, that is supposed to help you switch automatically between internal and external networks, but the setting doesn’t work for me. Hence, if I listen to music from home, I change the Preferred server address to Internal manually:
Some people even use a web version from a mobile phone and find it better.
Overall, I’m very pleased with the result. Although I have to maintain the music library by myself and upload new songs to the Raspberry Pi hard drive, the solution is low-cost (even free, if you have a Raspberry Pi and a hard drive) and works smoothly. In addition and it goes without saying, the service, that we configured can be used by your family or friends.
Next steps
Although the main work is done and the service is up and running, I want to improve my interaction with it:
- Uploading new songs. For now, it’s a manual process, that can be automated. What is required is a script, that detects new releases from a definitive list of artists, buys and uploads them to the hard drive. Some songs can be downloaded and used freely, which I also want to cover with the script: The copyright duration of composed music is the author’s lifetime + 70 years. Therefore, the musical compositions of old masters like Beethoven (1770–1827) or Mozart (1756–1791) are all in the public domain and we can freely use them
- Comparing client apps. As I mentioned earlier, I’m planning to try other clients and study them in depth to improve my experience of interacting with the library
- Adding recommendations. There is always room for creativity. Although, out of the box Navidrome doesn’t provide the feature, we can always implement it by ourselves. Luckily, on the Internet, there are many cases of how to build such a recommendation system with datasets, that can be already used for training the model