Playing Music with Mopidy and Ncmpcpp

12 minute read Published:

Learn. Unlearn. Relearn.
Table of Contents

Maybe you’re stumped as to how to access that massive music collection painlessly, and a have a fear of missing out on the latest mixtapes and radio streams on the internet.

Why use Mopidy-MPD and Ncmpcpp? The answer is the reason we use Linux in the first place; for it’s elegance and configurability. The time spent learning is often richly rewarding in unexpected ways.

MPD stands for Music Player Daemon, which is also the name of the original MPD server project. Mopidy does not depend on the original MPD server, but implements the MPD protocol itself, and is thus compatible with most clients built for the original MPD server ~

By default Mopidy is a http server, it ships ready to leverage audio content on the web. Think client and daemon. Mopidy-MPD puts the MPD back in MoPiDy and allows us to use one of the many MPD user interfaces to play tunes on our laptop. The beauty of using a Raspberry Pi for this type of deployment, is because it is light on resources, freeing your devices up for other work.

Mopidy is fertile ground for hacking with Python, JavaScript, and JSON-RPC APIs as well as the extension support. Mopidy 3.0 was released in Dec ‘19 just in time for the projects’ 10th anniversary. It was comprehensively restructured, leaving Python 2 behind to be supported by minimum of Python 3.7. This means it can leverage some great new features in gstreamer 1.14. Mopidy’s creator, Stein Magnus Jodal explains the origin story.

Mopidy on a Raspberry Pi is a natural fit for the diminutive device. You can use your phone as a controller with mopidy-mobile or even wire arcade buttons to the GPIO pins with a 16x2 Adafruit LCD display using only pre-built extensions.

My Solar/Wind Powered Raspberry Pi Ex-Grandfather's Clock


Mopidy and ncmpcpp can be installed on Linux, Mac (with brew) or Windows Subsystem for Linux (WSL2). For a Debian-based distro:

wget -q -O - | sudo apt-key add -
sudo wget -q -O /etc/apt/sources.list.d/mopidy.list
sudo apt update
sudo apt install mopidy ncmpcpp mopidy-mpd mopidy-local mopidy-alsamixer mopidy-internetarchive mopidy-podcast mopidy-podcast-itunes mopidy-somafm mopidy-soundcloud  mopidy-tunein

To avoid port conflicts, remove plain old MPD if it’s installed.

sudo apt remove mpd

We can just type mopidy to run it, however it is generally preferred to run it as a service. My approach is usually to stumble along in the fog of uncertainty, so I was delighted to discover answers to some burning questions laid out in the docs (MacOS users are covered too).

For Debian, run

sudo dpkg-reconfigure mopidy

Package Configuration

For other Linux distros using systemd such as Fedora and Arch

sudo systemctl enable mopidy

This means we can use systemd control commands, handy when applying configuration changes. Running as a service, Mopidy will no longer refer to ~/.config/mopidy/mopidy.conf (it was created if you ran the mopidy command). The service uses a barebones /etc/mopidy/mopidy.conf (created on installation) to add usernames and passwords, and for custom extension settings that will work in concert to override the system defaults.

Configuration Starter File

The following Mopidy subcommand will list out the current configuration values to your terminal, and also warns of any errors.

sudo mopidyctl config

This is what I’ve got in mine

Expand my /etc/mopidy/mopidy.conf
cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy

config_file = /etc/mopidy/logging.conf
debug_file = /var/log/mopidy/mopidy-debug.log

media_dir = /home/briain/media/music

playlists_dir = /var/lib/mopidy/playlists

hostname = ::
# Helps toavoid timeout errors for large amounts of files
connection_timeout = 300

output = tee name=t t. ! queue ! autoaudiosink t. ! queue ! audioresample ! audioconvert ! audio/x-raw,rate=44100,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/mpd.fifo
## TODO: following will make localhost:5555 
## available as a source of data for the 
## stereo visualizer without the fifo hack.
# output = tee name=t ! queue ! autoaudiosink t.  ! queue ! audio/x-raw,rate=44100,channels=2,format=S16LE ! udpsink host=localhost port=6600
mixer_volume = 70

media_dirs = /home/briain/media/music
#follow_symlinks = false
#metadata_timeout = 1000

enabled = true
browse_root = /var/lib/mopidy/media/podcasts.opml

#enabled = true
musicapi_enabled = true

#enabled = true

#enabled = true
username = *******
password = *******************

enabled = true
explore_songs = 45
auth_token = ********************

The config file is only read when Mopidy starts and so you must restart for any configuration change to take effect.

sudo systemctl restart mopidy

An alternate command also works for us Debian users

sudo service mopidy restart

NCurses Music Player Client (Plus Plus)

Ncmpcpp is a rewrite of Ncmpc in C++. It provides new useful features such as support for regular expressions for library searches, extended song format, items filtering, the ability to sort playlists, and a local filesystem browser. It has been my music player of choice for many years. Terminal-based ncurses programs are easy on the eye by setting your ideal keycommands, font-size and colorscheme.

Ncurses stands for new curses and first emerged in 1993. Curses is a terminal control library for Unix-like systems (going back to 1980), enabling the construction of text user interface (TUI) applications. The name is pun on the term “cursor [curser] optimization”. Curses-based software can have a lighter resource footprint and operate on a wider range of systems (both in terms of hardware and software) than their GUI-based counterparts. ~Wikipedia

Example configuration files reside in /usr/share/doc/ncmpcpp/examples and can be copied over. I can share what I’ve got in mine

Expand my ~/.ncmpcpp/config
mpd_music_dir = "/home/user/media/music"
lyrics_directory  = "/home/user/.ncmpcpp/lyrics"
ncmpcpp_directory  = "/home/user/.ncmpcpp"
mpd_host = "localhost"
mpd_port = "6600"
# mpd_connection_timeout = "5"
mpd_crossfade_time = "3"

## Playlist ## 
playlist_disable_highlight_delay = "1"
#playlist_display_mode = "columns"
playlist_display_mode = "classic"
playlist_show_remaining_time = "yes"
browser_display_mode = "columns"
autocenter_mode = "yes"
fancy_scrolling = "yes"
follow_now_playing_lyrics = "yes"
display_screens_numbers_on_start = "yes"
ignore_leading_the = "yes"
lyrics_database = "1"
song_columns_list_format = "(10)[blue]{l} (30)[green]{a} (30)[magenta]{b} (50)[yellow]{t}"
colors_enabled = "yes"
enable_window_title = "yes"
external_editor = "nvim"

#main_window_highlight_color = "green"
volume_color = "red"
#progressbar_color = "black"
progressbar_color = "cyan"
statusbar_color = "default"
#statusbar_color = "white"
active_window_border = "red"
alternative_header_first_line_format = "$0$aqqu$/a {$7%a - $9}{$5%t$9}|{$8%f$9} $0$atqq$/a$9"
alternative_header_second_line_format = "{{$6%b$9}{ [$6%y$9]}}|{%D}"
alternative_header_second_line_format = "{{$6%b$9}{ [$6%y$9]}}"
song_list_format = "{$3%n │ $9}{$7%a - $9}{$5%t$9}|{$8%f$9}$R{$6 │ %b$9}{$3 │ %l$9}"
#user_interface = "alternative"
user_interface = "classic"
default_place_to_search_in = "database"

## Visualizer ##

## Fifo may be depreciated but I still use it (shrugs).
## Details in ncmpcpp example conf re: an address of  
## udpsink gstreamer's output instead of fifo
visualizer_fifo_path = "/tmp/mpd.fifo"
visualizer_output_name = "my_fifo"
# Depreciated, will be removed in version .10
visualizer_sync_interval = "30"
# Can be ellipse, wave or spectrum
visualizer_type = "ellipse" (spectrum/wave)
visualizer_in_stereo = "yes"
#visualizer_look = "+|"
#visualizer_look = "●┃"
#visualizer_color = "default"
visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161

## Navigation ##
cyclic_scrolling = "no"
header_text_scrolling = "no"
jump_to_now_playing_song_at_start = "yes"
lines_scrolled = "0"

## Other ##
system_encoding = "utf-8"
regular_expressions = "extended"

## Selected tracks ##
selected_item_prefix = "* "
discard_colors_if_item_is_selected = "yes"

## Seeking ##
incremental_seeking = "yes"
seek_time = "13"

## Visibility ##
header_visibility = "yes"
statusbar_visibility = "yes"
#statusbar_visibility = "no"
titles_visibility = "yes"

#progressbar_look = "─╼ "
progressbar_look =  "=>-"
#progressbar_elapsed_color = "white"

# Misc
now_playing_prefix = "$b$5"
now_playing_suffix = "$/b$9"
song_status_format = " $2%a $4⟫$3⟫ $8%t $4⟫$3⟫ $5%b "
autocenter_mode = "yes"
centered_cursor = "yes"
display_bitrate = "yes"
follow_now_playing_lyrics = "yes"
ignore_leading_the = "yes"
empty_tag_marker = ""
allow_for_physical_item_deletion = yes
execute_on_song_change = notify-send "Now Playing ♫" "$(mpc current)"

empty_tag_color = "black"

The program is run from the commandline.


Getting Started

Pressing 2 will take you to the browse screen. Press enter to open a directory. Enter will also queue up and play a track if the cursor is on one. Backspace to go to the parent directory. Space will load an entire directory into the current playlist.

The Browse Screen

Help Page

Pressing F1 will show the defaults as well as your customized key commands. Arrow keys and page up/down are the defaults for scrolling/paging.

Ncmpcpp Help Page

Customizing Bindings

Adding keyboard shortcuts, or changing existing ones to be more Vim-like. Change and add keybindings to actions in ~/.ncmpcpp/bindings. The example bindings file documents that you can bind chains of actions and create macros of commands and filters.

Ncmpcpp Key Bindings

Expand my ~/.ncmpcpp/bindings
## Additional to the defaults in example file
def_key "j"
def_key "k"
def_key "d"
def_key "u"
def_key "ctrl-f"
def_key "ctrl-b"
def_key "n"
def_key "P"
def_key "space"
def_key "backspace"
def_key "left"
def_key "right"
def_key "H"
def_key "h"
def_key "h"
def_key "l"
def_key "l"
def_key "l"
def_key "l"
def_key "ctrl-a"
def_key "J"
def_key "K"
def_key "ctrl-e"
def_key "t"
def_key "down"
def_key "up"
def_key "shift-up"
def_key "N"
def_key "shift-down"
def_key "F"
def_key "*"
def_key "L"
def_key "C"
def_key "+"
def_key "="

Global Shortcuts

Set global shortcuts in your desktop settings to run mpc commands from within any application, so you don’t have to change track to change the track. My most used are: toggle play/pause (mpc toggle), skip ahead (mpc seek +7%), change tracks (mpc next) and toggle random mode (mpc random).

The ability to delete a song from the hard drive is critical for shaping a collection. Make the following script executable with chmod u+x You can trigger it with a global shortcut. Found on KDE at System Settings -> Shortcuts -> Custom Shortcuts.


##TODO: Fine-tune this script for mopidy.
## It was working fine for mpd but mopidy 
## has some other way of aliasing files. 
## I tweaked the sed regex, and it's close to 
## working. Feel free to post a fix in the comments section 
## or email
song_to_remove=$(mpc | head -n 1)
playlist_pos=$(mpc -f %position% | head -n 1)
## Move the song into ~/.trash 
mv "$(mpc -f %file% | head -n 1 | sed 's/.*\/.\//\//')" ~/.trash
## Better still, delete the song completely
# rm "$(mpc -f %file% | head -n 1 | 's/.*\/.\//\//')"
## Remove the song from playlist
mpc del $playlist_pos
## Write to log file
echo "[`date`] -> --$song_to_remove-- gone to trash..." >> ~/.mpdremove.log


Core extensions are available from the system package manager. Dozens of others are available on PyPI and Github. Documentation on Github is often more complete. Somafm, Mixcloud, Internet Archive, Youtube Music and Itunes Podcasts are ready to use out-of-the-box

Aptitude Package Manager

Local Music

Set the location in /etc/mopidy/mopidy.conf

media_dir = /home/username/media/music

To index your music collection.

sudo mopidyctl local scan


TuneIn has thousands of free stations. Some favourites on a 5V 9” display. Pressing 1 takes you to the playlist screen.

Favorites Playlist

Youtube Music

Youtube Music presents curated playlists (as does the iTunes Podcast directory).

sudo python3 -m pip install Mopidy-YTMusic

Add the following to /etc/mopidy/mopidy.conf

musicapi_enabled = true

Playlist Categories

By default you are connected to YouTube Music as a guest account with several hundred playlists of 50-100 tracks. Connecting to your account will give you even more options.

If the links become unresponsive, flush the cache like so

sudo python3 -m pip install --force-reinstall --no-cache-dir Mopidy-YTMusic


To use our own podcasts.opml file that you have exported from antennapod, gpodder or some other podcast client:

#enabled = true
browse_root = /var/lib/mopidy/media/podcasts.opml

Commented options (lines starting with #) represent the defaults. Uncomment and change to false to remove the option from the Browse page (or else uninstall).


Google Play and Spotify require paid accounts (the free version doesn’t work). Others like Soundcloud can be connected via the extensions’ documentation page (you need to be currently signed in). An authorization token will be generated and there are instructions there on how to add it to /etc/mopidy/mopidy.conf

Connecting Soundcloud with MoPiDy


Your music can start as soon as your computer boots. From the docs:

Automatically pick up where you left off and start playing the last track from the position before Mopidy was shut down. It also restores the tracklist options “Consume”, “Random”, “Repeat” and “Single”. It also remembers the volume and if Mopidy was muted. The exact behaviour is configurable, e.g. it is possible to force Mopidy to play a certain track or to start always unmuted.

sudo python3 -m pip install mopidy-autoplay

Search Engine

Searching will trawl through your extensions for tracks, albums, podcasts, mixtapes, streams and live recordings. Pressing 3 will get you there. Scroll your cursor to the relevant field(s), press enter and a text input box will appear at the bottom of the screen, enter. Scroll down to search and press enter. Same goes for reset

Search Screen

Music Visualization

For the visualizer, set the audio output in /etc/mopidy/mopidy.conf

output = tee name=t t. ! queue ! autoaudiosink t. ! queue ! audioresample ! audioconvert ! audio/x-raw,rate=44100,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/mpd.fifo
mixer_volume = 70

Configure the colors and layouts in ~/.ncmpcpp/config

#### Visualizer ####
visualizer_fifo_path = "/tmp/mpd.fifo"
visualizer_output_name = "my_fifo"
## visualizer_type can be spectrum, wave, or ellipse
visualizer_type = "ellipse" (spectrum/wave)
visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161

Press 8 for the Visualization screen


To save a debug log to file for sharing with others, you can pipe stdout and stderr to a file:

mopidy -vv 2>&1 | tee mopidy.log

The following few commands can also assist with troubleshooting

systemctl status mopidy
sudo mopidyctl deps
sudo journalctl -u mopidy
Expand for random troubleshooting
I ran into problems scanning the local music 
but later discovered that it was because I had 
removed the contents of the original /etc/mopidy/mopidy.conf 
and had replaced it with the contents of i
~/.config/mopidy/mopidy.conf when I changed over 
to running as a service.  Not too swift!

Running `sudo mopidyctl deps` warned that the 
read permission was missing from `/etc/mopidy/mopidy.conf` 
and that it failed to load. Normally the 
[postinstallation script]( 
sets it up correctly. However, the following command 
is what fixed it for me at the time. N.B. these steps are 
not required on a standard installation, however you 
could run into OS specific problems such as on PiMusicBox 
(plain Mopidy will give you less headaches). 

sudo chown mopidy /etc/mopidy/mopidy.conf

From the [docs]( 
"The Mopidy system service runs as the mopidy user, which is 
automatically created when you install the Mopidy package. 
The mopidy user will need `read access` to any 
local music you want Mopidy to play."

If your having issues with your `read access`, try 
adding the `mopidy` user to your username's group 

`sudo usermod -aG briain mopidy`
`sudo mopidyctl local scan`

If the scan still doesn't work, grant ownership 
of the `audio` group the to the `mopidy` user 

`sudo chown --recursive mopidy:audio /home/username/media/music`

The system is very robust and shouldn’t require much attention beyond committing the keystrokes to muscle memory 🎸 🎶 🕰 🎶 🌃

Support is available on the Discourse forum and Zulip chat.

FYI: Mopidy-MPD is currently looking for a new maintainer.

comments powered by Disqus