<h1 id="title">Listening To Music On Linux With MPD - Part 4</h1>
<div id="dates">
<span>Posted: <time id="post-date">2021-01-04</time></span>
</div>
<p id="post-excerpt">
As a follow up to my earlier pieces about using MPD <span class="footnote"><a href="/blog/mpd-my-setup-2018/"> MPD: My Setup 2018</a></span> <span class="footnote"><a href="/blog/mpd-through-a-bluetooth-speaker/"> MPD through a bluetooth speaker</a></span> <span class="footnote"><a href="/blog/mpd-local-listening/"> MPD for local listening</a></span>, I present to you a rundown of my current setup for listening to music with MPD. Things are mostly the same as before, but I now do things somewhat differently so I thought this could be a nice opportunity to tie things together. There's no need to read my prior posts unless you want to; this one will cover everything end-to-end as they do. With that out of the way, let's crank the volume!
</p>
<div id="toc"></div>
<h2>Why MPD?</h2>
<p>
It's worth noting why I prefer to use MPD. There are plenty of really great graphical music players such as <a href="https://www.strawberrymusicplayer.org/">Strawberry</a> and <a href="https://quodlibet.readthedocs.io/en/latest/">QuodLibet</a>, so why go to the trouble of using MPD?
</p>
<p>
There are probably many ways to answer that question, but for me it boils down to a few things:
</p>
<ul>
<li>My previous GUI music player was starting to use very large amounts of RAM after opening and indexing my large collection. <span class="footnote"> <a href="https://en.wikipedia.org/wiki/Clementine_(software)">Clementine</a>, which by the way is (was?) a fantastic piece of software.</span> This was a problem if I was doing anything else, which I usually am. <span class="footnote"> I rarely use my laptop as a jukebox, but it does happen from time to time.</span> <span class="footnote"> GUI stands for <a href="https://en.wikipedia.org/wiki/Graphical_user_interface">Graphical user interface</a>.</span></li>
<li>The server-client architecture makes it easy to use a mobile device as a remote control, and do other things you might not know you'd want such as the HTTP server (more on that <a href="#extras--httpd-server">later</a>).</li>
<li>It handles large collections without needing several GBs of RAM. <span class="footnote"> In general, resource usage on my server+client setup is very low. I don't have any hard data to demonstrate this, just the anecdote of my years of experience using and observing this setup.</span></li>
<li>It's very fast. <span class="footnote"> Even on older hardware, like my Thinkpad T61.</span></li>
<li>Awesome TUI clients such as <a href="https://github.com/ncmpcpp/ncmpcpp#ncurses-music-player-client-plus-plus">ncmpcpp</a>. <span class="footnote"> TUI stands for <a href="https://en.wikipedia.org/wiki/Text-based_user_interface">Text-based user interface</a>.</span></li>
</ul>
<p>
In a nutshell, the main initial selling points for me were the low resource usage and good performance points. After dealing with other players bringing my system to a slow crawl, I needed a change. <span class="footnote"> That was in 2015 and I've since never looked back! I have looked at how other players have advanced, which is how I found out about Strawberry, but MPD remains as what does the job best for me.</span>
</p>
<h2>What Do You Need?</h2>
<p>
To use MPD, you need to run a server and connect to it with a client. There are a variety of clients, my primary being ncmpcpp, mentioned above. I highly encourage you to look around for the right client, but if you like TUI applications then ncmpcpp is a great place to start. In any case, this entry will limit discussion largely to only this client.
</p>
<h3>The Server: The Service</h3>
<p>
I run the server as a runit user service, but most if not all distros ship MPD with a system-level service file. <span class="footnote"> Including the one I use, Void Linux.</span> It's up to you how to run it, I go the "user service" route because this doesn't need any extra privileges; running as my normal login user is totally fine, for this setup.
</p>
<p>
This is what my service file (<code>$HOME/.local/sv/mpd/run</code>) looks like:
</p>
<pre><code>#!/bin/sh
exec mpd --no-daemon /home/hristos/music/mpd/mpd.conf</code></pre>
<p>
I have a fish function that I use as a shortcut for interacting with it:
</p>
<pre><code>$ functions usv
# Defined in /home/hristos/.config/fish/config.fish @ line 224
function usv
env SVDIR=$HOME/.local/sv sv $argv
end</code></pre>
<p>
This makes managing the service much nicer:
</p>
<pre><code>$ usv stop mpd
ok: down: mpd: 0s, normally up
$ usv start mpd
ok: run: mpd: (pid 25536) 0s</code></pre>
<p>
Of course there are many ways to run a service like MPD. Do what works best for you or what your OS requires you to do.
</p>
<h3>The Server: The Config</h3>
<p>
As for the server configuration, there's nothing special going on:
</p>
<pre><code>music_directory "~/music"
bind_to_address "0.0.0.0:6600"
bind_to_address "~/music/mpd/socket"
playlist_directory "~/music/mpd/playlists"
db_file "~/music/mpd/mpd.db"
pid_file "~/music/mpd/mpd.pid"
state_file "~/music/mpd/mpdstate"
log_file "~/music/mpd/mpd.log"
user "hristos"
group "hristos"
restore_paused "yes"
replaygain "off"
audio_output {
type "pulse"
name "pulse"
server "localhost"
}
audio_output {
type "fifo"
name "Visualizer"
path "~/music/mpd/mpd.fifo"
format "44100:16:2"
}
audio_output {
type "httpd"
name "http"
port "8340"
encoder "vorbis"
format "44100:16:1"
}</code></pre>
<p>
At the top I set various server parameters such as where the music lives, where to write the socket, where to read playlists, and so on. I've got two values for <code>bind_to_address</code>; you can omit the first one that defines the port if you aren't going to need remote connections (for instance, to use the Android client).
</p>
<p>
The following three <code>audio_output</code> blocks each define how MPD emits music for me to enjoy:
</p>
<ul>
<li><code>pulse</code>: This is what I listen to; the audio playback is directed into PulseAudio and the system handles it like any other application. <span class="footnote"> In my full setup, I use a Pulse-to-Jackd bridge, but that's for another blog entry.</span></li>
<li><code>fifo</code>: This is what generates the ncmpcpp visualizer. Technically optional, but there's little reason to not have it! <span class="footnote"> Unless, of course, you aren't into visualizers. Then for sure just omit this.</span></li>
<li><code>httpd</code>: This streams your music via an HTTP endpoint. It is this feature which drives the <a href="/radio">radio page</a> of this very website. Definitely optional; most users probably don't have a need for this. More on this <a href="#extras--httpd-server">later</a>.</li>
</ul>
<p>
This is more or less the same setup I've used since the beginning, which as I write this makes me think that another feature of MPD is that it stays the same.
</p>
<h3>The Client: The Choices</h3>
<p>
Although ncmpcpp is my primary MPD client, I do actually employ two other clients that are worth mentioning:
</p>
<ul>
<li><code>mpc</code>: This one ships with MPD and is a command-line client. I've mapped some of my keyboard's media keys to mpc commands to enable skipping tracks and stopping/pausing/playing playback. I also use it to enable dunst notifications of track playback events. More on both of these below.</li>
<li><a href="https://f-droid.org/en/packages/org.gateshipone.malp/">M.A.L.P.</a>: This Android client allows for full media control and has many nice features. It could be your primary client, if you wished. I use this seldomly as a remote control, when the need arises.</li>
</ul>
<h3>The Client: The Config</h3>
<p>
My ncmpcpp config (<code>$HOME/.ncmpcpp/config</code>) is pretty short, but there are some key things inside:
</p>
<pre><code>execute_on_song_change = notify-send "♫ Now Playing: $(mpc current)"
mpd_host = "~/music/mpd/socket"
visualizer_fifo_path = "~/music/mpd/mpd.fifo"
visualizer_output_name = "Visualizer"
visualizer_sync_interval = "120"
visualizer_in_stereo = "yes"
visualizer_type = "spectrum"
visualizer_look = "◆▋"</code></pre>
<p>
The first line sends a notification message when a new song begins playback, and the second line points us to the MPD server socket.
</p>
<p>
The rest of the config is setup for the visualizer and can be omitted if you don't use that. In any case, pretty simple stuff that's easy to reason about.
</p>
<h2>Bluetooth?</h2>
<p>
My previous blog entries about MPD discussed using it with a bluetooth speaker. Since then, I've actually dropped bluetooth from my stack and now connect the speaker to my laptop with an eighth inch audio cable.
</p>
<p>
No matter what I did, I always seemed to end up with playback skipping when using bluetooth. I tried to work with it and around it for years, but this past summer I decided I had enough and got a cheap cable.
</p>
<p>
Of course now, with a cable, playback skipping is nonexistent and I don't have to mess with pairing. Still, if you want to go the bluetooth route: do be aware that it mostly works but has some annoying pitfalls.
</p>
<p>
In any case, I'm no longer including bluetooth coverage as part of my MPD setup. If you're interested in that, please refer to <a href="/blog/mpd-through-a-bluetooth-speaker/">my older post</a> but do note that it isn't fully comprehensive in describing all the things you may need to do for an optimal experience.
</p>
<h2>Extras: Keyboard Controls</h2>
<p>
Technically optional but potentially useful: I'll discuss my setup for using the media keys on my keyboard to control MPD. This is essentially unchanged from <a href="/blog/mpd-my-setup-2018/#controls">before</a>, I'm just re-covering it here for posterity.
</p>
<p>
I'm using <code>xbindkeys</code> to handle these keybinds, and here's a snippet of the MPD parts of my <code>$HOME/.xbindkeysrc</code> file:
</p>
<pre><code>...
# Increase volume
"/home/hristos/.local/bin/volume-tweak --raise"
XF86AudioRaiseVolume
# Decrease volume
"/home/hristos/.local/bin/volume-tweak --lower"
XF86AudioLowerVolume
# Play key
"mpc toggle"
m:0x0 + c:172
XF86AudioPlay
# Stop key
"mpc stop"
m:0x0 + c:174
XF86AudioStop
# Prev key
"mpc prev"
m:0x0 + c:173
XF86AudioPrev
# Next key
"mpc next"
m:0x0 + c:171
XF86AudioNext
# Muting
"/home/hristos/.local/bin/mute-or-not"
XF86AudioMute
...</code></pre>
<p>
The <code>volume-tweak</code> and <code>mute-or-not</code> scripts seen above are wrappers I've written to handle the various commands I need to use. They both interact with PulseAudio to properly set the volume up or down, or mute/unmute as needed.
</p>
<p>
Other keybinds simply use <code>mpc</code> directly. I get system notifications for those events "for free" due to the usage of <code>execute_on_song_change</code> in my ncmpcpp config file.
</p>
<h2>Extras: HTTPD Server</h2>
<p>
The vast majority of folks won't really have a use for this, but its a neat thing so I always like to discuss the httpd output feature of MPD.
</p>
<p>
As the name implies, the feature streams your playback over HTTP. And, as I mentioned above, it's actually this feature which drives the playback of this website's radio page.
</p>
<p>
I'm sure there are other possible creative usages for this, but for the normal "I need a music player" use-case I assume it isn't a feature folks usually look for.
</p>
<h2>Conclusion</h2>
<p>
MPD remains a key piece of software in my personal stack. It may sound silly to consider a music player like this, but it really is a major part of my productivity - I listen to music to relax, to work, and so on. It's fair to say I depend on it.
</p>
<p>
It's also worth noting that MPD isn't for eveyone. If the idea of running a service for your music player, and/or a TUI client isn't something you love, then MPD might not be right for you.
</p>
<p>
Additionally: the setup described here is meant for a local collection that you actually own. If you're a user of music "services" then MPD may or may not work for you at all.
</p>
<p>
In any case, thank you for reading this far! I hope you found it a useful reference, or an interesting read. And whether or not MPD is your ideal music player it is definitely worth a look if you've never tried it before.
</p>
<h2>Footnotes And References</h2>
<div id="footnotes"></div>