Jump to content

MPD: Difference between revisions

From Official NixOS Wiki
imported>Novmar
No edit summary
Novida (talk | contribs)
m fix duplicate code block error
 
(9 intermediate revisions by 8 users not shown)
Line 1: Line 1:
== Installation ==
[https://www.musicpd.org/ Music Player Daemon] (MPD) is a flexible, powerful, server-side application for playing music. Through plugins and libraries, it can play a variety of sound files while being controlled by its network protocol.
First you have to enable sound support in the NixOS <code>configuration.nix</code> :
 
== Home-manager Installation ==
Home-manager has a module for MPD which runs it as a systemd user service, giving it easier access to your user's sound server. In most cases no specific audio output configuration is necessary:
<syntaxhighlight lang="nix">services.mpd = {
  enable = true;
  musicDirectory = "/path/to/music";
  # Optional:
  network.listenAddress = "any"; # if you want to allow non-localhost connections
  network.startWhenNeeded = true; # systemd feature: only start MPD service upon connection to its socket
};</syntaxhighlight>
 
 
== NixOS Installation ==
A typical NixOS config, running MPD system-wide, will look like this:
<syntaxhighlight lang="nix">
services.mpd = {
  enable = true;
  musicDirectory = "/path/to/music";
  settings = {
    # must specify one or more audio_output blocks 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
};
</syntaxhighlight>
Still missing in the above configuration is one or more <code>audio_output</code>s. We will now see how MPD can be configured to work with ALSA, PulseAudio and PipeWire.
 
== PulseAudio ==
In order to use system-wide MPD with PulseAudio, enable sound support in the NixOS <code>configuration.nix</code> :
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
# Enable sound.
# Enable sound.
Line 6: Line 37:
hardware.pulseaudio.enable = true;
hardware.pulseaudio.enable = true;
</syntaxhighlight>
</syntaxhighlight>
Now, this article will show you how to setup MPD by using Pulseaudio.
Enable the mpd service :
<syntaxhighlight lang="nix">services.mpd.enable = true;</syntaxhighlight>


To specify MPD to output using Pulseaudio, we have to specify <code>audio_output</code> in MPD's configuration :
Then, add a PulseAudio output to MPD:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.mpd.extraConfig = ''
services.mpd.settings = {
   audio_output {
   audio_output = [
    type "pulse"
    {
    name "Pulseaudio"
      type = "pulse";
   }
      name = "My PulseAudio"; # this can be whatever you want
'';
    }
   ];
};
</syntaxhighlight>
</syntaxhighlight>
<code>type</code> is to define whether we are using Pulseaudio or ALSA. <code>name</code> can be what you want.


Now, according to <cite>https://wiki.archlinux.org/index.php/Music_Player_Daemon/Tips_and_tricks#Local_(with_separate_mpd_user)</cite>, this will not work, because MPD and Pulseaudio are ran by different users. Still according to the Arch Wiki, we can "configure mpd to use pulseaudio's tcp module to send sound to localhost".
Now, according to <cite>https://wiki.archlinux.org/index.php/Music_Player_Daemon/Tips_and_tricks#Local_(with_separate_mpd_user)</cite>, this will not work, because MPD and Pulseaudio are ran by different users.


So, to enable the required Pulseaudio modules, add
=== 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
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
hardware.pulseaudio.extraConfig = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1";
hardware.pulseaudio.extraConfig = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1";
Line 30: Line 60:
to <code>configuration.nix</code>
to <code>configuration.nix</code>


And add <code>server "127.0.0.1"</code> to MPD's config to tell it to connect to Pulseaudio's local sound server.
And add <code>server "127.0.0.1"</code> to MPD's config to tell it to connect to PulseAudio's local sound server.
 
In
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.mpd.extraConfig = ''
services.mpd.settings = {
   audio_output {
   audio_output = [
    type "pulse"
    {
    name "Pulseaudio"
      type = "pulse";
  }
      name = "Pulseaudio";
'';
      server = "127.0.0.1"; # add this line - MPD must connect to the local sound server
</syntaxhighlight>
    }
Add the <code>server "127.0.0.1"</code> line :
   ];
<syntaxhighlight lang="nix">
};
services.mpd.extraConfig = ''
   audio_output {
    type "pulse"
    name "Pulseaudio"
    server "127.0.0.1"
  }
'';
</syntaxhighlight>
</syntaxhighlight>
After editing the configuration and running <code># nixos-rebuild switch</code>, you can test if everything is working by using a MPD client, such as <code>MPC</code>.


Done ! You can now test if everything is working by using a MPD client, such as <code>MPC</code>.
=== PulseAudio workaround 2 ===
Another workaround is to configure NixOS to run PulseAudio system-wide.


Note : before testing, restart the MPD service :
<syntaxhighlight lang="nix">
hardware.pulseaudio.systemWide = true;


<code># systemctl restart mpd</code>
services.mpd.settings = {
  audio_output = [
    {
      type = "pulse";
      name = "Pulseaudio";
      mixer_type  = "hardware"; # optional
      mixer_device = "default";  # optional
      mixer_control = "PCM";    # optional
      mixer_index  = "0";        # optional
    }
  ];
};
</syntaxhighlight>


== Summary ==
== ALSA ==
You can also use alsa, just add audio output to services.mpd.extraConfig:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
# Enable sound.
services.mpd.settings = {
sound.enable = true;
  audio_output = [
hardware.pulseaudio = {
    {
  enable = true;
      type = "alsa";
  extraConfig = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1"; # Needed by mpd to be able to use Pulseaudio
      name = "My ALSA";
      device        = "hw:0,0"; # optional
      format        = "44100:16:2"; # optional
      mixer_type    = "hardware";
      mixer_device  = "default";
      mixer_control = "PCM";
    }
  ];
};
};
</syntaxhighlight>
== PipeWire ==
Make sure PipeWire is enabled. See [[PipeWire]]


# Music daemon, can be accessed through mpc or an other client
To use PipeWire with a system-wide MPD instance, create an <code>audio_output</code> for it:
services.mpd = {
<syntaxhighlight lang="nix">
   enable = true;
services.mpd.settings = {
  extraConfig = ''
   audio_output = [
     audio_output {
     {
       type "pulse" # MPD must use Pulseaudio
       type = "pipewire";
       name "Pulseaudio" # Whatever you want
       name = "My PipeWire Output";
      server "127.0.0.1" # MPD must connect to the local sound server
     }
     }
   '';
   ];
};
};
</syntaxhighlight>
</syntaxhighlight>
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.


== Further reading ==
=== PipeWire workaround ===
The legendary Arch Wiki : https://wiki.archlinux.org/index.php/Mpd
PipeWire typically runs as a normal user, while a system-wide MPD instance will run under a system user. A workaround is to configure MPD to run under the same user as PipeWire:
== Another solution - pulseaudio with systemWide ==
You can also set pulseaudio running system wide.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
sound.enable = true;
services.mpd.user = "userRunningPipeWire";
  hardware.pulseaudio = {
systemd.services.mpd.environment = {
    systemWide = true;
     # https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/609
    enable = true;
     XDG_RUNTIME_DIR = "/run/user/${toString config.users.users.userRunningPipeWire.uid}"; # User-id must match above user. MPD will look inside this directory for the PipeWire socket.
  };
 
services.mpd = {
  enable = true ;
  extraConfig = ''
     audio_output {
      type "pulse"
      name "Pulseaudio"
      mixer_type      "hardware"      # optional
      mixer_device    "default"      # optional
      mixer_control  "PCM"          # optional
      mixer_index    "0"            # optional
     }  '';
  ## optional
  network.listenAddress = "any"; # allow to control mop from any host
  musicDirectory = "/path/to/some/music"; # ptah to your music
};
};
</syntaxhighlight>
</syntaxhighlight>
You can also use alsa, just add audio output to services.mpd.extraConfig
 
<syntaxhighlight lang="nix">
Source: https://github.com/NixOS/nixpkgs/issues/102547#issuecomment-1016671189
services.mpd = {
 
  enabled = true;
== Further reading ==
  extraConfig = ''
MPD's output plugin documentation: https://mpd.readthedocs.io/en/stable/plugins.html#output-plugins
    audio_output {
 
      type "alsa"
Arch Wiki : https://wiki.archlinux.org/index.php/Mpd
      name "alsa"
 
      device "hw:0,0" # optional
[[Category:Audio]]
      format "44100:16:2" # optional
[[Category:Applications]]
      mixer_type "hardware"
      mixer_device "default"
      mixer_control "PCM"
    }
  '';
}
</syntaxhighlight>

Latest revision as of 04:34, 7 June 2026

Music Player Daemon (MPD) is a flexible, powerful, server-side application for playing music. Through plugins and libraries, it can play a variety of sound files while being controlled by its network protocol.

Home-manager Installation

Home-manager has a module for MPD which runs it as a systemd user service, giving it easier access to your user's sound server. In most cases no specific audio output configuration is necessary:

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


NixOS Installation

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

services.mpd = {
  enable = true;
  musicDirectory = "/path/to/music";
  settings = {
    # must specify one or more audio_output blocks 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 system-wide 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.settings = {
  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.settings = {
  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.settings = {
  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.settings = {
  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 PipeWire

To use PipeWire with a system-wide MPD instance, create an audio_output for it:

services.mpd.settings = {
  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 a system-wide MPD instance 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/${toString config.users.users.userRunningPipeWire.uid}"; # User-id 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