~hristoast/hristoast

4bf755add9b735aa97030f288cfaae81c60c8a7c — Hristos N. Triantafillou a month ago 02b0440
Publish: Listening To Music On Linux With MPD - Part 4

Update prior posts about MPD to link back to this one.
A site/blog/listening-to-music-on-linux-with-mpd-part-4.html => site/blog/listening-to-music-on-linux-with-mpd-part-4.html +275 -0
@@ 0,0 1,275 @@
<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 now 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>

M site/mpd-local-listening.html => site/mpd-local-listening.html +2 -2
@@ 1,11 1,11 @@
<h1 id="title">MPD for local listening</h1>

<div id="dates">
  <span>Posted: <time id="post-date">2016-03-27</time> | Updated: <time>2017-02-25</time></span>
  <span>Posted: <time id="post-date">2016-03-27</time> | Updated: <time>2017-02-25</time>, <time>2021-01-04</time></span>
</div>

<p>
  <span class="bold">UPDATE!</span> Check out <a href="/mpd-through-a-bluetooth-speaker/">my other post on MPD</a> to see how some of the flaws of the setup described here are resolved!
  <span class="bold">UPDATE!</span> Check out <a href="/blog/listening-to-music-on-linux-with-mpd-part-4/">my latest post on MPD</a> to see an updated writeup on my MPD setup and usage.
</p>

<p id="post-excerpt">

M site/mpd-my-setup-2018.html => site/mpd-my-setup-2018.html +2 -4
@@ 1,13 1,11 @@
<h1 id="title">MPD: My Setup 2018</h1>

<div id="dates">
  <span>Posted: <time id="post-date">2018-04-21</time> | Updated: <time>2020-12-10</time></span>
  <span>Posted: <time id="post-date">2018-04-21</time> | Updated: <time>2020-12-10</time>, <time>2021-01-04</time></span>
</div>

<p><span class="bold">UPDATE</span>: Of course not even a week after I posted this, I've made yet another tweak -- see the Bonus section at the end of the entry for more details.</p>

<p>
  It's also worth mentioning that since I published this and the updated entry, I've stopped using a Bluetooth speaker with MPD. There were just too many issues with reliability and "lag" that I now connect my bluetooth speaker with an audio cable. A fair warning for those that want to go down this path.
  <span class="bold">UPDATE!</span> Check out <a href="/blog/listening-to-music-on-linux-with-mpd-part-4/">my latest post on MPD</a> to see an updated writeup on my MPD setup and usage.
</p>

<p id="post-excerpt">

M site/mpd-through-a-bluetooth-speaker.html => site/mpd-through-a-bluetooth-speaker.html +2 -2
@@ 1,11 1,11 @@
<h1 id="title">MPD through a bluetooth speaker</h1>

<div id="dates">
  <span>Posted: <time id="post-date">2017-02-25</time> | Updated: <time>2020-12-10</time></span>
  <span>Posted: <time id="post-date">2017-02-25</time> | Updated: <time>2020-12-10</time>, <time>2021-01-04</time></span>
</div>

<p>
  <span class="bold">UPDATE:</span> be sure to check out <a href="/mpd-my-setup-2018/">my updated entry on MPD</a>!
  <span class="bold">UPDATE!</span> Check out <a href="/blog/listening-to-music-on-linux-with-mpd-part-4/">my latest post on MPD</a> to see an updated writeup on my MPD setup and usage.
</p>

<p>