Concept → IO ()

Linux Emacs Coding Music Links About Search

Pipewire network setup

My goal was to play audio over the network.

In detail, a computer with a sound card and speakers serves the audio device on the network (referred to as server). Other computers (referred to as clients) play audio which they send to the server to be played on the speakers managed by the servers. Ideally, this happens in real time without delay.

NixOS setup

I had such a service set up using Pulseaudio a while ago, but it being Pulseaudio I was eager to switch to Pipewire as soon as possible (Pipewire seems to be the cool kid on the block). There are numerous sources available talking about how easy a network setup was, however, I had trouble setting it up on NixOS. So I thought sharing my configuration may be useful to others.

Server NixOS module

_:

{
  services.pipewire.enable = true;
  services.pipewire.alsa.enable = true;
  services.pipewire.pulse.enable = true;

  # Publish audio sink on the local network.
  services.pipewire.extraConfig.pipewire-pulse."30-network-publish" = {
    "pulse.cmd" = [
      { cmd = "load-module"; args = "module-native-protocol-tcp"; }
      { cmd = "load-module"; args = "module-zeroconf-publish"; }
    ];
  };

  # Important: Open TCP port used by the Pulseaudio network sink.
  networking.firewall.allowedTCPPorts = [
    4713
  ];
}

Client NixOS module

_:

{
  services.pipewire.enable = true;
  services.pipewire.alsa.enable = true;
  services.pipewire.pulse.enable = true;

  services.pipewire.extraConfig.pipewire-pulse."30-network-discover" = {
    "pulse.cmd" = [
      { cmd = "load-module"; args = "module-zeroconf-discover"; }
    ];
  };
}

Avahi

Further, Avahi needs to be enabled and corresponding ports need to be opened in the firewall. I am not exactly sure how much of the following setup is required, but here you go:

# I do not know how much of this is necessary, but that's what I have in my configuration.
services.avahi.enable = true;
services.avahi.openFirewall = true;
services.avahi.publish.enable = true;
services.avahi.publish.addresses = true;
services.avahi.publish.domain = true;
services.avahi.publish.userServices = true;
services.avahi.publish.workstation = true;

Sources I used to come up with this configuration: