1# Spotifyd <!-- omit in toc --> 2[![Cargo Downloads](https://img.shields.io/crates/d/spotifyd)](https://crates.io/crates/spotifyd) 3[![Dependabot Status][dependabot-badge]](https://dependabot.com) 4[![Github Actions - CD][cd-badge]][github-actions] 5[![Github Actions - CI][ci-badge]][github-actions] 6 7> An open source Spotify client running as a UNIX daemon. 8 9Spotifyd streams music just like the official client, but is more lightweight and supports more platforms. Spotifyd also supports the Spotify Connect protocol, which makes it show up as a device that can be controlled from the official clients. 10 11> __Note:__ Spotifyd requires a Spotify Premium account. 12 13- [Installation](#installation) 14 - [Provided binaries](#provided-binaries) 15 - [Compiling from source](#compiling-from-source) 16 - [Feature Flags](#feature-flags) 17 - [Media controls](#media-controls) 18 - [Audio Backends](#audio-backends) 19 - [PulseAudio](#pulseaudio) 20 - [PortAudio](#portaudio) 21 - [Rodio](#rodio) 22- [Configuration](#configuration) 23 - [CLI options](#cli-options) 24 - [Configuration file](#configuration-file) 25- [Running as a system service](#running-as-a-system-service) 26- [Common issues](#common-issues) 27- [Contributing](#contributing) 28- [Credits](#credits) 29 30## Installation 31 32### Provided binaries 33 34We provide pre-built binaries through GitHub Actions for the more popular platforms: Linux, macOS and ARMv7. You can find them [here](https://github.com/Spotifyd/spotifyd/releases). For extra integrity, the file's SHA-512 gets calculated and uploaded as well. 35 36The 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](#feature-flags)). 37 38### Compiling from source 39 40You 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](https://rustup.rs). Follow their instructions to get started. 41 42> __Note:__ Please make sure that you compile the package using the most recent `stable` verison of Rust available throug `rustup`. Some distro versions are quite outdated and might result in compilation errors. 43 44`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. 45 46| Target Platform | Libraries | 47|-----------------|------------------------------------------------------| 48| Fedora | alsa-lib-devel, make, gcc | 49| openSUSE | alsa-devel, make, gcc | 50| Debian | libasound2-dev libssl-dev libpulse-dev libdbus-1-dev | 51| macOS | dbus, pkg-config, portaudio | 52 53> __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. 54 55To compile the binary, run 56 57```bash 58cargo build --release 59``` 60 61To install the resulting binary, run 62 63```bash 64cargo install --path . --locked 65``` 66 67### Installing with Cargo 68 69If you have `cargo` installed, you can directly install `spotifyd` by running: 70 71```bash 72cargo install spotifyd --locked 73``` 74 75That will compile and install `spotifyd`'s latest version under `$HOME/.cargo/bin` for you. 76 77#### Building a Debian package 78 79You can use the `cargo-deb` create in order to build a Debian package from source. 80Install it by: 81``` 82$ cargo install cargo-deb 83``` 84 85Then you can build and install the Debian package with: 86``` 87$ cargo deb --install 88``` 89 90Note, that when building a Debian package, the `--release` is passed to the 91build command already and you do not need to specify it yourself. See for the 92flags that are set by default in `Cargo.toml`. 93 94#### Feature Flags 95 96`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`. 97 98To enable an additional audio backend, pass `<audio_backend_name>_backend` as a feature flag. We currently support `alsa`, `pulseaudio` and `portaudio`. 99 100`Spotifyd` provides the following additional functionality: 101 102| Feature Flag | Description | 103|--------------|-------------------------------------------------------------------------------------| 104| dbus_keyring | Provides password authentication over the system's keyring (supports all platforms) | 105| dbus_mpris | Provides multimedia key support (Linux only) | 106 107> __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` 108 109##### Media controls 110 111Spotifyd implements the [MPRIS D-Bus Interface Specification][mpris-specification], meaning that it can be controlled by generic media playback controllers such as [playerctl][playerctl-homepage] as well as some tools specifically designed for use with the official Spotify client such as [sp][sp-homepage]. 112 113> __Note:__ Make sure to rename the service name within the `sp` script to `spotifyd`! 114 115Although the code greatly improved, this feature is still considered experimental. Make sure to open an issue if you encounter any issues while using other players to control `spotifyd`. 116 117##### Audio Backends 118 119By default, the audio backend is ALSA, as ALSA is available by default on a lot of machines and usually doesn't require extra dependencies. There is also support for `pulseaudio` and `portaudio`. 120 121> __Note:__ To disable this audio backend, pass `--no-default-features` down during compilation. 122 123###### PulseAudio 124 125To use PulseAudio, compile with the `--features` flag to enable 126it: 127 128```bash 129cargo build --release --features "pulseaudio_backend" 130``` 131 132You will need the development package for PulseAudio, as well 133as `build-essential` or the equivalent package of your distribution. 134 135###### PortAudio 136 137To use PortAudio (works on macOS), compile with the `--features` flag to enable it: 138 139```bash 140cargo build --release --no-default-features --features="portaudio_backend" 141``` 142 143> __Note:__ It is important that you also pass down `--no-default-features` as macOS doesn't support the `alsa_backend` feature! 144 145###### Rodio 146 147To use Rodio (works on Windows, OSX, Linux), compile with the `--features` flag to enable it: 148 149```bash 150cargo build --release --no-default-features --features="rodio_backend" 151``` 152 153On Linux you will need the development package for alsa and make/gcc. (`libasound2-dev`,`build-essential` on debian, `alsa-lib-devel`,`make`,`gcc` on fedora) 154 155## Configuration 156 157`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. 158 159### CLI options 160 161`Spotifyd` can be configured using CLI arguments. For a detailed description as well as possible values for each flag, run 162 163```bash 164spotifyd --help 165``` 166 167### Configuration file 168 169`Spotifyd` is able to load configuration values from a [TOML](https://toml.io/en/v0.5.0) 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! 170 171The configuration file consists of two sections, `global` and `spotifyd`, whereas `spotifyd` takes priority over `global`. 172 173The configuration file has the following format: 174 175```toml 176[global] 177# Your Spotify account name. 178username = "username" 179 180# Your Spotify account password. 181password = "password" 182 183# A command that gets executed and can be used to 184# retrieve your password. 185# The command should return the password on stdout. 186# 187# This is an alternative to the `password` field. Both 188# can't be used simultaneously. 189password_cmd = "command_that_writes_password_to_stdout" 190 191# If set to true, `spotifyd` tries to look up your 192# password in the system's password storage. 193# 194# This is an alternative to the `password` field. Both 195# can't be used simultaneously. 196use_keyring = true 197 198# 199# If set to true, `spotifyd` tries to bind to the session dbus 200# and expose MPRIS controls. When running headless, without a dbus session, 201# then set this to false to avoid binding errors 202# 203use_mpris = true 204 205# The audio backend used to play the your music. To get 206# a list of possible backends, run `spotifyd --help`. 207backend = "alsa" 208 209# The alsa audio device to stream audio to. To get a 210# list of valid devices, run `aplay -L`, 211device = "alsa_audio_device" # omit for macOS 212 213# The alsa control device. By default this is the same 214# name as the `device` field. 215control = "alsa_audio_device" # omit for macOS 216 217# The alsa mixer used by `spotifyd`. 218mixer = "PCM" 219 220# The volume controller. Each one behaves different to 221# volume increases. For possible values, run 222# `spotifyd --help`. 223volume_controller = "alsa" # use softvol for macOS 224 225# A command that gets executed in your shell after each song changes. 226on_song_change_hook = "command_to_run_on_playback_events" 227 228# The name that gets displayed under the connect tab on 229# official clients. Spaces are not allowed! 230device_name = "device_name_in_spotify_connect" 231 232# The audio bitrate. 96, 160 or 320 kbit/s 233bitrate = 160 234 235# The directory used to cache audio data. This setting can save 236# a lot of bandwidth when activated, as it will avoid re-downloading 237# audio files when replaying them. 238# 239# Note: The file path does not get expanded. Environment variables and 240# shell placeholders like $HOME or ~ don't work! 241cache_path = "cache_directory" 242 243# If set to true, audio data does NOT get cached. 244no_audio_cache = true 245 246# Volume on startup between 0 and 100 247initial_volume = 90 248 249# If set to true, enables volume normalisation between songs. 250volume_normalisation = true 251 252# The normalisation pregain that is applied for each song. 253normalisation_pregain = -10 254 255# The port `spotifyd` uses to announce its service over the network. 256zeroconf_port = 1234 257 258# The proxy `spotifyd` will use to connect to spotify. 259proxy = "http://proxy.example.org:8080" 260 261# The displayed device type in Spotify clients. 262# Can be unknown, computer, tablet, smartphone, speaker, tv, 263# avr (Audio/Video Receiver), stb (Set-Top Box), and audiodongle. 264device_type = "speaker" 265``` 266 267#### Alternatives to storing your password in the config file <!-- omit in toc --> 268 269- **`password_cmd`** config entry 270 271 This 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 the `password_cmd` config entry to the command you would like to use and remove the `password` config entry. 272 273 For example (using the password-management utility [pass][pass-homepage]). 274 275 ```toml 276 # ~/.config/spotifyd/spotifyd.conf 277 password_cmd = "pass spotify" 278 ``` 279 280- **`use_keyring`** config entry / **`--use-keyring`** CLI flag <!-- omit in toc --> 281 282 This features leverages [Linux's DBus Secret Service API][secret-storage-specification] or native macOS keychain in order to forgo the need to store your password directly in the config file. To use it, complile with the `dbus_keyring` feature and set the `use-keyring` config entry to `true` or pass the `--use-keyring` CLI flag during start to the daemon. Remove the `password` and/or `password_cmd` config entries. 283 284 Your keyring entry needs to have the following attributes set: 285 286 ``` 287 application: rust-keyring 288 service: spotifyd 289 username: <your-spotify-username> 290 ``` 291 292 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: 293 294 ```bash 295 secret-tool store --label='name you choose' application rust-keyring service spotifyd username <your-username> 296 ``` 297 298 You can use the keychain GUI on macOS to add an item respectively, or with the built-in `security` tool: 299 300 ```bash 301 security add-generic-password -s spotifyd -D rust-keyring -a <your username> -w 302 ``` 303 304#### Shell used to run commands indicated by `password_cmd` or `on_song_changed_hook` <!-- omit in toc --> 305 306If 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`. 307 308## Running as a system service 309 310### on Linux 311 312A `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: 313 314``` 315/etc/systemd/user/ 316~/.config/systemd/user/ 317``` 318 319Packagers 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`. 320 321Control of the daemon is handed over to systemd. The following example commands will run the service once and enable the service to always run on login in the future respectively: 322 323``` 324systemctl --user start spotifyd.service 325systemctl --user enable spotifyd.service 326``` 327 328 329### on macOS 330 331On macOS the system wide and per-user daemon/agent manager is known as `launchd`. Interfacing with `launchd` is performed through `launchctl`. 332 333In order to use `spotifyd` as a service on macOS one must specify a `.plist` that represents the service, and place it in `/Library/LaunchDaemons`. 334 335Here is a .plist which works with macOS Catalina 10.15.3: 336 337``` 338<?xml version="1.0" encoding="UTF-8"?> 339<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 340<plist version="1.0"> 341 <dict> 342 <key>Label</key> 343 <string>rustlang.spotifyd</string> 344 <key>ProgramArguments</key> 345 <array> 346 <string>/usr/local/bin/spotifyd</string> 347 <string>--config-path=/users/YourUserName/.config/spotifyd/spotifyd.conf</string> 348 <string>--no-daemon</string> 349 </array> 350 <key>UserName</key> 351 <string>YourUserName</string> 352 <key>KeepAlive</key> 353 <true/> 354 <key>ThrottleInterval</key> 355 <integer>30</integer> 356 </dict> 357</plist> 358``` 359 360 361Once present in the `/Library/LaunchDaemons` directory, the .plist must be loaded and started with the following commands. 362 363`sudo launchctl load -w /Library/LaunchDaemons/rustlang.spotifyd.plist` 364 365 366`sudo launchctl start /Library/LaunchDaemons/rustlang.spotifyd.plist` 367 368One may also unload/stop the service in a similar fashion replacing load/start with unload/stop. 369 370Note: 371 372* You should update "YourUserName" with your actual username for macOS (or remove "UserName" to run as root. 373 374 375* 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. 376 377* 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. 378 379## Common issues 380 381- Spotifyd will not work without Spotify Premium 382- The device name cannot contain spaces 383 384## Contributing 385 386We always appreciate help during the development of `spotifyd`! If you are new to programming, open source or Rust in general, take a look at issues tagged with [`good first issue`][good-first-issues]. These normally are easy to resolve and don't take much time to implement. 387 388## Credits 389 390This project would not have been possible without the amazing reverse engineering work done in [librespot](https://github.com/librespot-org/librespot), mostly by [plietar](https://github.com/plietar). 391 392<!-- This section contains all links used within the document. This prevents cluttering and makes reading the raw markdown a lot easier --> 393[github-actions]: https://github.com/Spotifyd/spotifyd/actions 394[good-first-issues]: https://github.com/Spotifyd/spotifyd/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 395[mpris-specification]: https://specifications.freedesktop.org/mpris-spec/latest/ 396[pass-homepage]: https://www.passwordstore.org/ 397[playerctl-homepage]: https://github.com/altdesktop/playerctl 398[secret-storage-specification]: https://www.freedesktop.org/wiki/Specifications/secret-storage-spec/ 399[sp-homepage]: https://gist.github.com/wandernauta/6800547 400 401[cd-badge]: https://github.com/Spotifyd/spotifyd/workflows/Continuous%20Deployment/badge.svg 402[ci-badge]: https://github.com/Spotifyd/spotifyd/workflows/Continuous%20Integration/badge.svg 403[dependabot-badge]: https://api.dependabot.com/badges/status?host=github&repo=Spotifyd/spotifyd 404