Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update docs #1327

Merged
merged 10 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- '**.rs'
- 'Cargo.toml'
- 'Cargo.lock'
- 'contrib/spotifyd.conf'

jobs:
codestyle:
Expand Down Expand Up @@ -50,7 +51,7 @@ jobs:
command: clippy
args: --all-targets --all-features -- -D warnings

check:
test:
needs: [lint]
runs-on: ${{ matrix.os }}
strategy:
Expand Down Expand Up @@ -83,5 +84,5 @@ jobs:
- name: Checking Rust code
uses: actions-rs/cargo@v1
with:
command: check
command: test
args: --locked --no-default-features --features ${{ matrix.features }}
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ directories = "5.0.1"
thiserror = "2.0"
time = { version = "0.3.37", default-features = false, features = ["formatting"] }
clap = { version = "4.5.23", features = ["derive"] }
serde_ignored = "0.1.10"

[target."cfg(unix)".dependencies]
daemonize = "0.5"
Expand Down
115 changes: 115 additions & 0 deletions contrib/spotifyd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
[global]

#---------#
# GENERAL #
#---------#

# The name that gets displayed under the connect tab on
# official clients.
#device_name = "device_name_in_spotify_connect"

# 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"

# The directory used to store credentials and audio cache.
# Default: infers a sensible cache directory (e.g. on Linux: $XDG_CACHE_HOME)
#
# Note: The file path does not get expanded. Environment variables and
# shell placeholders like $HOME or ~ don't work!
#cache_path = "/full/path/to/cache/directory"

# If set to true, audio data does NOT get cached.
# In this case, the cache is only used for credentials.
#no_audio_cache = true

# The maximal size of the cache directory in bytes
# The example value corresponds to ~ 1GB
#max_cache_size = 1000000000

# 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"

#-----------#
# DISCOVERY #
#-----------#

# If set to true, this disables zeroconf discovery.
# This can be useful, if one prefers to run a single-user instance.
#disable_discovery = false

# 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

#-------#
# AUDIO #
#-------#

# The audio backend used to play music. To get
# a list of possible backends, run `spotifyd --help`.
#backend = "alsa" # use portaudio for macOS [homebrew]

# The alsa audio device to stream audio. To get a
# list of valid devices, run `aplay -L`,
#device = "default" # 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 volume controller. Each one behaves different to
# volume increases. For possible values, run
# `spotifyd --help`.
#volume_controller = "softvol" # use softvol for macOS

# ! Only relevant for ALSA !
# The alsa control device. By default this is the same
# name as the `device` field.
#control = "default"

# ! Only relevant for ALSA !
# The alsa mixer used by `spotifyd`.
#mixer = "PCM" # omit for macOS

# The audio bitrate. 96, 160 or 320 kbit/s
#bitrate = 160

# Volume on startup between 0 and 100
#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

#-------ä
# OTHER #
#-------#

# After the music playback has ended, start playing similar songs based on the previous tracks.
# By default, `spotifyd` infers this setting from the user settings.
#autoplay = true

# A command that gets executed in your shell after each song changes.
#on_song_change_hook = "echo \"hook executed on $PLAYER_EVENT\""

# The proxy `spotifyd` will use to connect to spotify.
#proxy = "http://proxy.example.org:8080"
10 changes: 6 additions & 4 deletions docs/src/Introduction.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Introduction

This is the documentation of [spotifyd][spotifyd]
> An open source Spotify client running as a UNIX daemon.
This is the documentation of [spotifyd][spotifyd], which covers the installation and setup process as well as some advanced topics.

These docs should be regarded as an extension of the [README][spotifyd] so please check there first before looking through the docs.
## Getting Help

[spotifyd]: https://github.com/Spotifyd/spotifyd
If you're stuck in the setup process or have a question, please join the [community matrix server][matrix]. We're always willing to help!

[spotifyd]: https://github.com/Spotifyd/spotifyd
[matrix]: https://matrix.to/#/#spotifyd:matrix.org
33 changes: 16 additions & 17 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

[Introduction](./Introduction.md)

- [Installation Instructions](./installation/README.md)
- [Installing on a Raspberry Pi](./installation/Raspberry-Pi.md)
- [Installing on Ubuntu (from source)](./installation/Ubuntu.md)
- [Cross Compiling on Ubuntu](./installation/Cross-Compiling-on-Ubuntu.md)
- [Cross Compilation using Docker](./installation/cross-compile-using-docker.md)
- [Installing with Homebrew on macOS](./installation/MacOS.md)
- [Installing on FreeBSD](./installation/FreeBSD.md)
- [Installing on OpenBSD](./installation/OpenBSD.md)
- [Configuration](./config/README.md)
- [CLI options](./config/Cli.md)
- [Configuration file](./config/File.md)
- [Running as a Service](./config/services/README.md)
- [Running as systemd service](./config/services/Systemd.md)
- [Running as launchd service (MacOS)](./config/services/MacOS.md)
- [Other]()
- [D-Bus control](./other/D-Bus-control.md)

- [Installation](./installation/README.md)
- [Running as a service](./installation/service.md)
- [Installing on RaspberryPi OS 64-bit](./installation/raspberrypi64.md)
- [Building from source](./installation/source.md)
- [Cross-Compile using Docker](./installation/cross-compile-using-docker.md)
- [Configuration](./configuration/README.md)
- [Authentication](./configuration/auth.md)
- [Audio](./configuration/audio.md)
- [Other settings](./configuration/other.md)
- [Advanced Setup](./advanced/README.md)
- [Running as systemd service](./advanced/systemd.md)
- [Running as launchd service](./advanced/launchd.md)
- [Using D-Bus to control `spotifyd`](./advanced/dbus.md)
- [MPRIS on headless systems](./advanced/mpris.md)
- [Extending spotifyd with hooks](./advanced/hooks.md)
- [Troubleshooting](./troubleshooting.md)
3 changes: 3 additions & 0 deletions docs/src/advanced/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Advanced Setup

In this section, you will learn how to persist `spotifyd` as a system service, run hook scripts on certain events and control `spotifyd` via DBUS on headless systems.
118 changes: 118 additions & 0 deletions docs/src/advanced/dbus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Using D-Bus to control spotifyd

If MPRIS support is built into your version and enabled (`--use-mpris` cli flag / `use_mpris = true` in config), `spotifyd` exposes some interfaces via D-Bus through which it provides information and can be controlled.

Most of the time, you won't have to worry to much about the details, since tools like `playerctl` work out of the box with `spotifyd`. If you have some custom requirements or want to write custom scripts to control `spotifyd`, this section is for you.

## Available Interfaces

Directly after startup, no interfaces will be available. Once we are connected to Spotify, `spotifyd` will request the name `rs.spotifyd.instance$PID` (where `PID=$(pidof spotifyd)`) and expose the interface `rs.spotifyd.Controls`.

As soon as we are the playback device (e.g. because we are selected from another client or the `TransferPlayback` method has been called), `spotifyd` will additionally expose the MPRIS interfaces and request the name `org.mpris.MediaPlayer2.spotifyd.instance$PID`.

### Spotifyd Controls

The `rs.spotifyd.Controls` interface exposes a few useful controls that are available even if we're not the active playback device.

- Method `TransferPlayback`: transfers Spotify playback to `spotifyd`
- Method `VolumeUp`: increases player volume
- Method `VolumeDown`: decreases player volume

Examples:
```bash
dest=rs.spotifyd.instance$(pidof spotifyd)
# increase volume
dbus-send --print-reply --dest=$dest /rs/spotifyd/Controls rs.spotifyd.Controls.VolumeUp
# become the active playback device
dbus-send --print-reply --dest=$dest /rs/spotifyd/Controls rs.spotifyd.Controls.TransferPlayback
```

### MPRIS

The `org.mpris.MediaPlayer2` and `org.mpris.MediaPlayer2.Player` interfaces from the [MPRIS specification](https://specifications.freedesktop.org/mpris-spec/latest/) are implemented.

Example usage:
```bash
dest=org.mpris.MediaPlayer2.spotifyd.instance$(pidof spotifyd)
# Start playback of some Spotify URI
dbus-send --print-reply --dest=$dest /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.OpenUri string:spotify:track:4PTG3Z6ehGkBFwjybzWkR8
# Get metadata of the currently playing track
dbus-send --print-reply --dest=$dest /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Metadata
```

## Examples

Starting Playback without Client:
```bash
#!/bin/bash

# optionally, we can start `spotifyd` here
if ! pidof -q spotifyd
then
spotifyd --use-mpris
fi

dest=rs.spotifyd.instance$(pidof spotifyd)

wait_for_name() {
dst=$1
counter=0

# check if controls are available
until [ $counter -gt 10 ] || (dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep -q "$dest")
do
sleep 0.3
((counter++))
done

if [ $counter -gt 10 ]
then
echo "waiting for spotifyd timed out" >&1
exit 1
fi
}

controls_name=rs.spotifyd.instance$(pidof spotifyd)
wait_for_name $controls_name
echo "Transferring Playback"
dbus-send --print-reply --dest=$controls_name /rs/spotifyd/Controls rs.spotifyd.Controls.TransferPlayback

# if URI is specified, start the playback there
if [ -n "$1" ]
then
uri="$1"
mpris_name=org.mpris.MediaPlayer2.spotifyd.instance$(pidof spotifyd)
wait_for_name $mpris_name
echo "Starting Playback of $uri"
dbus-send --print-reply --dest=$mpris_name /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.OpenUri "string:$uri"
else
echo "Hint: specify an argument to start playback of a specific Spotify URI"
fi
```

Sleep Timer:
```bash
#!/bin/bash

usage() {
echo "Usage: $0 <timeout>" >&1
exit 1
}

[ -n "$1" ] || usage

echo "Sleeping for $1 seconds"
sleep $1

dest=org.mpris.MediaPlayer2.spotifyd.instance$(pidof spotifyd)
dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep -q "$dest"

if [ "$?" = "0" ]
then
dbus-send --print-reply --dest=$dest /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Stop
# alternatively just pause:
# dbus-send --print-reply --dest=$dest /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause
else
echo "No active spotifyd playback."
fi
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# User supplied Scripts

If you want to create custom behaviour around `spotifyd`, one option is to look into the [D-Bus functionality](./dbus.md). But on headless systems or smaller projects, we also offer a hook API. On certain events, a hook can be executed with event details given as environment variables.

To point `spotifyd` to such a script, use the `--onevent /path/to/script` cli arg / `on_song_change_hook = "/path/to/script"` configuration value.

In order to learn about the available events and the available details, you can either create simple scripts which log the given environment variables or look at the output of `spotifyd`, which logs whenever the script is executed.

The following scripts are intended to serve as inspiration for your own scripts. If you have written own scripts which you think might be useful to others, please create a PR adding them here!

## Dunst Notifications (Using Spotify API)

This script will show a dunst notification when you play/change/stop Spotify (and when the music change). It is using spotify APIs to get music details.
Expand Down Expand Up @@ -48,19 +56,5 @@ This script will show a dunst notification when you play/change/stop Spotify (an
fi
```

* Make this script executable (```chmod +x ntification_script.sh```)
* Add the line ```onevent = "bash /home/YOU_USER/bin/spotifyNotifications.sh"``` to your ```spotifyd.conf```

## Dunst Notifications (Using Playerctl metadata)

This script is a modification of the script supplied above, however instead of calling the Spotify API for track information, the metadata of the current track is used instead, leading to a more performant script.

### Dependencies

* [Playerctl](https://github.com/altdesktop/playerctl)

### How to Use:

* Download this [gist](https://gist.github.com/ohhskar/efe71e82337ed54b9aa704d3df28d2ae)
* Make the script executable (```chmod +x notifications.sh```)
* Add the line ```onevent = "/path/to/file/spotifyNotifications.sh"``` to your ```spotifyd.conf```
* Make this script executable (`chmod +x notification_script.sh`)
* Add the line `onevent = "bash /home/YOU_USER/bin/spotifyNotifications.sh"` to your `spotifyd.conf`
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Running spotifyd as a service on macOS
# Running as launchd service

On macOS the system wide and per-user daemon/agent manager is known as `launchd`. Interfacing with `launchd` is performed through `launchctl`.
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`.

Expand Down
Loading
Loading