MPD: Difference between revisions

From NixOS Wiki
imported>The pumpkin man
mNo edit summary
→‎Installation: fix startWhenNeeded option
 
(6 intermediate revisions by 5 users not shown)
Line 1: Line 1:
== Installation ==
== Installation ==
First you have to enable sound support in the NixOS <code>configuration.nix</code> :
A typical config, running MPD system-wide, will look like this:
<syntaxhighlight lang="nix">
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
  network.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 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 24:
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 :
Then, add a PulseAudio output to MPD:
<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 :
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.mpd.extraConfig = ''
services.mpd.extraConfig = ''
   audio_output {
   audio_output {
     type "pulse"
     type "pulse"
     name "Pulseaudio"
     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 45:
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.extraConfig = ''
Line 38: Line 51:
     type "pulse"
     type "pulse"
     name "Pulseaudio"
     name "Pulseaudio"
    server "127.0.0.1" # add this line - MPD must connect to the local sound server
   }
   }
'';
'';
</syntaxhighlight>
</syntaxhighlight>
Add the <code>server "127.0.0.1"</code> line :
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>.
 
=== PulseAudio workaround 2 ===
Another workaround is to configure NixOS to run PulseAudio system-wide.
 
<syntaxhighlight lang="nix">
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
    }  '';
};
</syntaxhighlight>
 
== ALSA ==
You can also use alsa, just add audio output to services.mpd.extraConfig:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.mpd.extraConfig = ''
services.mpd.extraConfig = ''
   audio_output {
   audio_output {
     type "pulse"
     type "alsa"
     name "Pulseaudio"
     name "My ALSA"
     server "127.0.0.1"
     device "hw:0,0" # optional
    format "44100:16:2" # optional
    mixer_type "hardware"
    mixer_device "default"
    mixer_control "PCM"
   }
   }
'';
'';
</syntaxhighlight>
</syntaxhighlight>


Done ! You can now test if everything is working by using a MPD client, such as <code>MPC</code>.
== PipeWire ==
Make sure PipeWire is enabled. See [[PipeWire]]


Note : before testing, restart the MPD service :
To use PipeWire, create an <code>audio_output</code> for it:
<syntaxhighlight lang="nix">
services.mpd.extraConfig = ''
  audio_output {
    type "pipewire"
    name "My PipeWire Output"
  }
'';
</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.


<code># systemctl restart mpd</code>
=== 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:


== Summary ==
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
# Enable sound.
services.mpd.user = "userRunningPipeWire";
sound.enable = true;
systemd.services.mpd.environment = {
hardware.pulseaudio = {
     # 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.
  extraConfig = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1"; # Needed by mpd to be able to use Pulseaudio
}
 
# Music daemon, can be accessed through mpc or an other client
services.mpd = {
  enable = true;
  extraConfig = ''
     audio_output {
      type "pulse" # MPD must use Pulseaudio
      name "Pulseaudio" # Whatever you want
      server "127.0.0.1" # MPD must connect to the local sound server
    }
  '';
};
};
</syntaxhighlight>
</syntaxhighlight>
Source: https://github.com/NixOS/nixpkgs/issues/102547#issuecomment-1016671189


== Further reading ==
== Further reading ==
The legendary Arch Wiki : https://wiki.archlinux.org/index.php/Mpd
MPD's output plugin documentation: https://mpd.readthedocs.io/en/stable/plugins.html#output-plugins
 
Arch Wiki : https://wiki.archlinux.org/index.php/Mpd
 
[[Category:Audio]]
[[Category:Applications]]

Latest revision as of 07:49, 13 July 2024

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
  network.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 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/${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