Unverified Commit 92b9d111 authored by K900's avatar K900 Committed by GitHub
Browse files

Merge pull request #282377 from hcsch/pipewire-wireplumber-config-packages

nixos/pipewire: add configPackages options
parents e3474e1d e722c561
Loading
Loading
Loading
Loading
+40 −11
Original line number Diff line number Diff line
# pipewire service.
# PipeWire service.
{ config, lib, pkgs, ... }:

with lib;

let
  json = pkgs.formats.json {};
  mapToFiles = location: config: concatMapAttrs (name: value: { "pipewire/${location}.conf.d/${name}.conf".source = json.generate "${name}" value;}) config;
  mapToFiles = location: config: concatMapAttrs (name: value: { "share/pipewire/${location}.conf.d/${name}.conf" = json.generate "${name}" value; }) config;
  extraConfigPkgFromFiles = locations: filesSet: pkgs.runCommand "pipewire-extra-config" { } ''
    mkdir -p ${lib.concatMapStringsSep " " (l: "$out/share/pipewire/${l}.conf.d") locations}
    ${lib.concatMapStringsSep ";" ({name, value}: "ln -s ${value} $out/${name}") (lib.attrsToList filesSet)}
  '';
  cfg = config.services.pipewire;
  enable32BitAlsaPlugins = cfg.alsa.support32Bit
                           && pkgs.stdenv.isx86_64
@@ -19,13 +23,33 @@ let
    mkdir -p "$out/lib"
    ln -s "${cfg.package.jack}/lib" "$out/lib/pipewire"
  '';

  configPackages = cfg.configPackages;

  extraConfigPkg = extraConfigPkgFromFiles
    [ "pipewire" "client" "client-rt" "jack" "pipewire-pulse" ]
    (
      mapToFiles "pipewire" cfg.extraConfig.pipewire
      // mapToFiles "client" cfg.extraConfig.client
      // mapToFiles "client-rt" cfg.extraConfig.client-rt
      // mapToFiles "jack" cfg.extraConfig.jack
      // mapToFiles "pipewire-pulse" cfg.extraConfig.pipewire-pulse
    );

  configs = pkgs.buildEnv {
    name = "pipewire-configs";
    paths = configPackages
      ++ [ extraConfigPkg ]
      ++ lib.optionals cfg.wireplumber.enable cfg.wireplumber.configPackages;
    pathsToLink = [ "/share/pipewire" ];
  };
in {
  meta.maintainers = teams.freedesktop.members ++ [ lib.maintainers.k900 ];

  ###### interface
  options = {
    services.pipewire = {
      enable = mkEnableOption (lib.mdDoc "pipewire service");
      enable = mkEnableOption (lib.mdDoc "PipeWire service");

      package = mkPackageOption pkgs "pipewire" { };

@@ -33,7 +57,7 @@ in {
        default = true;
        type = types.bool;
        description = lib.mdDoc ''
          Automatically run pipewire when connections are made to the pipewire socket.
          Automatically run PipeWire when connections are made to the PipeWire socket.
        '';
      };

@@ -200,6 +224,15 @@ in {
          '';
        };
      };

      configPackages = lib.mkOption {
        type = lib.types.listOf lib.types.package;
        default = [];
        description = lib.mdDoc ''
          List of packages that provide PipeWire configuration, in the form of
          `share/pipewire/*/*.conf` files.
        '';
      };
    };
  };

@@ -283,12 +316,8 @@ in {
      "alsa/conf.d/99-pipewire-default.conf" = mkIf cfg.alsa.enable {
        source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
      };
    }
    // mapToFiles "pipewire" cfg.extraConfig.pipewire
    // mapToFiles "client" cfg.extraConfig.client
    // mapToFiles "client-rt" cfg.extraConfig.client-rt
    // mapToFiles "jack" cfg.extraConfig.jack
    // mapToFiles "pipewire-pulse" cfg.extraConfig.pipewire-pulse;
      pipewire.source = "${configs}/share/pipewire";
    };

    environment.sessionVariables.LD_LIBRARY_PATH =
      lib.mkIf cfg.jack.enable [ "${cfg.package.jack}/lib" ];
@@ -301,7 +330,7 @@ in {
          "audio"
          "video"
        ] ++ lib.optional config.security.rtkit.enable "rtkit";
        description = "Pipewire system service user";
        description = "PipeWire system service user";
        isSystemUser = true;
        home = "/var/lib/pipewire";
        createHome = true;
+82 −31
Original line number Diff line number Diff line
@@ -14,48 +14,95 @@ in
        type = lib.types.bool;
        default = config.services.pipewire.enable;
        defaultText = lib.literalExpression "config.services.pipewire.enable";
        description = lib.mdDoc "Whether to enable Wireplumber, a modular session / policy manager for PipeWire";
        description = lib.mdDoc "Whether to enable WirePlumber, a modular session / policy manager for PipeWire";
      };

      package = lib.mkOption {
        type = lib.types.package;
        default = pkgs.wireplumber;
        defaultText = lib.literalExpression "pkgs.wireplumber";
        description = lib.mdDoc "The wireplumber derivation to use.";
      };
        description = lib.mdDoc "The WirePlumber derivation to use.";
      };

      configPackages = lib.mkOption {
        type = lib.types.listOf lib.types.package;
        default = [ ];
        description = lib.mdDoc ''
          List of packages that provide WirePlumber configuration, in the form of
          `share/wireplumber/*/*.lua` files.
        '';
      };

  config = lib.mkIf cfg.enable {
    assertions = [
      {
        assertion = !config.hardware.bluetooth.hsphfpd.enable;
        message = "Using Wireplumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
      }
    ];
      extraLv2Packages = lib.mkOption {
        type = lib.types.listOf lib.types.package;
        default = [];
        example = lib.literalExpression "[ pkgs.lsp-plugins ]";
        description = lib.mdDoc ''
          List of packages that provide LV2 plugins in `lib/lv2` that should
          be made available to WirePlumber for [filter chains][wiki-filter-chain].

    environment.systemPackages = [ cfg.package ];
          Config packages have their required LV2 plugins added automatically,
          so they don't need to be specified here.

    environment.etc."wireplumber/main.lua.d/80-nixos.lua" = lib.mkIf (!pwUsedForAudio) {
      text = ''
        -- Pipewire is not used for audio, so prevent it from grabbing audio devices
        alsa_monitor.enable = function() end
          [wiki-filter-chain]: https://docs.pipewire.org/page_module_filter_chain.html
        '';
      };
    environment.etc."wireplumber/main.lua.d/80-systemwide.lua" = lib.mkIf config.services.pipewire.systemWide {
      text = ''
    };
  };

  config =
    let
      pwNotForAudioConfigPkg = pkgs.writeTextDir "share/wireplumber/main.lua.d/80-pw-not-for-audio.lua" ''
        -- PipeWire is not used for audio, so prevent it from grabbing audio devices
        alsa_monitor.enable = function() end
      '';
      systemwideConfigPkg = pkgs.writeTextDir "wireplumber/main.lua.d/80-systemwide.lua" ''
        -- When running system-wide, these settings need to be disabled (they
        -- use functions that aren't available on the system dbus).
        alsa_monitor.properties["alsa.reserve"] = false
        default_access.properties["enable-flatpak-portal"] = false
      '';
    };
    environment.etc."wireplumber/bluetooth.lua.d/80-systemwide.lua" = lib.mkIf config.services.pipewire.systemWide {
      text = ''
      systemwideBluetoothConfigPkg = pkgs.writeTextDir "wireplumber/bluetooth.lua.d/80-systemwide.lua" ''
        -- When running system-wide, logind-integration needs to be disabled.
        bluez_monitor.properties["with-logind"] = false
      '';

      configPackages = cfg.configPackages
          ++ lib.optional (!pwUsedForAudio) pwNotForAudioConfigPkg
          ++ lib.optionals config.services.pipewire.systemWide [ systemwideConfigPkg systemwideBluetoothConfigPkg ];

      configs = pkgs.buildEnv {
        name = "wireplumber-configs";
        paths = configPackages;
        pathsToLink = [ "/share/wireplumber" ];
      };

      requiredLv2Packages = lib.flatten
        (
          lib.concatMap
            (p:
              lib.attrByPath ["passthru" "requiredLv2Packages"] [] p
            )
            configPackages
        );

      lv2Plugins = pkgs.buildEnv {
        name = "wireplumber-lv2-plugins";
        paths = cfg.extraLv2Packages ++ requiredLv2Packages;
        pathsToLink = [ "/lib/lv2" ];
      };
    in
    lib.mkIf cfg.enable {
      assertions = [
        {
          assertion = !config.hardware.bluetooth.hsphfpd.enable;
          message = "Using WirePlumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
        }
      ];

      environment.systemPackages = [ cfg.package ];

      environment.etc.wireplumber.source = "${configs}/share/wireplumber";

      systemd.packages = [ cfg.package ];

@@ -66,8 +113,12 @@ in
      systemd.user.services.wireplumber.wantedBy = [ "pipewire.service" ];

      systemd.services.wireplumber.environment = lib.mkIf config.services.pipewire.systemWide {
      # Force wireplumber to use system dbus.
        # Force WirePlumber to use system dbus.
        DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket";
        LV2_PATH = "${lv2Plugins}/lib/lv2";
      };

      systemd.user.services.wireplumber.environment.LV2_PATH =
        lib.mkIf (!config.services.pipewire.systemWide) "${lv2Plugins}/lib/lv2";
    };
}