Open NilsIrl opened 5 years ago
Can you try reverting 361b5f7f6533c2b597057805b16bdf229d675d15, and see what changes? That's the only pulseaudio related change that happened on master.
Are you using unstable? (nixos-info output would be helpful)
@worldofpeace
Will try
Please note that spotifyd is supposed to use alsa by default. And when I explicitly tell it to use alsa I get the same error. So I don't know to what extent this is pulseaudio related.
I am not using unstable
"x86_64-linux"
Linux 4.19.79, NixOS, 19.09.840.8bf142e001b (Loris)
yes
yes
nix-env (Nix) 2.3
"nixos-unstable-20.03pre194293.2436c27541b"
"nixos-19.09.840.8bf142e001b"
/nix/var/nix/profiles/per-user/root/channels/nixos
@NilsIrl Ok, that commit doesn't touch 19.09 so it's likely unrelated. From the errors, maybe there's permission problems on the spotifyd user's home.
From the errors, maybe there's permission problems on the spotifyd user's home.
spotifyd
doesn't have a home directory.
Have you enabled the pulseaudio service?
Looking at the definition in all-packages.nix
withALSA = stdenv.isLinux;
withPulseAudio = config.pulseaudio or stdenv.isLinux;
You probably have it built with it.
Also not sure if the pulseaudio backend needs spotifyd user to have a home directory.
Have you enabled the pulseaudio service?
I have hardware.pulseaudio.enable = true;
and Firefox has audio so I suppose Pulseaudio is working.
Rough idea, paplay
as the spotifyd
user?
Rough idea,
paplay
as thespotifyd
user?
I am not sure what you mean but spotifyd
runs under the spotifyd
user when using services.spotifyd
.
$ ps aux | grep spotifyd
nils 23814 0.0 0.0 129024 2288 pts/1 S+ 23:39 0:00 grep spotifyd
spotifyd 24789 0.0 0.0 366632 5676 ? Ssl 20:27 0:02 /nix/store/f9810s7y3f4nfc4lkzl077fj0qh20qgz-spotifyd-0.2.11/bin/spotifyd --no-daemon --cache_path /var/cache/spotifyd --config /nix/store/8k2b9gczrfijs964bbnlk6wdm79gvb7i-spotifyd.conf
@NilsIrl Sorry was vague. It seems it's trying to play audio with pulseaudio.
The rough idea was getting a minimal case not related to spotifyd, by using paplay
to play something as the spotifyd
user. (some output from there maybe, to find out what home directory pulseaudio talking about?)
by using
paplay
to play something as thespotifyd
user
$ sudo -u spotifyd paplay imagine.wav
Home directory not accessible: Permission denied
Connection failure: Connection refused
pa_context_connect() failed: Connection refused
this seems to be the problem
So I guess it might be a good idea to try adding
StateDirectory = "spotifyd";
RuntimeDirectory = "spotifyd";
to the systemd service config.
If I was accepting a PR I'd want to add
ProtectHome=true
PrivateTmp=true
as well.
These didn't fix anything.
spotifyd
has no need of StateDirectory
and RuntimeDirectory
.
What did change stuff:
DynamicUser
hardware.pulseaudio.systemWide
to true
However none fix the problem
For example, without DynamicUser
and with hardware.pulseaudio.systemWide
, I get:
Oct 19 02:22:49 nixos spotifyd[14965]: ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Access denied
Oct 19 02:22:49 nixos spotifyd[14965]: 02:22:49 [ERROR] Alsa error PCM open ALSA function 'snd_pcm_open' failed with error 'ECONNREFUSED: Connection refused'
Oct 19 02:22:49 nixos spotifyd[14965]: 02:22:49 [ERROR] Could not start audio: Alsa error: PCM open failed
This could be linked to the following line that appears when running sudo nixos-rebuild switch
:
[/etc/tmpfiles.d/var.conf:19] Duplicate line for path "/var/cache", ignoring.
content of these files:
$ grep '/var/cache' /etc/tmpfiles.d/*
/etc/tmpfiles.d/nixos.conf:d /var/cache 0755 root root -
/etc/tmpfiles.d/systemd.conf:d /var/cache/private 0700 root root -
/etc/tmpfiles.d/var.conf:d /var/cache 0755 - - -
Weird, I don't have a /etc/tmpfiles.d/nixos.conf:d /var/cache 0755 root root -
entry on my system on nixos-unstable.
@worldofpeace have you managed to get it working (for you)?
services.spotifyd.config = "just password and username set"
Could you try without this? One should be able to connect to the service anyway if one is on the same network—at least that is how it works for me. I have never used this option so perhaps this option does not work as intended.
I am quite busy right now but could look more at this in a couple of days or so. Feel free to ping me in a week or so if the problem is not resolved and it seems like I have forgotten about it.
services.spotifyd.config = "just password and username set"
Could you try without this? One should be able to connect to the service anyway if one is on the same network
On the same network as what? The official Spotify client?
On the same network as what? The official Spotify client?
Sorry, it might be that I do not understand your use case. I have spotifyd running on a Raspberry Pi on my home network. I then use any official Spotify client to control the spotifyd instance (via Spotify Connect). This works without any username or password set as long as the client I connect with is connected to my home network. I guess this is not how you use spotifyd?
I am running spotifyd on my local computer, the one I am using right now to type this.
And I hope to control spotifyd from the web interface. Also with this current setup that doesn't work I can control spotifyd but nothing plays.
Sorry, it might be that I do not understand your use case. I have spotifyd running on a Raspberry Pi on my home network. I then use any official Spotify client to control the spotifyd instance (via Spotify Connect). This works without any username or password set as long as the client I connect with is connected to my home network.
How do you connect to the raspberry pi? Do you have to input the IP into the Spotify client?
How do you connect to the raspberry pi? Do you have to input the IP into the Spotify client?
No, I just use an official Spotify client and connect via Spotify Connect:
This could be linked to the following line that appears when running
sudo nixos-rebuild switch
:[/etc/tmpfiles.d/var.conf:19] Duplicate line for path "/var/cache", ignoring.
content of these files:
$ grep '/var/cache' /etc/tmpfiles.d/* /etc/tmpfiles.d/nixos.conf:d /var/cache 0755 root root - /etc/tmpfiles.d/systemd.conf:d /var/cache/private 0700 root root - /etc/tmpfiles.d/var.conf:d /var/cache 0755 - - -
This seems to be caused partly by locate
. Though disabling locate doesn't resolve the spotifyd
problem.
I haven't tried any workarounds yet, but I also have this issue when trying to get spotifyd working. This is still a regular single user laptop situation, but I'm still reluctant to change how pulseaudio is running just to get spotifyd working, but I'd like to use spotifyd
+spotify-tui
over using Spotify in browser or the electron client.
This got the daemon up and running for me: https://github.com/colemickens/nixpkgs/commit/ece91964dc1
Also, it was defaulting to alsa for me, I specified backend = pulseaudio
in my config file.
Yeah, I think running spotifyd as user service is the correct solution, as that is what upstream suggests. We should install the upstream service file into the package and just do the following in the module:
systemd.packages = [ pkgs.spotifyd ];
systemd.user.services.spotifyd.ExecStart = [ "" "${pkgs.spotifyd}/bin/spotifyd --no-daemon --cache-path /var/cache/spotifyd --config-path ${spotifydConf}" ];
I would prefer having spotifyd running under a separate user. (I only interact with spotifyd via Spotify Connect on official clients.) What is the use case requiring spotifyd running as a user service?
I would guess that since MPRIS usually runs on session bus, we would need to run it as user service to be able to use that.
I see, thanks. Would it make sense to have an option which makes spotifyd run under a separate user?
I see, thanks. Would it make sense to have an option which makes spotifyd run under a separate user?
I'm pretty sure that currently it runs under the spotifyd
user
Yes, I meant if the default behaviour was changed to run it as a user service.
Having the same problem with mpd :(
Hi,
I have a working configurations !
{ config, pkgs, ... }:
{
hardware.pulseaudio = {
enable = true;
package = pkgs.pulseaudioFull;
# there is no real user on the Raspberry Pi
# running daemon system wide should be safe this allow some services (such as: SpotifyD)
systemWide = true;
};
services.spotifyd = {
# don't use SpotifyD service from nixpkgs
# * PulseAudio seems to not work with DynamicUser
# * cache's directory is forced
enable = false;
};
# put configuration file on the default location for SpotifyD as per the documentation https://github.com/Spotifyd/spotifyd/blob/cfef0ad92f/README.md#L172
environment.etc."xdg/spotifyd/spotifyd.conf".text = ''
[global]
username = pinage404
password = ${builtins.readFile ./spotifyd.pass}
backend = pulseaudio
cache_path = ${config.users.users.spotifyd.home}/.cache/spotifyd/
'';
users = {
users.spotifyd = {
isSystemUser = true;
home = "/home/spotifyd";
createHome = true;
description = "spotifyd";
group = "spotifyd";
shell = pkgs.bash;
extraGroups = [ "audio" ];
};
groups.spotifyd = {};
};
systemd.services.spotifyd = {
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" "sound.target" ];
description = "spotifyd, a Spotify playing daemon";
serviceConfig = {
ExecStart = "${pkgs.spotifyd}/bin/spotifyd --no-daemon";
Restart = "always";
RestartSec = 12;
DynamicUser = false;
User = "spotifyd";
SupplementaryGroups = [ "audio" ];
};
};
}
Full and real configuration can be found here :
{
sound.enable = true;
services.spotifyd = {
enable = true;
config = ''
[global]
username = pinage404
password = ${builtins.readFile ./spotifyd.pass}
backend = alsa
#cache_path = NixOS' service force it to /var/cache/spotifyd/
'';
};
}
Full and real configuration can be found here :
Is this still up to date?
In my case, the only config necessary was to enable anonymous auth on module-native-protocol-unix
:
hardware.pulseaudio.enable = true;
hardware.pulseaudio.systemWide = true;
# required for spotifyd to be able to connect
hardware.pulseaudio.extraConfig = ''
unload-module module-native-protocol-unix
load-module module-native-protocol-unix auth-anonymous=1
'';
services.spotifyd = {
enable = true;
config = ''
[global]
zeroconf_port = 5354
backend = pulseaudio
bitrate = 320
'';
};
Here is my approach. I wanted to run it as a user unit
{ pkgs, ... }:
let
spotifyd = pkgs.spotifyd.override { withMpris = true; withPulseAudio = true; };
spotifydConf = pkgs.writeText "spotifyd-config" ''
[global]
username = "??????"
password = "??????"
backend = "pulseaudio"
bitrate = 320
use_mpris = true
'';
in
{
systemd.user.services.spotifyd = {
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" "sound.target" ];
description = "spotifyd, a Spotify playing daemon";
serviceConfig = {
ExecStart = "${spotifyd}/bin/spotifyd --no-daemon --cache-path=\${HOME}/.cache/spotifyd --config-path=${spotifydConf}";
Restart = "always";
RestartSec = 12;
};
};
environment.systemPackages = with pkgs; [
spotify-tui
];
}
and
{ pkgs, ... }:
{
sound.enable = true;
hardware.pulseaudio = {
enable = true;
package = pkgs.pulseaudioFull;
};
}
I made the change in my config that @flokli suggested, and it worked for a little bit, but I'm still getting frequent service crashes:
spotifyd[232705]: Failed to create secure directory (//.config/pulse): Read-only file system
spotifyd[232705]: Audio Sink Error Connection Refused: <PulseAudioSink> Connection refused
systemd[1]: spotifyd.service: Main process exited, code=exited, status=1/FAILURE
Once the service restarts, any attempts to connect to the device result in another crash with the same error.
Even when it was working, the logs frequently included:
spotifyd[229817]: Failed to create secure directory (//.config/pulse): Read-only file system
spotifyd[229817]: Failed to load cookie file from cookie: Read-only file system
I'm not sure how to go about troubleshooting why sometimes the PA server supposedly refuses the connection (there are no related logs in the system journal) or why spotifyd
continuously complains about being unable to create a pulse config directory or read a pulse cookie (it apparently doesn't know that anonymous auth is enabled).
I can only assume that there is still some lingering issue related to the service being run with DynamicUser=yes
. But maybe the issue is specific to my setup? I can try to make a minimal, reproducible example if that would be helpful...
I would love to find a solution that avoids getting stuck in a crash-loop state that doesn't involve switching to a user service or disabling DynamicUser
.
If anyone has any advice/suggestions to share, I would be quite grateful!
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
Describe the bug Spotifyd doesn't work and outputs the following errors.
To Reproduce Steps to reproduce the behavior:
services.spotifyd.enable = true
services.spotifyd.config = "just password and username set"
Expected behavior
Music plays and no errors.
Additional context
If
spotifyd
is called from bash manually, there is no problem.@anderslundstedt @marsam