Spotify from the command line
During the setup and build of a new machine I was making efforts to explore and learn the Linux environment in deeper detail. A large part of this involved setting up various utilities from (closer-to-)scratch. One of these was spotify from the command line. Since I had to implement a couple of workarounds I thought I’d write about it in the hope others might find it useful in future.
`
NOTE [August 2023]:
As anticipated in the below article, spotify-tui has been confirmed, for now,
to be abandoned by the developer.
As a result I have moved to
spotify-player
which is well packaged, easy to install, and does not require separate client setup.
I am leaving the this article here should any of it be useful in future.
Why spotify from the command line?
- I’m currently in the command line hipster mindset. Let’s just be honest, that has a lot to do with it. In serious though I am terrible at having multiple windows and tabs open cluttering up my computer and mind. Reducing spotify to a command line tool that is easily opened from a terminal when needed should help reduce this.
- It should throw up a number of interesting learning opportunities around audio and software.
- Spotify’s linux app is proprietry. Whilst I have nothing against spotify providing an audio streaming service, this fits in with the FOSS ethos and knowing exactly what is on my computer.
To achieve this we are going to make use of two pieces of software, spotifyd to stream audio, and spotify-tui to access the API and provide an interface.
A significant amount of this was aided by an article similar to this one written by Sophia Brandt and tha package documentation. However, anything in Linux is rarely straightforward, and there are a few differences in the way I did things.
spotifyd client
The first step is to install a client for streaming music from spotify. To do this I used spotifyd as recommended by the command-line client I planned to use (spotify-tui).
Instructions for setting this up on the github repo are fairly minimal.
On Arch this involved running sudo pacman -S spotifyd
.
Access to your account then requires a config file which I placed at ~/.config/spotifyd/spotifyd.conf
.
If you do enough digging there is
an example of this
in the repo.
For my purposes I used pulseaudio, though this was established through a process of trial and error. Since I am using wayland I have PipeWire which features compatability interfaces on to both ALSA and PulseAudio. Setting pulseaudio is what worked for me.
device_name
is how this device will appear in spotify’s ‘device list’ to be controlled from other devices. I chose the name of the laptop I am installing it on.
|
|
This script can now be run through spotifyd --verbose
to view any outputs and aid with debugging.
spotifyd recommend you then create a system daemon service through systemctl --user enable --now spotifyd.service
. You can check that it is running properly with systemctl --user status spotifyd.service
and journalctl
.
I did not do this, however, as I want to make use of pass , the Linux password manager. The setup for doing this in spotifyd is currently buggy ( GitHub issue #696 ) so I’ll implement a workaround below. Perhaps once I have had a play around I might look at this if it hasn’t been resolved.
spotify-tui
install
The next step is to install spotify-tui through which we will interact with spotify.
This does not stream music, but instead interacts with the spotify API to display information and provide navigation and control, it interfaces with spotifyd to then stream and play music.
spotify-tui is available on the
AUR
and can be installed by your method of choice (mine is pikaur): pikaur -S spotify-tui
.
Here there is a slight nuance as, for me, the default install raises issues with locating OpenSSL headers. Whilst the relevant issues on GitHub were not helpful, there is a reddit post that came in useful. The solution was to update the PKGBUILD when pikaur asks and change
|
|
to
|
|
I suspect this occurs because spotify-tui has not been updated in a year (need to keep an eye on this in case it becomes unsupported) and the --frozen
flag now refers to packages that are now out of date.
API access
The next step is to generate a key to access the spotify API. The instructions in the documentation are very clear for this:
- Go to the Spotify dashboard
- Click ‘Create an app’
You now can see your
Client ID
andClient Secret
- Now click ‘Edit Settings’
- Add
http://localhost:8888/callback
to the Redirect URIs - Scroll down and click ‘Save’
- You are now ready to authenticate with Spotify!
- Go back to the terminal
- Run
spt
- Enter your
Client ID
when prompted - Enter your
Client Secret
when propmted - Press enter to confirm the default port (8888) or enter a custom port
- You will be redirected to an official Spotify webpage to ask you for permissions.
- After accepting the permissions, you’ll be redirected to localhost. If all goes well, the redirect URL will be parsed automatically and now you’re done. If the local webserver fails for some reason you’ll be redirected to a blank webpage that might say something like “Connection Refused” since no server is running. Regardless, copy the URL and paste into the prompt in the terminal.
configuration
This first run generates a YAML config file at ~/.config/spotify-tui/config.yml
(and a client file for authentication).
The
documentation
has an example.
Launching
As mentioned above, I did not set spotifyd up as a systemd process as I wanted to implement a password workaround so that I could use the
Linux password manager
pass
.
It also means that I don’t need to have spotifyd running in the background unless I need it which might save on some energy.
This was inspired by a
youtube video
for launching spotifyd when required, and I built on top of it to add pass
functionality.
I added the following alias function to my ~/.bashrc
allowing me to successfully launch spt with the command spotify
:
|
|
The command starts a process that first checks if spotifyd is already running.
If it is, great, if not then the password is requested from pass
and redirected to /dev/null
.
This has the effect of prompting us for our gpg key to release the password.
I have a 5 second cache on my gpg key (set default-cache-ttl 5
in ~/.gnupg/gpg-agent.conf
) meaning that it is still available when called through spotifyd.
Note that we need to comment out password = "<your spotify password>"
and uncomment password_cmd = "pass show spotify | head -n 1"
in ~/.config/spotifyd/spotifyd.conf
.
Closing
At the end of all this I am able to control and play spotify through my laptop using minimalist FOSS from the command line.
It took me a while to realise that I search by typing /<your search term>
, and whilst some windows support looping scrolling, others need to be navigated in a pgdn
, pgup
fashion with ctrl+d
and ctrl+u
.
My final bit of coding involved binding the play/pause and skip buttons to the
|
|
My one main gripe is more with spotify than the software here. The spotify API only allows control over spotify clients on other devices, so whilst I can control playback on my laptop from my phone and vice versa I can’t control my third-party speaker system from spotify-tui, only from the proprietry client on my phone.
I’ve also come across an issue where one of the podcasts I listen to returns an API error when I try and select it in spotify-tui. Interestingly the episodes play if I am controlling spotify from my phone (playing through my laptop). Something to investigate in future perhaps.
A final comment would be that spotify-tui currently displays minimal metadata. It might be nice if it could display a little more info such as album release year etc. This should hopefully be relatively straightforward based on the current code, and I have been meaning to take a look at Rust…