Raspberry Pi based Music Player (Pt. 1)


So I had a problem that needed to be solved: I had an unused Raspberry Pi lying around I wanted a more comfortable method of listening to my music collection. Up to this point I would listen to music in two ways (at home): Either with my CD-Player, but that has the huge drawback of only being able to listen to a single album at a time, or by connecting my laptop to my amplifier, which enabled me to listen to my entire library, but I don't want to always get my laptop out of my backpack just to listen to music.

After reading some blog-posts by Lars Ingebrigtsen (like this one) I was intrigued: He uses a computer housed inside a case looking like a part of a stereo system on which he runs an emacs-based music player which streams the line-out to all rooms in his apartment via Cat5 while displaying the current song and cover art on a screen. The device apparently gets the music files from a dedicated file server.

Of course, that is absolute overkill. And although I kinda like absurdly over engineered solutions for minor problems, I decided to do something slightly simpler. I had an unused Raspberry Pi lying around, which I wanted to use for this. After some testing I found out that the integrated audio is absolute garbage, so I had to get an external DAC (digital to analog converter). All the cheap USB ones I could find also had a headphone amplifier integrated, a feature I explicitly did not want, so I went with the HiFiBerry DAC+, which is a hat for the Pi that can simply be plugged onto the device. This hat adds a line out (in form of the typical cinch audio connectors) to the Pi, as well as a high(er) quality DAC. I also found a cheap plastic case that was originally designed to be mounted into server-racks (or audio-racks), but it had the exact width and color of my amplifier, so I chose it as a case. Although it is way larger than it would need to be, it will fit better with my other equipment.

There are a few pre-packaged audio players for the Pi. They are all basically some Linux distribution with an already configured music player and interface. I tried a few and did not like any of them. Mo0de-Audio is based on MPD (music player daemon), a program I don't really like, and has a terrible web-interface. Rune-Audio, also based on MPD, did not even boot. piCorePlayer just plays datastreams. LibreELEC and OSMC just boot into Kodi, which I find to be absolutely unusable as a music player. Despite, running Kodi would mean I'd have to attach a screen and some sort of input device attached while using something with a web-interface would require me to boot some device with a browser. Both defeat the purpose of the simple "turn it on, music starts playing"-device I want.

So I decided to go with a "blank" distribution and turn it into a music player myself. I choose void-linux, because it uses runit instead of system-d as init-system, which has two major advantages: It boots extremely fast (usually under 8 seconds) and creating services with it is really easy. Keep this last feature in mind, it will be important later.

After downloading the correct image and writing it to the SD card, I mounted the card to modify /boot/config.txt . I just deleted everything and added a single line, which is necessary for the Pi to find the DAC hat:


Since I want my music to be stored not on the SD card, but on an external device (currently a small USB drive) I had to add an entry to the /etc/fstab file so that mentioned storage device gets automatically mounted. I used drive name instead of UUID, so I can easiely swap the drive in the future. Since I only want the Pi to read from there, it will be mounted read only.

/dev/sda /music ext4 defaults,ro 0 1

The Pi booted without problems and my music drive was mounted. On the first boot of void-linux on the Pi, one has to enable a NTPD service, which is explained in the void wiki. Just be sure that the Pi has the correct date before you try to install software. I use my favourite media player, mpv, to play the music files, so I installed that. It is advisable to do an update before installing anything.

xbps-install -Syu
 xbps-install alsa-utils mpv

After mpv as installed, I tested if the DAC hat was found and used, which it was. Note that for a simple audio setup as this, Alsa is enough, larger audio servers like PulseAudio are not needed.

Since I want the device to start playing without any human interaction, I created a service to start mpv at boot. As I mentioned above, this is really easy thanks to runit. All one has to do is to create a directory insid /etc/sv/ (I called mine 'music-player') and put a single file inside it: an executable called simply 'run'. In this case (and in most cases actually) the executable is a shell script.


 cat <( find $MUSIC_DIR -name "*.ogg" ) <( find $MUSIC_DIR -name "*.flac" ) | shuf > $LIBRARY_FILE
 exec mpv --no-video --loop-playlist --playlist=$LIBRARY_FILE --input-file=$CONTROL_FIFO > /dev/null 2> /dev/null

This script will generate a randomised list of all files with the .flac or .ogg extension in the /music directory and stores it in a file. Then, mpv is called and uses the previously generated list as a play list. --no-video is needed because otherwise mpv would try to display the album art, which would fail since I did not install any graphical environment. --loop-playlist covers the extremely unrealistic chance that mpv will reach the end of the playlist; It will then just start at the top again. --input-file= defines a special file which can be used to control mpv

Now the service has to be enabled, which is done by simply sym-linking it into /var/services/ .

ln -s /etc/sv/music-player /var/services

Now one has to create the file to control mpv. I used a FIFO (named pipe). If one does not create the file, mpv will do it, but it will create a socket instead of a FIFO and those are a little annoying to work with.

mkfifo /mpv-fifo

After a reboot, the Pi automatically started to play my music, without me doing anything, not even logging in; Perfect for my use case. I want to avoid interacting with the device as much as possible. In fact I really like that I don't have fine control over what exactly is playing: Only having three controls: Next, Previous and Play/Pause, means that I won't gravitate towards my favourite songs, like I do on my laptop where I can just search for them. Instead I am more likely to listen to songs I otherwise would rarely listen to. I could even get rid of the three controls I have, so it would be like a radio, but since I don't want to listen to Lacrimosa (metal) after First Aid Kit (folk), or similar unfitting combinations, I will keep them.

To control mpv, one can write certain commands into the FIFO:

echo playlist-next > /mpv-fifo  # go to next song
 echo playlist-prev > /mpv-fifo  # go to previous song

The only problem I currently have with the device: I have no way of actually executing the above commands, so at the moment I can't skip or go back (radio mode) without attaching a keyboard. I have ordered a few nice push buttons; Hopefully the DAC hat does not entirely block all GPIO pins of the Pi. I will also experiment with one of these presentation remotes, which basically are keyboards with only two buttons (page up and page down). Once I have found a viable method to control the thing, I will post part two, as well as a few pictures.

In the mean time, I will thoroughly ... test ... the device with about 10 GB of both my favourite albums as well as few I have only listened to a few times.