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 tospotifyd - Method
VolumeUp: increases player volume - Method
VolumeDown: decreases player volume
Examples:
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 are implemented.
Example usage:
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:
#!/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:
#!/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