No Sound mopidy as a service + wireplumber + NIXOS 22.05

Hey everyone,
I’m pulling my hair out here over something I’ve been fighting to try and get mopidy to work in NixOS 22.05 with wireplumber.

I am starting mopidy as a service with the following config:

Mopidy

services.mopidy = {
	enable = true;
	extensionPackages = with pkgs; [ mopidy-local mopidy-mpd mopidy-podcast mopidy-tunein mopidy-youtube mopidy-ytmusic ];
	configuration = ''

		[audio]
			mixer = software
			mixer_volume =
			output = autoaudiosink
			buffer_time = 

			[core]
			cache_dir = $XDG_CACHE_DIR/mopidy
			config_dir = $XDG_CONFIG_DIR/mopidy
			data_dir = $XDG_DATA_DIR/mopidy
			max_tracklist_length = 10000
			restore_state = true

			#[jellyfin]      
			#hostname = 192.168.1.105:8096
			#username = ${mySecrets.mopidy.jellyfin.username}
			#password = ${mySecrets.mopidy.jellyfin.passwd}

			[file]
			enabled = true
			media_dirs = /tmp/Music
			excluded_file_extensions =
			.jpg
			.html
			.mp4
			.mpg
			.nfo

			show_dotfiles = false
			follow_symlinks = false
			metadata_timeout = 1000


			[local]
			enabled = true
			media_dir = /tmp/Music
			data_dir =  $HOME/Music/data
			scan_timeout = 1000
			excluded_file_extensions = 
			.html
			.mp4
			.mpg
			.nfo

			[logging]
			color = true
			console_format = %(levelname)-8s %(message)s
			debug_format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n
			debug_file = mopidy.log
			verbosity = 4

			[mpd]
			enabled = true
			hostname = 127.0.0.1
			port = 6600
			password = 
			max_connections = 20
			connection_timeout = 60
			zeroconf = Mopidy MPD Server on $hostname
			command_blacklist =
			default_playlist_scheme = m3u


			# [spotify]
			# enabled = true
			# username = deep_6
			# password = ${mySecrets.mopidy.spotify.passwd}
			# client_id = ${mySecrets.mopidy.spotify.client_id}
			# client_secret = ${mySecrets.mopidy.spotify.client_secret}

			[tunein]
			enabled = false
			timeout = 5000

			[youtube]
			enabled = false
			youtube_api_key = ${mySecrets.mopidy.youtube.api_key}
			api_enabled = true
			musicapi_enabled = true
			search_results = 50 
			playlist_max_videos = 1

			[ytmusic]
			enabled = true
			auth_json = /tmp/auth.json
			'';
};

I am enabling audio as follows:

Enable sound.

#{{{

sound.enable = true;

services.pipewire  = {
	enable = true;
	alsa.enable = true;
	alsa.support32Bit = true;
	pulse.enable = true;
	wireplumber.enable = true;
	jack.enable = false;
};
environment.etc = {
	"wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = ''

bluez_monitor.properties = {
[“bluez5.enable-sbc-xq”] = true,
[“bluez5.enable-msbc”] = true,
[“bluez5.enable-hw-volume”] = true,
[“bluez5.headset-roles”] = “[ hsp_hs hsp_ag hfp_hf hfp_ag ]”
}

'';
	"wireplumber/access.configuration.lua/50-default-access-config.lua".text = ''
          	
	  matches = {
	  { 
	   { "pipewire.access", "=", "ncmpcpp" },
	   },
	},
	   default_permission = "rx",
			   
'';

};

I’m able to run the following and hear the beep

gst-launch-1.0 audiotestsrc ! audioresample ! autoaudiosink

I should also note sound works everywhere else, and when I’ve done some troubleshooting by using nix-shell -p mopidy and mopidy-* plugins and used the exact same configuration it works.

Yet I have no sound whatsoever when I try to run mopidy here’s some debug info:

I have also toggled to make sure it’s not a mute issue

My debug log is located here:

I suspect some sort of permissions issue, but I can’t solve it though I tried with the “wireplumber/access.configuration.lua/50-default-access-config.lua”.text = ‘’
portion

I know nothing about nixos but is this service a user service or a system service? In Debian, we configure the latter to run as user mopidy which means you need some way to get audio from user mopidy to whatever user your sound server (pulseaudio, pipewire etc) is running at, which is normally your user. We have a way documented for pusle in our docs.

If running as a user service, I think there’s a github issue about getting this working but nobody seems interested in actually making a docs PR.

I’m running it as a system service. Definitely check out NixOS it’s quite cool!

Right, in which case you definitely need to solve the problem of running Mopidy as one user and running the audio server as another.

Is this an established pattern, somewhere, that I have to adapt to NixOS, or in it totally new territory?

https://docs.mopidy.com/en/latest/running/service/#system-service-and-pulseaudio

Is the fact this is wireplumber as opposed to pipewire/pulse, relevant or is this still relevant?

Isn’t wireplummer something to do with pipewire? Ultimately I’m not familiar with your setup but hopefully that page explains what the potential problem might be and you can see if it applies to your setup.

To be honest I’m a bit hazy on it all myself, I think wireplumber is the media-session for pipewire…but not certain. I am trying to solve for the permission issue with the lua permissioning: not sure if it’s correct though:

“wireplumber/access.configuration.lua/50-default-access-config.lua”.text = ‘’

	  matches = {
	  {
	   { "pipewire.access", "=", "ncmpcpp" },
	   },
	},
	   default_permission = "rx",
			
'';

};

Perhaps you’ll find some useful info in this issue. Or people that might be able to help.

I managed to get it working, but in the end just took the easy route and started mopidy via home-manager as a user service. With the following code:
# MOPIDY {{{
services.mopidy.enable = true;
services.mopidy.extensionPackages = with pkgs; [ mopidy-jellyfin mopidy-local mopidy-mpd mopidy-podcast mopidy-tunein mopidy-ytmusic ];
services.mopidy.settings = {
file = {
media-dirs = [ “$XDG_MUSIC_DIR|Music” ];
follow_symlinks = true;
excluded_file_extensions = [
“.html”
“.zip”
“.jpg”
“.jpeg”
“.png”
];
};
audio = {
mixer = ‘’ software ‘’;
output =’’ autoaudiosink ‘’ ;
};
core = {
cache_dir = “$XDG_CACHE_DIR/mopidy”;
restore_state = true;
};
jellyfin = {
enabled = true;
hostname = “10.0.0.1:8096”;
username = “${mySecrets.mopidy.jellyfin.username}”;
password = “${mySecrets.mopidy.jellyfin.passwd}”;

  };
  mpd = {
    enabled = true;
    port = 6600;
    zeroconf = "Mopidy server on $hostname";
    default_playlist_scheme = "m3u";

  };
  podcast = {
          enabled = true;
  };
  local = {
    enabled = true;
    media_dir = "~/Music";
    excluded_file_extensions = ''

      .directory
      .html
      .jpeg
      .jpg
      .log
      .nfo
      .png
      .txt

‘’;
};
softwaremixer = {
enabled = true;
};
tunein = {
enabled = true;
};
ytmusic = {
enabled = true;
enable_history = true;
enable_scrobbling = true;
stream_preference = ‘’ “141”, “251” ‘’;
verify_track_url = ‘’ yes ‘’;
};
};
#}}}