Updated on 09/01/2023 with more information about mpd and why I reccomend it.
I've spent like 4 hours total? in the last 2-3 days getting mpd and ncmpcpp to work on my laptop. If you're curious as to how to pronounce the second name, I have no idea what to tell you except that I can't help but read it as "nincompoop". The documentation for mpd and ncmpcpp both are very thorough, but there were a few things I struggled with, so I thought that I should put them here in case anyone else comes across the same roadblocks as I did.
Why should anyone use mpd and its front-end clients over a music player with a GUI? It looks cool, for one... it's infinitely more customizable, for two...
We all know that Spotify tracks everything you listen to— it kind of has to, so it can provide you with informed reccomendations and playlists (which honestly is the biggest pro and con about it). But I think there is reason to be leery about not actually having your music on your device. Spotify is SaaS and while there are many advantages that come with it, ultimately you do not have much control over your music. While you technically can download the music from Spotify to listen to it offline, you have to pay just for that option, which I find absurd.
Of course you can use FOSS media players like VLC, which has a nice and intuitive GUI, and I still do. But to those who are specifically interested in CLI programs should look into mpv (which is able to play videos) and mpd + ncmpcpp.
mpd stands for 'Music Player Daemon'. A daemon is a process that 'detaches' itself to run in the background, meaning that you as the user can't directly interact with it. Maybe one of the most notable (and perhaps infamous?) daemons is systemd, which is a whole suite of programs that manages the system processes of GNU/Linux distros, such as those of the desktop environment or audio configurations. The 'd' in systemd stands for 'daemon', so does the 'd' in 'mpd'. Anyways, the most important takeaway here being that you can't really access what's going on with mpd. Once you run it in the terminal, it scurries off to do its own thing. Because mpd is a music-playing server, it requires a client to interface with it.
Therefore, in order to interact with mpd, you will need a frontend. There are a variety of front-nd mpd clients, both GUI or CLI, but the most popular CLI one is ncmpcpp.
This mouthful of a program makes up the user interface for mpd. It stands for 'n-curses music player client plus plus', as it was built off of a previously existing client, ncmp. With ncmpcpp (and most other mpd clients), you can create and organize playlists, edit music file metadata, queue songs, and more. ncmpcpp has a neat visualization feature as well, and it also allows you to use regular expressions to traverse through your files, which I always appreciate. Note that ncmpcpp is a command-line program, so you'll be doing everything through your terminal or whatever emulator you use.
Device info, or why don't I just pull up neofetch?
- Device: MacBook Pro
- OS: MacOS Monterey 12.4
- Package manager: homebrew
- Text Editor: vim (semi-important if you want to edit your config files in a practical way, but I think using the default macOS text editor, TextEdit, should be fine (you should totally use vim though wink wink))
- Also note that I download most (if not all) of my music
via Soulseek, which stores its files by default in
~/Soulseek Downloads. You'll want to set up a directory that stores all your music files beforehand.
Installation is pretty straightforward with homebrew. For mpd, run either
brew install mpd (or
brew search mpd if you
want to check if you have the mpd cask in the first place). You
could also compile from source on the GitHub page, but mpd
and ncmpcpp does have a few dependencies which might be a pain
to track down and install without homebrew or a package manager.
No surprise, installing ncmpcpp is as simple as
install ncmpcpp (once again, search for it beforehand if
you want to be careful).
As expected of a CLI program, both ncmpcpp and mpd are extremely configurable and many people more experienced than I am have already put up guides and even their own config files you can lift and fiddle with — so I'll just be linking to those I found most helpful and also listing the most basic of basic configurations that you'll need to get them up and running.
My device's config file path for mpd (downloaded using homebrew
in Dec 2022):
My devices's config file path for ncmpcpp (downloaded using
homebrew in Dec 2022):
*These will definitely differ depending on how you set up your own directories and config files. For simplicity's sake, sticking to one config file will be best as you don't want to fall into the trap of not knowing which file your program is reading from. There are ways to figure it out... but it's probably better to be organized from the get-go, and not have your system be cluttered up with extra config files.
For your mpd config:
- A music directory (set to ~/music by default. Just choose whichever directory you're storing your music files in)
- A playlist directory (should be an empty folder. You don't manually store your playlists here! mpd and ncmpcpp fills this directory on their own as you initialize them)
- db, pid, state files (all empty files, named mpd.db, mpd.pid, and mpd.state respectively. mpd and ncmpcpp will fill these files as you start them)
- Network/port addresses (I think by default it's set to any available port
and address, but I know you can bind mpd to multiple addresses; I have the
address set to
127.0.0.1for streaming music on your local device, which I'm assuming is what you want to do too.)
For your ncmpcpp config:
- A music directory (should be the same as in your mpd config)
- the ncmpcpp directory (where your ncmpcpp files are, mine is simply
- hosts and ports (should be the same as in your mpd config)
- ncmpcpp cheatsheet, a resource that shows all default ncmpcpp keybindings and functions
- dotshare.it for mpd/ncmpcpp, a massive repository of config files others have already written for you, especially nice if you want a pre-existing visual theme to add onto your ncmpcpp config, or to tinker with a template. This site is amazing because it also has config templates for shells, window managers, and vim/emacs.
- comprehensive blogpost about installing and configuring mpd/ncmpcpp, includes ways to connect to Youtube Music, Soundcloud, etc. This guide uses Mopidy which is a music server written in Python, and can be interfaced the same way with ncmpcpp and other mpd clients.
- Obligatory links to the mpd documentation and ncmpcpp faq page.
Running mpd and ncmpcpp by themselves might not yield you the
most helpful of error descriptions, tending to be pithy
statements like "Malformed path" or "No database found".
Using the tags
--verbose --stdout --no-daemon generates
more detailed error messages, including showing where both of the
programs are reading the config files from, and where exactly they
fail in their start-up process.
You type in "mpd" and hit enter. Everything seems to be going
fine. You do it again, but this time there's an error message that says
exception: Failed to bind to '0.0.0.0:6600'; Failed to bind socket: Address already in use.
This confused me to no end in the beginning, and I think it would be confusing in general if it's your first time (like me) getting up close and personal with a daemon. Because mpd is a daemon, once you start an instance of it, it will occupy that port, running untouchable in the background until you kill it. It is possible to run multiple instances of mpd, but that's outside of the scope of this post. If you're curious about doing so, there is a section on the Arch Wiki (of course there is) on a multi-mpd setup.
You can kill the process (and free up that port to restart another instance of mpd) with this command:
This will list ('lsof' meaning 'list open files') all the processes that are running at the port address you indicated; for example, if you're running it in the port 6600, the command would be lsof -i:6600. But more importantly, it will also list their PIDs (process IDs), which you need to kill the currently running daemon.
You might not have the lsof command installed, which will throw an
error. You can get it by running
brew install lsof.
Now you can run:
to free up that port, leaving you free to run mpd again without worry, ad nauseam.
For MacBooks, mpd automatically finds the audio output, so you don't have to define one in your config file. Apple has changed the audio API a few times before, so I recommend not explicitly defining an output unless you want to use the visualizer (as that technically requires more than one audio output to be configured).
Silly errors with the database ate up most of my troubleshooting time.
Let me reiterate that the files you create for ncmpcpp and mpd should
be empty, that the music and playlist paths should point to directories
and not files, and to make ample use of the
command. As always, the Ubuntu and Arch Linux forums probably already have
documentation and/or informative discussions on any of the more common
problems you might run into, but be careful with copy and pasting
terminal commands you find online, and make sure you have at least an idea
of what the command is actually doing.
Again, both mpd and ncmpcpp are extensively documented. Peruse the manuals and FAQs first before going to forums or Reddit threads!
mpd is a powerful program, and ncmpcpp is a fantastic front-end client for it. I hope you don't have too much trouble with setting them up on your device, and if you do, I hope you learn a lot about daemons and the CLI as I have! Hopefully this might spark your interest about other cool CLI programs, and make you more comfortable with working in the terminal.
I'll try my best to help you out if you're having any problems with mpd/ncmpcpp that I haven't included on this page, you can contact me either via email or XMPP. Thanks for reading :)
Pretty minimal for now, basically the only things you need to get started.
# MPD Configuration file music_directory "~/Music" playlist_directory "~/.mpd/playlists" db_file "~/.mpd/mpd.db" pid_file "~/.mpd/mpd.pid" state_file "~/.mpd/mpd.state" # For network bind_to_address "0.0.0.0" bind_to_address "127.0.0.1"
# Files mpd_music_dir = "~/Music" lyrics_directory = ~/.ncmpcpp/lyrics ncmpcpp_directory = ~/.ncmpcpp mpd_host = "localhost" mpd_port = "6600" mpd_connection_timeout = "5" mpd_crossfade_time = "5"