Take the BUS! How to control Spotify with the terminal
As a guy who loves to use the terminal I always look for stuff that makes my life easier. My .zshrc is filled with a bunch of aliases to make my daily doing more convenient.
Everything in my terminal window is under control but to start Spotify, play & pause songs or jump to the next song I always had to switch the window focus or use the mouse. That was something I want to get rid of, so I started to investigate how linux desktop programs & processes communicate with each other.
So if you want to know how desktop applications do that or you also want to control Spotify or other desktop applications with the terminal, lean back and continue reading.
The D-BUS
The D-BUS or desktop-BUS is a library which desktop programs in linux use for internal process communication. It was created by the open source freedesktop organization to unify the way how desktop programs share information. So, if a process of a program want’s to share information with an other process, it sends a message to the D-BUS. Today the D-BUS is part of almost all modern distributions out there.
The D-BUS consists of three parts. The D-BUS daemon which is basically responsible for handling all the messages. The library libdbus which is an API and has to be use by the process to send or receive messages. And the D-BUS protocol which defines how a message look like.
So let’s have a look at an ordinary scenario. Lets imagine Proccess A is the HAL-daemon which recognize that you plugged in a USB-stick. It will send a message to the D-BUS to tell anyone who’s interested in a hardware change. Now lets say, Proccess B is our file manager, which is interested in hardware changes. It will take the information from the D-BUS and knows now that there is a new device, so it shows us the USB-icon in the file manager.
The D-BUS is separated in two channels, the Session BUS and the System BUS. The Session Bus is used when ever a process want’s to talk to an other process within the same desktop session. The System BUS is used for the communication to the kernel or other parts of the system. So the USB example from above used the System BUS because a system daemon sent the message to the D-BUS.
The Idea of control
After I recognized that the communication between desktop programs is handled by the D-BUS I started to search for interfaces that programs likes Spotify provides. My idea was to send a message from my terminal window to the Spotify D-BUS interface to pause the current song or jump to the next one.
Finding the Spotify D-BUS interface
One way to figure out what interfaces are available on the current Session Bus is to actually send a message to the D-BUS. Because the developers of the D-BUS already integrated such an interface. But also for me as a terminal lover, this is really unhandy. But for everyone who want’s to give it a try check out this command:
$> dbus-send — session \
— dest=org.freedesktop.DBus \
— type=method_call \
— print-reply \
/org/freedesktop/DBus \
org.freedesktop.DBus.ListNames
I prefer to use a tool for that task and the first one I found (D-Feet) worked out of the box. With D-Feet you can simply search for program name you want to investigate. Alternatively you can scroll to all the interfaces the system or session provides.
Take control
After I found the interface I was looking for I started to play arround with the actual methods and send messages to the D-BUS. As same as listing command this can be done by the dbus-send command but I prefer qdbus. Qdbus is a small program which makes sending messages really easy.
So lets send a message to the running Spotify software and take a deeper look at all arguments of the command.
qdbus org.mpris.MediaPlayer2.spotify\
/org/mpris/MediaPlayer2 \
org.mpris.MediaPlayer2.Player.PlayPause
- qdbus (The program which sends the message)
- org.mpris.MediaPlayer2.spotify (The program we want to talk to, Spotify)
- /org/mpris/MediaPlayer2 (The object path)
- org.mpris.MediaPlayer2.Player.PlayPause (The interface name including the method we want to call, which is PlayPause)
As you can see, all information are provided by D-Feet and easy to use in the terminal. To have a bit more convenience I wrapped the command into an alias and paste it into my .zshrc
alias spp=’qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause’
But that’s not the end of the road. Spotify provides a lot more Methods on the interface which can be used. E.g. skipping a song or jumping backwards.
One of my favorite ones is selecting a playlist. With the following command I start Spotify from the terminal, wait three seconds to enshure the program is up’n running and then send the message to open my weekly playlist.
(spotify 1>/dev/null 2>&1 &) && \
sleep 3 && \
qdbus org.mpris.MediaPlayer2.spotify \
/org/mpris/MediaPlayer2 \
org.mpris.MediaPlayer2.Player.OpenUri \
spotify:playlist:37i9dQZEVXcVAMA5dHC059
Sum up
Sending messages to the D-BUS to control a desktop application is not only a hacky trick to increase the terminal convenience. Further it increased my knowledge about my operating system and how things are glued together.
But the most important thing is, that it was a lot fun to figure out how all the stuff works and what is also possible.