Introduction
This is the documentation of spotifyd
An open source Spotify client running as a UNIX daemon.
These docs should be regarded as an extension of the README so please check there first before looking through the docs.
Installation
Provided binaries
We provide pre-built binaries through GitHub Actions for the more popular platforms: Linux, macOS and ARMv7. You can find them here. For extra integrity, the file's SHA-512 gets calculated and uploaded as well.
The provided binaries come in two flavours, slim
and full
. Each are compiled with different features. slim
only contains the platform's most used audio backend, full
has also all optional features enabled (see Feature Flags).
Provided packages
There are packages for the following systems:
Building from source
You can also compile Spotifyd
yourself, allowing you to make use of feature flags. Spotifyd
is written in Rust. You can download the toolchain (compiler and package manager) over at rustup.rs. Follow their instructions to get started.
Note: Please make sure that you compile the package using the most recent
stable
version of Rust available throughrustup
. Some distro versions are quite outdated and might result in compilation errors.
Spotifyd
might require additional libraries during build and runtime, depending on your platform and the way to compile it (static or dynamic). The following table shows the libraries needed for each OS respectively.
Target Platform | Libraries |
---|---|
Fedora | alsa-lib-devel make gcc |
openSUSE | alsa-devel make gcc |
Debian | libasound2-dev libssl-dev libpulse-dev libdbus-1-dev |
Arch | base-devel alsa-lib libogg libpulse dbus |
macOS | dbus pkg-config portaudio |
Note: The package names for Linux are the ones used on Debian based distributions (like Ubuntu). You will need to adapt the packages for your distribution respectively.
To compile the binary, run
cargo build --release
To install the resulting binary, run
cargo install --path . --locked
Installing with Cargo
If you have cargo
installed, you can directly install spotifyd
by running:
cargo install spotifyd --locked
That will compile and install spotifyd
's latest version under $HOME/.cargo/bin
for you.
Building a Debian package
You can use the cargo-deb
create in order to build a Debian package from source.
Install it by:
cargo install cargo-deb
Then you can build and install the Debian package with:
cargo deb --install
Note, that when building a Debian package, the --release
is passed to the
build command already and you do not need to specify it yourself. See for the
flags that are set by default in Cargo.toml
.
Feature Flags
Spotifyd
is split into a base package plus additional features that can be toggled on or off during compilation. Those can be split into two groups: The audio backend features that are responsible for playing back the music and additional functionality features, which enhance your experience using spotifyd
.
To enable an additional audio backend, pass <audio_backend_name>_backend
as a feature flag. We currently support alsa
, pulseaudio
and portaudio
.
Spotifyd
provides the following additional functionality:
Feature Flag | Description |
---|---|
dbus_keyring | Provides password authentication over the system's keyring (supports all platforms) |
dbus_mpris | Provides multimedia key support (Linux and BSD only) |
Note: Compiling Spotifyd with all features and the pulseaudio backend on Ubuntu would result in the following command:
cargo build --release --no-default-features --features pulseaudio_backend,dbus_keyring,dbus_mpris
Raspberry Pi install guide
This guide will help you to install spotifyd
on a Raspberry Pi and have it always running.
Download
- Download the latest ARMv6 from https://github.com/Spotifyd/spotifyd/releases (use
wget
) - Unzip the file:
tar xzf spotifyd-linux-arm6*
You will now see a file calledspotifyd
. You can run it with./spotifyd --no-daemon
Systemd daemon file
Create a systemd service file and copy the default configuration into it. Change ExecStart to where you unzipped the spotifyd
binary.
sudo nano /etc/systemd/user/spotifyd.service
if you want to run as user instead of root or have some Failed to get D-Bus connection: Connection refused
, you define spotifyd.service
in your home directory:
mkdir -p ~/.config/systemd/user/
nano ~/.config/systemd/user/spotifyd.service
systemctl --user daemon-reload
Configuring spotifyd
Spotifyd comes pre-configured with defaults that should be working in most cases, but if you want to tweak it further to your needs, have a look at the configuration section of this book.
Start the service
systemctl --user start spotifyd.service
Now see if you can find it in the normal Spotify client (Devices in right bottom corner). Retry the above steps if you can't find it.
Starting spotifyd at boot
sudo loginctl enable-linger <username>
systemctl --user enable spotifyd.service
The first command is required to enable your user to run long-running services. Without it systemd
would kill the spotifyd
process as soon as you log out, and only run it when you log in.
Now spotifyd
is always running on the Pi, so you can use it as a listening device remotely!
Ubuntu install guide
Install the rust toolchain
To install the latest rust toolchain, follow the installation instructions on rustup.rs.
Note: If you installed rust before via apt, you need to remove it before installing rustup. We recommend to always use the latest version and don't guarantee compatibility with older ones.
Install the requirements
sudo apt install libasound2-dev libssl-dev pkg-config
Clone the repository
git clone https://github.com/Spotifyd/spotifyd.git
Building spotifyd
This takes a while...
cd spotifyd
cargo build --release
The resulting binary will be placed in target/release/spotifyd
Running spotifyd
You can run it using ./target/release/spotifyd
Ubuntu compilation guide
These are some notes on cross-compiling, that worked on WSL xenial Ubuntu.
Activate the cross compilation in dpkg
dpkg --add-architecture armhf
sed 's/deb http/deb \[arch=amd64,i386\] http/' -i /etc/apt/sources.list
echo >/etc/apt/sources.list <<EOF
deb [arch=armhf] http://ports.ubuntu.com/ $(lsb_release -cs) main universe restricted multiverse
deb [arch=armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-updates main universe restricted multiverse
deb [arch=armhf] http://ports.ubuntu.com/ $(lsb_release -cs)-security main universe restricted multiverse
EOF
apt update
Install dependency libraries
apt install libssl-dev:armhf libasound2-dev:armhf
Replace standard rust with rustup and activate the target architecture
apt remove rustc
curl https://sh.rustup.rs -sSf | sh
rustup target add arm-unknown-linux-gnueabihf
Build
PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig PKG_CONFIG_ALLOW_CROSS=1 cargo build --target=arm-unknown-linux-gnueabihf --release
Cross Compilation using Docker
We can also use docker
to cross compile on every platform and OS that runs docker
and qemu
:
-
Setup a docker custom builder
docker buildx create \ --name container-builder \ --driver docker-container \ --use --bootstrap
If you are not using Docker-Desktop you might have to install QEMU
-
Create a docker
compose-file.yml
Here we are building a
arm64
binary, so we setplatform: linux/arm64
services: build-container: image: rust:1.79-bookworm platform: linux/arm64 command: bash -c " apt-get update && apt-get install -y \ libasound2-dev \ libssl-dev \ pkg-config && curl -sSL https://api.github.com/repos/Spotifyd/spotifyd/tarball/v0.3.5 | tar xz -C /spotifyd --strip-components=1 && cargo build --release && cp /spotifyd/target/release/spotifyd /build/" working_dir: /spotifyd volumes: - ./:/build
-
Run
docker compose up
This will copy the build
spotifyd
binary in the current directory.
MacOS installation Guide
spotifyd is available via Homebrew and can be installed as follows:
brew install spotifyd
One can then enable it as a service at startup:
brew services start spotifyd
FreeBSD install guide
This guide will help you to install spotifyd
on FreeBSD and have it always running.
spotifyd
is available for the FreeBSD architectures :
- amd64
- i386
- arm64
Install
sudo pkg install spotifyd
Configuring spotifyd
If you installed spotifyd using the above method, you'll either need to supply --backend portaudio
as a command-line argument or add backend = "portaudio"
to /usr/local/etc/spotifyd.conf
.
Apart from that, spotifyd comes pre-configured with defaults that should be working in most cases, but if you want to tweak it further to your needs, have a look at the configuration section of this book.
Start the service
sudo service spotifyd onestart
Now see if you can find it in the normal Spotify client (Devices in right bottom corner). Retry the above steps if you can't find it.
Starting spotifyd at boot
sudo sysrc spotifyd_enable=YES
OpenBSD install guide
spotifyd
is available on all supported Rust architectures:
- aarch64
- amd64
- i386
- powerpc64
- riscv64
- sparc64
Install
# pkg_add spotifyd
Configuring spotifyd
The official package uses PortAudio and works out of the box, no configuration is required.
Running spotifyd
You may start spotifyd
as background daemon in your ~/.xsession
X11 startup script
or have clients like spotify-qt
start/stop it accordingly.
Configuration
Spotifyd
is able to run without configuration at all and will assume default values for most of the fields. However, running without configuration will only allow you to connect to it via Spotify Connect if you're on the same network as the daemon
Command Line Options
Spotifyd
can be configured using CLI arguments. For a detailed description as well as possible values for each flag, run
spotifyd --help
Configuration file
Spotifyd
is able to load configuration values from a TOML file too. The file has to be named spotifyd.conf
and reside in the user's configuration directory (~/.config/spotifyd
) or the system configuration directory (/etc
or /etc/xdg/spotifyd
). This also applies to macOS!
The configuration file consists of two sections, global
and spotifyd
, whereas spotifyd
takes priority over global
.
The configuration file has the following format:
[global]
# Your Spotify account name.
username = "username"
# Your Spotify account password.
password = "password"
# A command that gets executed and can be used to
# retrieve your password.
# The command should return the password on stdout.
#
# This is an alternative to the `password` field. Both
# can't be used simultaneously.
password_cmd = "command_that_writes_password_to_stdout"
# If set to true, `spotifyd` tries to look up your
# password in the system's password storage.
#
# Note, that the `password` field will take precedence, if set.
use_keyring = true
# If set to true, `spotifyd` tries to bind to dbus (default is the session bus)
# and expose MPRIS controls. When running headless, without the session bus,
# you should set this to false, to avoid errors. If you still want to use MPRIS,
# have a look at the `dbus_type` option.
use_mpris = true
# The bus to bind to with the MPRIS interface.
# Possible values: "session", "system"
# The system bus can be used if no graphical session is available
# (e.g. on headless systems) but you still want to be able to use MPRIS.
# NOTE: You might need to add appropriate policies to allow spotifyd to
# own the name.
dbus_type = "session"
# The audio backend used to play music. To get
# a list of possible backends, run `spotifyd --help`.
backend = "alsa" # use portaudio for BSD and macOS [homebrew]
# The alsa audio device to stream audio. To get a
# list of valid devices, run `aplay -L`,
device = "alsa_audio_device" # omit for macOS
# The PCM sample format to use. Possible values
# are F32, S32, S24, S24_3, S16.
# Change this value if you encounter errors like
# "Alsa error PCM open ALSA function 'snd_pcm_hw_params_set_format' failed with error 'EINVAL: Invalid argument'"
audio_format = "S16"
# The alsa control device. By default this is the same
# name as the `device` field.
control = "alsa_audio_device" # omit for macOS
# The alsa mixer used by `spotifyd`.
mixer = "PCM" # omit for macOS
# The volume controller. Each one behaves different to
# volume increases. For possible values, run
# `spotifyd --help`.
volume_controller = "alsa" # use softvol for BSD and macOS
# A command that gets executed in your shell after each song changes.
on_song_change_hook = "command_to_run_on_playback_events"
# The name that gets displayed under the connect tab on
# official clients.
device_name = "device_name_in_spotify_connect"
# The audio bitrate. 96, 160 or 320 kbit/s
bitrate = 160
# The directory used to cache audio data. This setting can save
# a lot of bandwidth when activated, as it will avoid re-downloading
# audio files when replaying them.
#
# Note: The file path does not get expanded. Environment variables and
# shell placeholders like $HOME or ~ don't work!
cache_path = "cache_directory"
# The maximal size of the cache directory in bytes
# The example value corresponds to ~ 1GB
max_cache_size = 1000000000
# If set to true, audio data does NOT get cached.
no_audio_cache = true
# Volume on startup between 0 and 100
# NOTE: This variable's type will change in v0.4, to a number (instead of string)
initial_volume = "90"
# If set to true, enables volume normalisation between songs.
volume_normalisation = true
# The normalisation pregain that is applied for each song.
normalisation_pregain = -10
# After the music playback has ended, start playing similar songs based on the previous tracks.
autoplay = true
# The port at which `spotifyd` is going to offer its service over the network (TCP).
# If not set, a random port > 1024 is used. For the service to be discoverable on the
# local network via mDNS, both the mDNS port (5353 UDP) and the random or fixed
# zeroconf port need to be allowed through any active firewall.
zeroconf_port = 1234
# The proxy `spotifyd` will use to connect to spotify.
proxy = "http://proxy.example.org:8080"
# The displayed device type in Spotify clients.
# Can be unknown, computer, tablet, smartphone, speaker, t_v,
# a_v_r (Audio/Video Receiver), s_t_b (Set-Top Box), and audio_dongle.
device_type = "speaker"
Alternatives to storing your password in the config file
-
use zeroconf authentication from Spotify Connect
Spotifyd is able to advertise itself on the network without credentials. To enable this, you must omit / comment any
username
/username_cmd
orpassword
/password_cmd
in the configuration. Spotifyd will receive an authentication blob from Spotify when you choose it from the devices list.Note: If you choose to go with this, it is also recommended to omit the
cache_path
andcache_directory
options. Otherwise the first user to connect to the service will have its authentication blob cached by the service and nobody else will be able to connect to the service without clearing the cache.This way, a Spotifyd instance can also be made available to multiple users.
For more information, have a look at the librespot documentation.
-
password_cmd
config entryThis feature allows you to provide a command that prints your password to
stdout
, which saves you from having to store your password in the config file directly. To use it, set thepassword_cmd
config entry to the command you would like to use and remove thepassword
config entry.For example (using the password-management utility pass).
# ~/.config/spotifyd/spotifyd.conf password_cmd = "pass spotify"
-
use_keyring
config entry /--use-keyring
CLI flagNote: If choosing the user's keyring to store login credentials, running spotifyd as a systemd system service is no longer possible. A system wide service cannot access a specific user's keyring. In this case, make sure to run spotifyd as a systemd user service. See systemd configuration.
This features leverages Linux's DBus Secret Service API or native macOS keychain in order to forgo the need to store your password directly in the config file. To use it, compile with the
dbus_keyring
feature and set theuse-keyring
config entry totrue
or pass the--use-keyring
CLI flag during start to the daemon. Remove thepassword
and/orpassword_cmd
config entries.Your keyring entry needs to have the following attributes set:
application: rust-keyring service: spotifyd username: <your-spotify-username>
To add such an entry into your keyring, you can use
secret-tool
, a CLI used to communicate with agents that support the Secret Service API:secret-tool store --label='name you choose' application rust-keyring service spotifyd username <your-username>
You can use the keychain GUI on macOS to add an item respectively, or with the built-in
security
tool:security add-generic-password -s spotifyd -D rust-keyring -a <your username> -w
Shell used to run commands indicated by password_cmd
or on_song_changed_hook
If either of these options is given, the shell spotifyd
will use to run its commands is the shell indicated by the SHELL
environment variable, if set. If the SHELL
environment variable is not set, spotifyd
will use the user's default shell, which, on Linux and BSD, is the shell listed in /etc/passwd
. On macOS it is the shell listed in the output of dscl . -read /Users/<username> UserShell
.
Running as a Service
You can run Spotifyd as a service that automatically starts in the background.
Running spotifyd as a systemd service
As as a user service
A systemd.service
unit file is provided to help run spotifyd as a service on systemd-based systems. The file contrib/spotifyd.service
should be copied to either:
/etc/systemd/user/
~/.config/systemd/user/
Packagers of systemd-based distributions are encouraged to include the file in the former location. End-user should prefer the latter. It should be noted that some targets are not available when running under the user directory, such as network-online.target
.
Control of the daemon is handed over to systemd. The following command will start the service whenever the user logs in to the system. Logging out will stop the service.
systemctl --user enable spotifyd.service --now
As a system wide service
When running spotifyd as a system wide service, it is not possible to access a user's keyring to obtain login credentials. Do not set use_keyring = true
and do not specify --use-keyring
, when running as a system wide service. To be able to access login credentials stored in the user's keyring, run spotifyd as a user service, as decribed above.
Additionally, use_mpris = true
or --use-mpris
should not be used, since their intended usage is within user sessions (and not system-wide daemons). If you have very specific requirements and still want to control a system-wide spotifyd
instance, there is some help available here.
A systemd.service
unit file is provided to help run spotifyd as a service on systemd-based systems. The file contrib/spotifyd.service
should be copied to:
/etc/systemd/system/
Control of the daemon is handed over to systemd. The following example commands will start the service and keep it running across reboots.
systemctl daemon-reload
systemctl enable spotifyd.service --now
Running spotifyd as a service on macOS
On macOS the system wide and per-user daemon/agent manager is known as launchd
. Interfacing with launchd
is performed through launchctl
.
In order to use spotifyd
as a service on macOS one must specify a .plist
that represents the service, and place it in /Library/LaunchDaemons
.
Here is a .plist which works with macOS Catalina 10.15.3:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>rustlang.spotifyd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/spotifyd</string>
<string>--config-path=/users/YourUserName/.config/spotifyd/spotifyd.conf</string>
<string>--no-daemon</string>
</array>
<key>UserName</key>
<string>YourUserName</string>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>30</integer>
</dict>
</plist>
Once present in the /Library/LaunchDaemons
directory, the .plist must be loaded and started with the following commands.
sudo launchctl load -w /Library/LaunchDaemons/rustlang.spotifyd.plist
sudo launchctl start /Library/LaunchDaemons/rustlang.spotifyd.plist
One may also unload/stop the service in a similar fashion replacing load/start with unload/stop.
Note:
-
You should update "YourUserName" with your actual username for macOS (or remove "UserName" to run as root.
-
The string,
<string>--no-daemon</string>
is needed as launchd won't receive a PID for the process and will lose its remit over spotifyd. So it's best to include it, there will be no difference in use, nor will you see any log output. -
macOS tries to start the daemon immediately on boot, and spotifyd fails if Wifi isn't connected. So one must have a keep alive (which retries if it fails to launch on boot), that retries after 30 seconds, which is enough for wifi etc to come up.
D-Bus control
Spotifyd
can be configured to bind to D-Bus, exposing controls including standard MPRIS interfaces.
To configure D-Bus, see use_mpris
and dbus_type
in the configuration file. Spotifyd
must also be built with the dbus_mpris
feature, which is available in the full
flavour of the provided binaries.
The D-Bus service name will be in the format org.mpris.MediaPlayer2.spotifyd.instance<number>
, where <number>
is the process id.
Interfaces
MPRIS
The org.mpris.MediaPlayer2
and org.mpris.MediaPlayer2.Player
interfaces from the MPRIS specification are implemented.
Note the Volume
property of the org.mpris.MediaPlayer2.Player
interface is read-only, despite supporting writes in the specification.
Spotifyd Controls
The rs.spotifyd.Controls
interface includes additional non-standard controls.
- Method
TransferPlayback
: transfers Spotify playback tospotifyd
- Method
VolumeUp
: increases player volume - Method
VolumeDown
: decreases player volume
Usage
Spotifyd
can be controlled by applications which support MPRIS such as the playerctl command-line utility.
The dbus-send
command can also be used to control spotifyd
. For example:
- Find the service registered by
spotifyd
:dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep spotifyd
- Transfer playback to
spotifyd
:dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotifyd.instancexxx /rs/spotifyd/Controls rs.spotifyd.Controls.TransferPlayback
- Get metadata for the current track:
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotifyd.instancexxx /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Metadata
Troubleshooting
"Failed to initialize DBus connection" on a headless system
Where no graphical session is available, the system bus can be used by setting the dbus_type
configuration option to system
.
"Failed to register dbus player name" using the system bus
Spotifyd
may not have permission to register the D-Bus service due to D-Bus security policies. It should be granted permission to own any service with the prefix "org.mpris.MediaPlayer2.spotifyd".
For example, this statement can be added to the default policy in /usr/share/dbus-1/system.conf
.
<allow own_prefix="org.mpris.MediaPlayer2.spotifyd"/>
It may also be necessary to add a statement to allow clients to send messages.
<allow send_destination_prefix="org.mpris.MediaPlayer2.spotifyd"/>
Make sure to reload the D-Bus configuration after making changes. For example sudo systemctl reload dbus
.