This content has moved - please find it at

Although these pages remain accessible, some content may not display correctly in future as the new blog evolves.


Installing Mopidy and pHAT Beat on a Raspberry Pi

A Raspberry Pi Zero W with the pHAT Beat audio HAT attached and wired to old-school hi-fi speakers

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.

Required Hardware

For my setup, I used the equipment below. The links point to The Pi Hut but if you aren't based in the UK you could try Adafruit or your own electronics retailer.

  • 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

Preparing the operating system

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.

Caveat Emptor

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.


The first test of pHAT Beat on a Raspberry Pi Model 3 A

First Steps

  • 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 pi and password raspberry

(Optional) Changing the password

  • Execute passwd and follow the prompts to change the password of the pi user.

Changing the memory split

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).

  • Execute sudo nano /boot/config.txt
  • Add the line gpu_mem=16 to the start of the file
  • Press Control+X, then y and press Enter to save the changes and exit Nano (this guide requires editing a few files but I won't be repeating this line)

Connecting to wireless

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.

  • Execute sudo nano /etc/wpa_supplicant/wpa_supplicant.conf (you can press tab while entering filenames and the shell will try to autocomplete them for you)
  • Add the line country=GB, replacing GB with the ISO code of your own country as appropriate
  • Add at least one network definition similar to the template below
network = {

(Optional) Enabling ssh

The Raspberry Pi boot loader will automatically enable SSH if a file named /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.

  • Execute sudo touch /boot/ssh

(Optional) Changing the host name

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.

  • Execute 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.

  • Execute sudo reboot to 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.

(Optional) Continue with SSH

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)
  • Execute ssh pi@<hostname>, where <hostname> is the name of your Pi
  • When prompted, type yes and press Enter to 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)

Creating a directory to store music

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.

  • Execute sudo mkdir /srv/music
  • Execute sudo mkdir /srv/music/playlists
  • Execute sudo chown -R nobody.nogroup /srv/music
  • Execute sudo chmod -R 777 /srv/music

Updating the system

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.

  • Execute sudo apt update (this looks for updates but doesn't actually install anything)
  • Execute sudo apt upgrade -y (this installs all available updates. The -y flag means it will install without prompting to continue first)

The second test, temporarily located on a hastly cleared shelf

Installing Mopidy

Before we can install Mopidy, we need to add it to our package resources as per their installation guilde.

  • Execute wget -q -O - | sudo apt-key add -
  • Execute sudo wget -q -O /etc/apt/sources.list.d/mopidy.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)

Installing Python Pip

Mopidy is written using Python and some of its extensions aren't installed via apt, but instead with Python's own package installer, Pip.

  • Execute sudo apt install python3-pip -y

Installing Mopidy-Iris

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!

  • Execute sudo python3 -m pip install Mopidy-Iris
  • Execute sudo sh -c 'echo "mopidy ALL=NOPASSWD: /usr/local/ lib/python3.7/dist-packages/mopidy_iris/" >> /etc/ sudoers' (this is for giving Mopidy permission to update Iris)

Installing Mopidy-Local

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.

  • Execute sudo python3 -m pip install Mopidy-Local

Configuring Mopidy

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.

  • Execute sudo nano /etc/mopidy/mopidy.conf

Add the following content, replacing paths as appropriate.

enabled = false

playlists_dir = /srv/music/playlists

hostname = ::

media_dir = /srv/music
scan_timeout = 10000
scan_flush_threshold = 100

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.

The scan_timeout and 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 scan_timeout to 10000 and decreasing scan_flush_threshold to 100 I have avoided some of these issues.

Enable Mopidy to run at start up

Although Mopidy installs a system service, this is isn't enabled.

  • Execute sudo systemctl enable mopidy to force Mopidy to start at boot time
  • Executesudo systemctl start mopidy to start Mopidy now

Checking the Mopidy configuration

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.

  • Execute sudo mopidyctl config

Installing Samba

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.

  • Execute sudo apt install samba -y
  • If you are asked any questions by the install, just accept the default value

Configuring Samba

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.

  • Execute sudo nano /etc/samba/smb.conf

Add the following lines to the end of the file, replacing the path as appropriate.

comment = Music
path = /srv/music
browseable = yes
guest ok = yes
read only = no
create mask = 777

Restarting Samba

As we've changed the configuration, we need to restart the service.

  • Execute sudo service smbd restart

Copying Music

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.

Updating the music 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.

  • Execute 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.

Installing pHAT Beat

(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.txt and re-enabled onboard sound, audio no longer played properly through it.

  • Execute curl | bash
  • When prompted to continue enter y
  • (Optional) When prompted to install examples and documentation, enter y. If you answer n, the VU meter won't automatically work. It was much easier to answer y than to install it from source
  • Once the installation has completed, answer y to reboot

Testing the speakers

To test your audio is working and you have the speakers the right way around, you can use the speaker-test program.

  • Execute speaker-test -c2 -t wav
  • Press Ctrl+C to terminate

Running Iris

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

(Optional) Adding a start up sound

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
  • Execute 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.

aplay /srv/music/sounds/tada.wav

(Optional) Reducing the master volume

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%

  • Execute 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 aplay.

amixer sset Master -- 70%

Closing Thoughts

The final unit, along with a frosted acrylic shield which produces a nice bokeh effect

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

About The Author


The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported