How to Add Files to mpd using python-mpd2

The music player daemon, mpd, and its client counterpart mpc operate on a managed directory structure. All paths are relative to this root directory. You cannot make mpd play a file from just anywhere, it seems.

This is important to know when you script MPDClient using python-mpd2, because when you try to add any absolute path, even those pointing into the managed directory, you’ll be in trouble.

mpd.base.CommandError: [4@0] {add} Access denied

That’s all you’ll get for an absolute file://-style URL.

And if you just use the absolute path without a protocol specification, you get:

mpd.base.CommandError: [50@0] {add} Malformed URI

The trick is to remember to exclusively use relative paths.

Instead of e.g.

/music/mpd/files/The Artist/The Album/The Track.mp3`

you pass in

The Artist/The Album/The Track.mp3

and all will be fine.

To make sure you get this right, have a look at the output of mpc listall where all accepted relative file paths are listed.

You can use os.path.relpath to remove the path to the managed music library from an absolute path. See the following classes for an example.

Types to manage music libraries

import os

class Album:
    def __init__(self, rel_path):
        self.rel_path = rel_path

    def name(self):
        return os.path.basename(self.rel_path)

class Library:
    def __init__(self, lib_path):
        self.path = os.path.abspath(lib_path)

    def _guard_exists(self):
        if not (os.path.exists(self.path) \
                and os.path.isdir(self.path)):
            raise Exception("Music library directory does not exist at: %s" % self.path)

    def all_albums(self):
        """Returns a list of Album objects in the library subdirectories, sorted by name."""
        return [Album(rel_path=path)
                for path in sorted(os.listdir(self.path))
                if os.path.isdir(os.path.join(self.path, path))]

I then use Album objects to make the audio player switch audio books.

Receive new .