diff --git a/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix b/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix index 539a4cf4469..17a2d49bb1f 100644 --- a/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix +++ b/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix @@ -4,6 +4,7 @@ with lib; let + json = pkgs.formats.json {}; cfg = config.services.pipewire.media-session; enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.isx86_64 @@ -17,24 +18,13 @@ let media-session = (builtins.fromJSON (builtins.readFile ./media-session.conf.json)); v4l2-monitor = (builtins.fromJSON (builtins.readFile ./v4l2-monitor.conf.json)); }; - # Helpers for generating the pipewire JSON config file - mkSPAValueString = v: - if builtins.isList v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]" - else if lib.types.attrs.check v then - "{${lib.concatStringsSep " " (mkSPAKeyValue v)}}" - else if builtins.isString v then "\"${lib.generators.mkValueStringDefault { } v}\"" - else lib.generators.mkValueStringDefault { } v; - mkSPAKeyValue = attrs: map (def: def.content) ( - lib.sortProperties - ( - lib.mapAttrsToList - (k: v: lib.mkOrder (v._priority or 1000) "${lib.escape [ "=" ":" ] k} = ${mkSPAValueString (v._content or v)}") - attrs - ) - ); - - toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue attrs); + configs = { + alsa-monitor = recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor; + bluez-monitor = recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor; + media-session = recursiveUpdate defaults.media-session cfg.config.media-session; + v4l2-monitor = recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor; + }; in { meta = { @@ -62,7 +52,7 @@ in { config = { media-session = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the media session core. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/media-session.conf @@ -71,7 +61,7 @@ in { }; alsa-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the alsa monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/alsa-monitor.conf @@ -80,7 +70,7 @@ in { }; bluez-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the bluez5 monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/bluez-monitor.conf @@ -89,7 +79,7 @@ in { }; v4l2-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the V4L2 monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/v4l2-monitor.conf @@ -106,15 +96,34 @@ in { systemd.packages = [ cfg.package ]; systemd.user.services.pipewire-media-session.wantedBy = [ "pipewire.service" ]; - environment.etc."pipewire/media-session.d/media-session.conf" = { text = toSPAJSON (recursiveUpdate defaults.media-session cfg.config.media-session); }; - environment.etc."pipewire/media-session.d/v4l2-monitor.conf" = { text = toSPAJSON (recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor); }; + environment.etc."pipewire/media-session.d/media-session.conf" = { + source = json.generate "media-session.conf" configs.media-session; + }; + environment.etc."pipewire/media-session.d/v4l2-monitor.conf" = { + source = json.generate "v4l2-monitor.conf" configs.v4l2-monitor; + }; - environment.etc."pipewire/media-session.d/with-alsa" = mkIf config.services.pipewire.alsa.enable { text = ""; }; - environment.etc."pipewire/media-session.d/alsa-monitor.conf" = mkIf config.services.pipewire.alsa.enable { text = toSPAJSON (recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor); }; + environment.etc."pipewire/media-session.d/with-alsa" = + mkIf config.services.pipewire.alsa.enable { + text = ""; + }; + environment.etc."pipewire/media-session.d/alsa-monitor.conf" = + mkIf config.services.pipewire.alsa.enable { + source = json.generate "alsa-monitor.conf" configs.alsa-monitor; + }; - environment.etc."pipewire/media-session.d/with-pulseaudio" = mkIf config.services.pipewire.pulse.enable { text = ""; }; - environment.etc."pipewire/media-session.d/bluez-monitor.conf" = mkIf config.services.pipewire.pulse.enable { text = toSPAJSON (recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor); }; + environment.etc."pipewire/media-session.d/with-pulseaudio" = + mkIf config.services.pipewire.pulse.enable { + text = ""; + }; + environment.etc."pipewire/media-session.d/bluez-monitor.conf" = + mkIf config.services.pipewire.pulse.enable { + source = json.generate "bluez-monitor.conf" configs.bluez-monitor; + }; - environment.etc."pipewire/media-session.d/with-jack" = mkIf config.services.pipewire.jack.enable { text = ""; }; + environment.etc."pipewire/media-session.d/with-jack" = + mkIf config.services.pipewire.jack.enable { + text = ""; + }; }; } diff --git a/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixos/modules/services/desktops/pipewire/pipewire.nix index 7cf19706a63..dbd6c5d87e1 100644 --- a/nixos/modules/services/desktops/pipewire/pipewire.nix +++ b/nixos/modules/services/desktops/pipewire/pipewire.nix @@ -4,6 +4,7 @@ with lib; let + json = pkgs.formats.json {}; cfg = config.services.pipewire; enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.isx86_64 @@ -29,24 +30,13 @@ let pipewire-pulse = builtins.fromJSON (builtins.readFile ./pipewire-pulse.conf.json); }; - # Helpers for generating the pipewire JSON config file - mkSPAValueString = v: - if builtins.isList v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]" - else if lib.types.attrs.check v then - "{${lib.concatStringsSep " " (mkSPAKeyValue v)}}" - else if builtins.isString v then "\"${lib.generators.mkValueStringDefault { } v}\"" - else lib.generators.mkValueStringDefault { } v; - - mkSPAKeyValue = attrs: map (def: def.content) ( - lib.sortProperties - ( - lib.mapAttrsToList - (k: v: lib.mkOrder (v._priority or 1000) "${lib.escape [ "=" ] k} = ${mkSPAValueString (v._content or v)}") - attrs - ) - ); - - toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue attrs); + configs = { + client = recursiveUpdate defaults.client cfg.config.client; + client-rt = recursiveUpdate defaults.client-rt cfg.config.client-rt; + jack = recursiveUpdate defaults.jack cfg.config.jack; + pipewire = recursiveUpdate defaults.pipewire cfg.config.pipewire; + pipewire-pulse = recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse; + }; in { meta = { @@ -78,7 +68,7 @@ in { config = { client = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for pipewire clients. For details see @@ -87,7 +77,7 @@ in { }; client-rt = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for realtime pipewire clients. For details see @@ -96,7 +86,7 @@ in { }; jack = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire daemon's jack module. For details see @@ -105,7 +95,7 @@ in { }; pipewire = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire daemon. For details see @@ -114,7 +104,7 @@ in { }; pipewire-pulse = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire-pulse daemon. For details see @@ -187,11 +177,21 @@ in { source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf"; }; - environment.etc."pipewire/client.conf" = { text = toSPAJSON (recursiveUpdate defaults.client cfg.config.client); }; - environment.etc."pipewire/client-rt.conf" = { text = toSPAJSON (recursiveUpdate defaults.client-rt cfg.config.client-rt); }; - environment.etc."pipewire/jack.conf" = { text = toSPAJSON (recursiveUpdate defaults.jack cfg.config.jack); }; - environment.etc."pipewire/pipewire.conf" = { text = toSPAJSON (recursiveUpdate defaults.pipewire cfg.config.pipewire); }; - environment.etc."pipewire/pipewire-pulse.conf" = { text = toSPAJSON (recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse); }; + environment.etc."pipewire/client.conf" = { + source = json.generate "client.conf" configs.client; + }; + environment.etc."pipewire/client-rt.conf" = { + source = json.generate "client-rt.conf" configs.client-rt; + }; + environment.etc."pipewire/jack.conf" = { + source = json.generate "jack.conf" configs.jack; + }; + environment.etc."pipewire/pipewire.conf" = { + source = json.generate "pipewire.conf" configs.pipewire; + }; + environment.etc."pipewire/pipewire-pulse.conf" = { + source = json.generate "pipewire-pulse.conf" configs.pipewire-pulse; + }; environment.sessionVariables.LD_LIBRARY_PATH = lib.optional cfg.jack.enable "/run/current-system/sw/lib/pipewire"; diff --git a/pkgs/development/libraries/pipewire/default.nix b/pkgs/development/libraries/pipewire/default.nix index 955a4d9da6e..d685bde35ed 100644 --- a/pkgs/development/libraries/pipewire/default.nix +++ b/pkgs/development/libraries/pipewire/default.nix @@ -75,6 +75,11 @@ let ./0070-installed-tests-path.patch # Add flag to specify configuration directory (different from the installation directory). ./0080-pipewire-config-dir.patch + # Fix JSON parser. + (fetchpatch { + url = "https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/34800dc0191a4ee7a329eeb361a6f2ccf4a75176.diff"; + sha256 = "0dzxzr408qqzf0252nwg14709p1lb2k826i3kdzg6djq8w98d5aj"; + }) ]; nativeBuildInputs = [