nix-files/hosts/common/programs/pipewire.nix

104 lines
3.7 KiB
Nix

# administer with pw-cli, pw-mon, pw-top commands
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.pipewire;
in
{
sane.programs.pipewire = {
suggestedPrograms = [ "wireplumber" ];
# sandbox.method = "landlock"; #< also works
sandbox.method = "bwrap";
sandbox.wrapperType = "inplace"; #< its config files refer to its binaries by full path
sandbox.extraConfig = [
"--sane-sandbox-keep-namespace" "pid"
];
sandbox.usePortal = false;
# needs to *create* the various device files, so needs write access to the /run/user/$uid directory itself
sandbox.extraRuntimePaths = [ "/" ];
sandbox.extraPaths = [
"/dev/snd"
# desko/lappy don't need these, but moby complains if not present
"/dev/video0"
"/dev/video1"
"/dev/video2"
];
sandbox.extraHomePaths = [
# pulseaudio cookie
".config/pulse"
];
services.pipewire = {
description = "pipewire: multimedia service";
after = [ "graphical-session.target" ];
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/pipewire";
ExecStartPost = pkgs.writeShellScript "pipewire-wait-started" ''
waitFor() {
while [ ! -e "$1" ]; do
sleep 1
done
}
waitFor "$XDG_RUNTIME_DIR/pipewire-0"
waitFor "$XDG_RUNTIME_DIR/pipewire-0-manager"
'';
ExecStopPost = ''rm -f "$XDG_RUNTIME_DIR/{pipewire-0,pipewire-0.lock,pipewire-0-manager,pipewire-0-manager.lock}"'';
Type = "simple";
Restart = "always";
RestartSec = "5s";
};
# environment.PIPEWIRE_LOG_SYSTEMD = "false";
# environment.PIPEWIRE_DEBUG = "*:3,mod.raop*:5,pw.rtsp-client*:5";
};
services.pipewire-pulse = {
description = "pipewire-pulse: Pipewire compatibility layer for PulseAudio clients";
after = [ "pipewire.service" ];
wantedBy = [ "pipewire.service" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/pipewire-pulse";
ExecStartPost = pkgs.writeShellScript "pipewire-pulse-wait-started" ''
waitFor() {
while [ ! -e "$1" ]; do
sleep 1
done
}
waitFor "$XDG_RUNTIME_DIR/pulse/native"
waitFor "$XDG_RUNTIME_DIR/pulse/pid"
'';
ExecStopPost = ''rm -f "$XDG_RUNTIME_DIR/pulse/{native,pid}"'';
Type = "simple";
Restart = "always";
RestartSec = "5s";
};
};
};
# taken from nixos/modules/services/desktops/pipewire/pipewire.nix
# removed 32-bit compatibility stuff
environment.etc = lib.mkIf cfg.enabled {
"alsa/conf.d/49-pipewire-modules.conf".text = ''
pcm_type.pipewire {
libs.native = ${cfg.package}/lib/alsa-lib/libasound_module_pcm_pipewire.so ;
}
ctl_type.pipewire {
libs.native = ${cfg.package}/lib/alsa-lib/libasound_module_ctl_pipewire.so ;
}
'';
"alsa/conf.d/50-pipewire.conf".source = "${cfg.package}/share/alsa/alsa.conf.d/50-pipewire.conf";
"alsa/conf.d/99-pipewire-default.conf".source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
};
services.udev.packages = lib.mkIf cfg.enabled [
cfg.package
];
# rtkit/RealtimeKit: allow applications which want realtime audio (e.g. Dino? Pulseaudio server?) to request it.
# this might require more configuration (e.g. polkit-related) to work exactly as desired.
# - readme outlines requirements: <https://github.com/heftig/rtkit>
# XXX(2023/10/12): rtkit does not play well on moby. any application sending audio out dies after 10s.
# security.rtkit.enable = lib.mkIf cfg.enabled true;
}