Adding mopidy to my Raspberry Pi Based Media System

In a past blogpost I described how I did set up a media system based on snapcast and librespot.

What I didn't get to yet was configuring mopidy to play music from my NAS.

installing mopidy

Installing mopidy is as easy as sudo pacman -S mopidy. Configuring snapcast and mopidy to play music works as follows:

  1. Editing /etc/snapserver.conf

    source = pipe:///run/snapserver/snapfifo?name=mopidy
    
  2. Editing /etc/mopidy/mopidy.conf to configure mopidy's audio output

    [audio]
    output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! filesink location=/run/snapserver/snapfifo
    

To be able to play local files I wanted to use the Mopidy-Local extension. For that I needed to install the following packages from the AUR:

To get access to the music collection of the NAS I mounted the path system wide via /etc/fstab.

To not store the credentials in plaintext in /etc/fstab directly I created a credentials file in /var/lib/private:

# /var/lib/private/nas-cifs-credentials
username=your_username
password=your_password
domain=your_domain  # Optional, if applicable

To give mopidy access to the files, we need to know its user and group ID:

$ cat /etc/passwd|grep mopidy
mopidy:x:46:46:Mopidy User:/var/lib/mopidy:/usr/bin/nologin

and put it together like this:

#/etc/fstab
//$IP_OF_NAS/$PATH_TO_MUSIC  /mnt/music  cifs  credentials=/var/lib/private/nas-cifs-credentials,uid=46,gid=46  0  0

Then we need to tell the mopidy extension where our music is:

#/etc/mopidy/mopidy.conf
[local]
media_dir = /mnt/music
scan_timeout = 5000

And let it scan the directory:

$ sudo mopidyctl local scan

The rather long scan_timeout of 5s is needed since my NAS goes into power save mode when idle and needs some seconds for the initial response.

mopidy-mpd

To control mopidy I chose to use the mpoidy-mpd extension, also available from the AUR.

By default mopidy-mpd is only available from localhost. To make it usable from the network we need to configure it to listen on all interfaces for both IPv4 and IPv6:

[mpd]
hostname = ::

Trying to use it quickly revealed that the plugin is quite outdated and won't work with newer mpd clients:

$ mpc
warning: MPD 0.21 required
mpd version: 0.19.0

Looking at GitHub I found mopidy-mpd issue 68 and mopidy-mpd issue 47 which confirmed that.

Because of that I anticipated a lot of interoperability issues with newer clients and decided not to use it and uninstalled it again.

mopidy-iris

Instead of using an mpd client there is the option to use web interfaces to controll mopidy. mopidy-iris looked like a popular and well-maintained web interface for mopidy.

After installing and restarting mopidy we get greeted by it's webinterface when accessing http://$MOPIDY_HOST/iris/ 🎉

mopidy-iris welcome screen

mopidy-iris welcome screen

The interface is straightforward to use and allows to search and add music to the queue which is everything I want from it.

mopidy-iris playback

mopidy-iris playing an album

mopidy snapcast integration

Snapcast supports reporting and controlling the player state of sources via controllscripts on the source configuration

# /etc/snapserver.conf
source = pipe:///run/snapserver/snapfifo?name=mopidy&controlscript=meta_mopidy.py&controlscriptparams=--mopidy-host=muzikskatolo.home

I ran into a few issues:

  • The controlscript in /usr/share/snapserver/plug-ins/meta_mopidy.py wasn't marked as executable. This was fixed by the AUR package maintainer after I reported it

  • I didn't install the optional python-websocket-client dependency for snapserver which lead to a crash:

    /usr/share/snapserver/plug-ins/meta_mopidy.py
    Traceback (most recent call last):
      File "/usr/share/snapserver/plug-ins/meta_mopidy.py", line 25, in <module>
        import websocket
    ModuleNotFoundError: No module named 'websocket'
    

    Installing it with sudo pacman -S --asdeps python-websocket-client fixed it.

  • I needed to explicitly set the mopidy-host on the command line, since otherwise the generated links to the album art won't work since they would point to localhost.

Accessing the snapcast webinterface then allows us to see the metadata of the playing song:

snapcast meta sources

Snapcast has a nice feature called meta sources.

It allows to just play the audio from the first active source:

source = pipe:///run/snapserver/snapfifo?name=mopidy&controlscript=meta_mopidy.py&controlscriptparams=--mopidy-host=muzikskatolo.home
source = librespot:///usr/bin/librespot>?name=librespot&devicename=Snapcast
source = meta:///librespot/mopidy?name=any

Here I configured a meta source named "any" which plays audio from librespot or mopidy.

scanning the local library regularly

Running sudo mopidyctl local scan manually get's tedious over time when I add new music. So I created a systemd unit and a timer to run it daily:

# /etc/systemd/system/mopidy-local-scan.service
[Unit]
Description=Mopidy music server
After=remote-fs.target

[Service]
Type=oneshot
User=mopidy
ExecStart=/usr/bin/mopidy --config /usr/share/mopidy/conf.d:/etc/mopidy/mopidy.conf local scan
# /etc/systemd/system/daily@.timer
[Unit]
Description=Daily timer for %i service

[Timer]
OnCalendar=*-*-* 02:00:00
AccuracySec=6h
RandomizedDelaySec=1h
Unit=%i.service
Persistent=true
[Install]
WantedBy=timers.target

After creating the files we can reload systemd and enable the timer:

$ sudo systemctl daemon-reload
$ sudo systemctl enable daily@mopidy-local-scan.timer

Created symlink '/etc/systemd/system/timers.target.wants/daily@mopidy-local-scan.timer' -> '/etc/systemd/system/daily@.timer'.
$ sudo systemctl list-timers  --all
NEXT                            LEFT LAST                              PASSED UNIT                             ACTIVATES
Sun 2025-02-23 00:00:00 UTC 3h 30min Sat 2025-02-22 09:42:48 UTC      10h ago shadow.timer                     shadow.service
Sun 2025-02-23 02:56:10 UTC       6h Sat 2025-02-22 18:38:44 UTC 1h 50min ago daily@mopidy-local-scan.timer    mopidy-local-scan.service
Sun 2025-02-23 09:57:33 UTC      13h Sat 2025-02-22 09:57:33 UTC      10h ago systemd-tmpfiles-clean.timer     systemd-tmpfiles-clean.service
Fri 2025-02-28 16:49:57 UTC   5 days Mon 2025-02-10 09:45:18 UTC            - archlinux-keyring-wkd-sync.timer archlinux-keyring-wkd-sync.service

4 timers listed.

With mopidy, librespot and snapcast I have a nice solution to listen to the music I bought from Bandcamp and stream from Spotify in my home.

blogroll

social