MPD

From NixOS Wiki
Revision as of 14:37, 15 February 2022 by imported>Joeriexelmans (Restructure article + add section on PipeWire)

Installation

A typical config, running MPD system-wide, will look like this:

services.mpd = {
  enable = true;
  musicDirectory = "/path/to/music";
  extraConfig = ''
    # must specify one or more outputs in order to play audio!
    # (e.g. ALSA, PulseAudio, PipeWire), see next sections
  '';

  # Optional:
  network.listenAddress = "any"; # if you want to allow non-localhost connections
  startWhenNeeded = true; # systemd feature: only start MPD service upon connection to its socket
};

Still missing in the above configuration is one or more audio_outputs. We will now see how MPD can be configured to work with ALSA, PulseAudio and PipeWire.

PulseAudio

In order to use MPD with PulseAudio, enable sound support in the NixOS configuration.nix :

# Enable sound.
sound.enable = true;
hardware.pulseaudio.enable = true;

Then, add a PulseAudio output to MPD:

services.mpd.extraConfig = ''
  audio_output {
    type "pulse"
    name "My PulseAudio" # this can be whatever you want
  }
'';

Now, according to https://wiki.archlinux.org/index.php/Music_Player_Daemon/Tips_and_tricks#Local_(with_separate_mpd_user), this will not work, because MPD and Pulseaudio are ran by different users.

PulseAudio workaround 1

One way to work around this issue is to configure MPD to use PulseAudio's TCP module to send sound to localhost". To enable the required PulseAudio modules, add

hardware.pulseaudio.extraConfig = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1";

to configuration.nix

And add server "127.0.0.1" to MPD's config to tell it to connect to PulseAudio's local sound server.

services.mpd.extraConfig = ''
  audio_output {
    type "pulse"
    name "Pulseaudio"
    server "127.0.0.1" # add this line - MPD must connect to the local sound server
  }
'';

After editing the configuration and running # nixos-rebuild switch, you can test if everything is working by using a MPD client, such as MPC.

PulseAudio workaround 2

Another workaround is to configure NixOS to run PulseAudio system-wide.

hardware.pulseaudio.systemWide = true; 

services.mpd.extraConfig = ''
    audio_output {
      type "pulse"
      name "Pulseaudio"
      mixer_type      "hardware"      # optional
      mixer_device    "default"       # optional
      mixer_control   "PCM"           # optional
      mixer_index     "0"             # optional
    }  '';
};

ALSA

You can also use alsa, just add audio output to services.mpd.extraConfig:

services.mpd.extraConfig = ''
  audio_output {
    type "alsa"
    name "My ALSA"
    device			"hw:0,0"	# optional 
    format			"44100:16:2"	# optional
    mixer_type		"hardware"
    mixer_device	"default"
    mixer_control	"PCM"
  }
'';

PipeWire

Make sure PipeWire is enabled. See https://nixos.wiki/wiki/PipeWire

To use PipeWire, create an audio_output for it:

services.mpd.extraConfig = ''
  audio_output {
    type "pipewire"
    name "My PipeWire Output"
  }
'';

See https://mpd.readthedocs.io/en/stable/plugins.html#pipewire for more options. However, similar to PulseAudio, MPD cannot connect to the PipeWire socket because MPD will by default run under a different user than PipeWire.

PipeWire workaround

PipeWire typically runs as a normal user, while MPD will run under a system user. A workaround is to configure MPD to run under the same user as PipeWire:

services.mpd.user = "userRunningPipeWire";
systemd.services.mpd.environment = {
    # https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/609
    XDG_RUNTIME_DIR = "/run/user/1000"; # User-id 1000 must match above user. MPD will look inside this directory for the PipeWire socket.
};

Source: https://github.com/NixOS/nixpkgs/issues/102547#issuecomment-1016671189

Further reading

MPD's output plugin documentation: https://mpd.readthedocs.io/en/stable/plugins.html#output-plugins

Arch Wiki : https://wiki.archlinux.org/index.php/Mpd