I've been running Mopidy for a few weeks now on a Raspberry Pi 3 Model A using a spare set of computer speakers. As I also have a spare Raspberry Pi Zero W, I decided to buy a HAT for this that would allow me to use a set of proper hi-fi speakers that were powered by the Pi instead of external power.
This article describes how to set up the Mopidy music server with selected extensions using the Pimoroni pHAT Beat. However, you could follow most of this guide to create a Mopidy music server using another model of Raspberry Pi via the built in audio chip and 3.5mm audio jack. In this case, just ignore the instructions for installing the pHAT Beat software and follow everything else.
- A Raspberry Pi Zero W. Mine was an older model 1.1 version and was bare
- GPIO headers (both male and female, male to fit to the bare board and female for connecting to the HAT). As I don't currently have a soldering iron, I choose to use this kit that included solderless versions of both headers along with a nifty installation jig for hammering them into the boards without breaking anything
- pHAT Beat audio board. This has two pairs of connectors for wiring a pair of speakers, two rows of 8 leds and some hardware buttons
- Speakers. I picked up a pair of 40W 8Ω speakers from eBay (TEAC LS-X8 for the curious). I naively assumed any speakers would work but this isn't correct
- Speaker wire. Again, I didn't really do my research and just grabbed a coil of 1.5mm pure copper speaker wire, which does work but is probably overkill
- A 64GB class 10 U1 A1 SD card
- A monitor for at least the initial set up
- A keyboard for at least the initial set up
I'm going to assume that if you're using a Raspberry Pi you already know how to flash operating systems onto the SD card, so I won't provide instructions. Previously I used Rufus for this sort of task, but the recently introduced Raspberry Pi Imager could scarcely make this easier if it tried and is my new go-to tool for imaging Raspberry Pi cards. As I don't need a desktop environment for this project, I installed Raspbian Buster Lite.
This guide is assuming you are starting from a completely fresh setup.
As is sometimes the case, this guide comes with a caveat or two.
Firstly, I'm not a Linux expert. I know enough to be dangerous as they say. So I may not be using the most efficient commands or may not be following best practices. Suggestions on improvements are definitely welcome!
Secondly, I know even less about electronics that I do about Linux. My level is basically plugging LED's and resistors into a breadboard and getting overly excited when they light up. Therefore I am not making any recommendations on what speakers are compatible or what type of speaker wire to use... it's more than likely I'm using the wrong ones now, even though so far everything has been running fine.
Finally, this being Linux all the software I will be installing is open source by various individuals. At the time of writing (April 4th 2020) this guide works fine (I have done a fresh run run from start to end four times during the course of writing this article) but that is no guarantee it will work in a months time. On the bright side, at least it isn't using Node so more than likely it will work in a months time.
- Connect the pHAT to the Pi
- Connect a keyboard and monitor to the Pi
- Insert the flash card
- Power up the Pi and wait for initial setup to complete (this may involve an automatic reboot) and for a login prompt to appear
- Log in. For Raspbian, the default credentials is user
passwdand follow the prompts to change the password of the
As this is fully headless, there's no point allocating precious memory to the GPU, so the first thing we'll do is reduce this to the minimum value (16MB).
sudo nano /boot/config.txt
- Add the line
gpu_mem=16to the start of the file
Enterto save the changes and exit Nano (this guide requires editing a few files but I won't be repeating this line)
We'll be controlling music playback using a web browser, plus it is much more convenient to manage a Raspberry Pi remotely using SSH rather than having to plug monitors and keyboards in, so the next step is to configure the wireless adapter.
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf(you can press
tabwhile entering filenames and the shell will try to autocomplete them for you)
- Add the line
GBwith the ISO code of your own country as appropriate
- Add at least one network definition similar to the template below
The Raspberry Pi boot loader will automatically enable SSH if a
/boot/ssh is present. We can use
touch to create
this file. SSH makes it easy to remote onto your Pi for
maintenance tasks, but if you always intend to plug into a
keyboard and monitor then you don't need to do this step.
sudo touch /boot/ssh
The default host name is
raspberrypi. If you have multiple
Raspberry Pi's, you definitely want to change the host name and
I recommend you give it a custom name regardless.
sudo nano /etc/hostname
- Delete the existing value and enter your own using letters a-z, digits 0-9, or a dash
The changes made to enable SSH (and if you changed your host name) won't take effect until the Pi is rebooted.
sudo rebootto reboot
When the Raspberry Pi reboots, just before the login prompt is displayed, check for a message stating My IP address is x.x.x.x. If this message doesn't appear, your Pi didn't connect to the wireless network successfully.
After I have SSH enabled and the Pi connected to the network, I disconnect the monitor and keyboard and remotely access it via SSH. I used to use Putty for this, but one of the rare things in Windows 10 I actually like is that it now includes a SSH client which is much more convenient to use than Putty.
However, if you don't want to do this log into your Pi and continue with the next section.
- Open a Windows command line (good old
cmd.exe, PowerShell or the new Windows Terminal)
ssh pi@<hostname>, where
<hostname>is the name of your Pi
- When prompted, type
Enterto store the fingerprint of your device (if in future you try to connect to
<hostname>and the fingerprint doesn't match, SSH will prompt to continue as it is extremely likely you aren't connecting to the machine you think you are)
For our music server, we need two different directories, one to hold the actual music and another to store playlists. You can stick these where ever you like, but for simplicities sake I decided to put playlists as a subdirectory of music.
Later on, I'll be installing Samba so that I can access these directories via SMB shares. The first time I set all this up on my Model A, getting the share to work was a complete pain. I ended up creating user accounts on the Pi that mirrored my Windows user accounts and all sorts of other nonsense trying to get it to work. This time around, I followed this answer on Ask Ubuntu which suggested making "nobody" have full control over these directories. This worked first time for me and so I'll be presenting the same instructions here.
sudo mkdir /srv/music
sudo mkdir /srv/music/playlists
sudo chown -R nobody.nogroup /srv/music
sudo chmod -R 777 /srv/music
As this is a fresh install, it's likely to be out of date. Before installing any other software I like to make sure that everything else is up to date first.
sudo apt update(this looks for updates but doesn't actually install anything)
sudo apt upgrade -y(this installs all available updates. The
-yflag means it will install without prompting to continue first)
Before we can install Mopidy, we need to add it to our package resources as per their installation guilde.
wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -
sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/buster.list
Now we need to check for updates again and then install Mopidy
sudo apt update && sudo apt install mopidy -y(the && operator executes multiple commands sequentially, but only if the proceeding command(s) were successful)
Mopidy is written using Python and some of its extensions aren't
apt, but instead with Python's own package
sudo apt install python3-pip -y
Mopidy includes a few basic plugins, but doesn't actually include anything for front end playback. There are a number of web based front ends I've tried and I don't like any of them. Mopidy-Iris is probably the best of the bunch, it looks good and provides basic playlist management. I don't like it because it keeps trying to load Spotify (which I don't use) when I'm working with playlists and because it appears to be more focused towards making playlists out of individual tracks, whereas I am a touch old school and my playlists are made out of full albums and shuffle is definitely banned!
sudo python3 -m pip install Mopidy-Iris
sudo sh -c 'echo "mopidy ALL=NOPASSWD: /usr/local/ lib/python3.7/dist-packages/mopidy_iris/system.sh" >> /etc/ sudoers'(this is for giving Mopidy permission to update Iris)
Although Mopidy ships with a files plugin for playing local media, Mopidy-Local is a better alternative - it caches all the media in a database, so is able to quickly access media information. It also provides album art to other plugins, for example Iris above.
sudo python3 -m pip install Mopidy-Local
With Mopidy and extensions installed, we need to update the configuration to tell it where and how to process our media files. I also disable the file plugin given we are using local instead.
sudo nano /etc/mopidy/mopidy.conf
Add the following content, replacing paths as appropriate.
By default, Mopidy's HTTP browser is only accessible from local
host - not great for a headless device. The
hostname = ::
opens it up fully to any computer on your network. Consider
viewing the warning in the Mopidy-HTTP documentation.
scan_flush_threshold values are a
matter of personal preference. I have just under 5000 MP3 files
and on both the Model 3A and Zero initial scans have timed out
with the default values, or completely stalled, loosing
progress. By increasing the
100 I have avoided some
of these issues.
Although Mopidy installs a system service, this is isn't enabled.
sudo systemctl enable mopidyto force Mopidy to start at boot time
sudo systemctl start mopidyto start Mopidy now
To check the complete Mopidy configuration, enter the following command. This will output a configuration similar to the file you edited above, but also including all other parameters and their values.
sudo mopidyctl config
I mentioned at the start of the guide I'd be installing Samba and we're now at that point. This will make it easy to connect to the music directory via a file share to copy new tunes over.
sudo apt install samba -y
- If you are asked any questions by the install, just accept the default value
I have found the default Samba configuration works out of the box, but you still need to configure at least one share. As with the directory permissions at the start of this guide, the share configuration below comes from the same Ask Ubuntu answer.
sudo nano /etc/samba/smb.conf
Add the following lines to the end of the file, replacing the path as appropriate.
As we've changed the configuration, we need to restart the service.
sudo service smbd restart
You should now be able to access your music share over the network. As copying files to a Raspberry Pi Zero seems to be very slow (it consistently took four hours to copy 25GB of music in my tests) you may wish to start with a single album until you have tested everything, and then copy your full library.
As we've installed Mopidy-Local which stores media information in a database, we need to tell Mopidy to scan the file system to update that database.
The documentation recommends setting up a cron job for this, but this seems overkill unless you are constantly modifying your media library. I prefer to run it on demand when I add music.
sudo mopidyctl local scan
Note that this may take some time to run. If any file's time out you can always run the command again when it completes and it will try again with the skipped files.
(Skip this section if you are using the built-in soundcard and onboard audio connector.)
Installing this software will disable the onboard sound. However, I found that it also had another impact for if I undid the settings it made to
/boot/config.txtand re-enabled onboard sound, audio no longer played properly through it.
curl https://get.pimoroni.com/phatbeat | bash
- When prompted to continue enter
- (Optional) When prompted to install examples and
y. If you answer
n, the VU meter won't automatically work. It was much easier to answer
ythan to install it from source
- Once the installation has completed, answer
To test your audio is working and you have the speakers the right way around, you can use the speaker-test program.
speaker-test -c2 -t wav
You should now have a headless music server - last step is to open Iris and play!
- Open a web browser pointing to
http://<hostname>:6680/iris/(don't forget the port)
- The first time you access Iris you'll be prompted for a few settings, update these as appropriate and click Save
- Click Albums and verify music is loaded
- Right click an Album and choose Play
As this is a headless device, it is hard to know when it is ready to accept commands. For this reason I took to adding a start up sound to play a brief tone when the Pi has finished booting. As the Pi Zero is much slower to boot than the others, this is definitely something I appreciate.
- Copy a short wave file to your music share
sudo nano /etc/rc.local
Add the following line, changing the path and filename as
appropriate, towards the end of the file but before the
exit 0 line.
I find that the default volume is pretty loud and as I usually want the music to be background noise, I set the volume in Iris to be a low single digit. I also tweak the master volume so that when the machine starts it is already quieter, even though Mopidy still thinks it is 100%
sudo nano /etc/rc.local
Add the following line, changing the percentage according to
your own tastes. If you added a start up sound, it might be a
good idea to put this line before the call to
Ever so slowly I'm becoming a fan of Linux, one of these days I might try and use a full blown desktop (although that'll probably be difficult due to Visual Studio and WinForms).
I'm not really a fan of the pHAT Beat. My original Mopidy setup on the 3A didn't use a HAT, so the GPIO pins were free. I'd added a couple of wires and a switch to safely shutdown the Pi when pressed, and then start it up again if pressed again. The pHAT Beat takes away that option, and even though it has a hardware button, if you manage to get it working it only seems to shutdown the device, not to start it up again. I haven't yet looked into if there is another way I can add a power switch (having a switch on a USB cable isn't fully sufficient as I still want to safely halt the Pi, not just do the equivalent of yanking out the power cable).
In addition, the VU meter doesn't scale to the current volume, meaning that as I have everything turned quite low, only the first pair of LED's light up - and barely at that. On the 3A, I changed the source code and recompiled based on some advice on the Pimoroni forums but I haven't done that on the Zero yet. It is a shame it doesn't just scale nicely for you.
I also wish the speaker connectors on the HAT were screw based. Instead, you just push the wires until they lock. I don't find that to a be a particularly strong mechanism though.
However, there is no denying that quality of audio wise, using this HAT is far better than my previous set up. Whether that's just to the speakers or the hardware on the expansion board is another question but it is definitely better. And at the end of the day, a VU meter is just a nicety, it's not like I sit and stare at it!
While I don't entirely like playlist management on Iris, I really only need to set play lists up once. What I don't like is having to reload from scratch each reboot and set the repeat flag. Previously I played music on my desktop computer using foobar2000 and what I really liked about that was it would continue where it left off. I'm sure WinAmp used to do that too back in the day and one of the reasons I didn't like Windows Media Player either. I think the only way to get that behaviour back is to write something myself to control Mopidy directly via the Music Player Daemon protocol.
But first I definitely need to figure out a new power switch!
- 12Apr2020 - Added some images of the device
- 10Apr2020 - First published