In the forever quest for the perfect <INSERT THING HERE> setup, I’ve recently installed spotifyd on my Raspberry Pi so that I can casually switch from my phone’s headphones to my HiFi system when I come home, sit back, relax & enjoy my sweet streamed tunes.
So after this, you’ll have your RaspberryPi hooked up to your HiFi system, which you’ll be able to control via your smartphone, or any Spotify app instance. This will only work if you have a spotify premium account.
Spotifyd - The Spotify Daemon
Spotifyd is a neat little daemon written in Rust. It implements the Spotify connect protocol which allows you to control one instance of spotify from another (ie. control your PC’s spotify with your smartphone).
Building Spotifyd on RaspberryPi
As my RaspberryPi’s primary function is a media center, I’m runnig OSMC (a linux distribution forked from debian) on it. So your mileage may vary, as you may have a different setup.
First you need to install Rust, refer to this page for the latest instructions on how to install Rust.
Once this is done, you should be able to invoke cargo build --release
(cargo
being Rust’s package manager), this should install the dependencies needed by
Spotifyd.
This can a while on a RaspberryPi so be patient…
Once it is done, you will need a configuration file for spotifyd, go ahead and
issue the following command mkdir -p ~/.config/spotifyd/
, in that folder
create a config file that looks something like:
[global]
username = YOUR_USER_NAME
password = YOUR_PASSWORD
backend = alsa
device = hw:0
onstart = /usr/bin/amixer cset numid=3 1
onstop = /usr/bin/amixer cset numid=3 0
device_name = videodrome
bitrate = 320
cache = /home/osmc/.cache/spotifyd/
You might also want to create the ~/.cache/spotifyd
folder.
This is pretty straightforward for the most part, the tricky part being things
related to the audio backend, namely backend
, device
, onstart
and
onstop
.
The RaspberryPi has two audio outputs, one for HDMI (through the TV speakers) and one for the analog jack plug (for the HiFi). In this setup, both outputs will be used thanks to some wizardry.
Identifying your audio output
Running aplay -L
(you can sudo apt-get install alsa-utils
if theaplay
is
not available) will list all the audio devices you have. The output is pretty
cryptic, here’s mine:
osmc@Videodrome:~$ aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
default:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
sysdefault:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
dmix:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample mixing device
dmix:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample mixing device
dsnoop:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample snooping device
dsnoop:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample snooping device
hw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct hardware device without any conversions
hw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct hardware device without any conversions
plughw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Hardware device with all software conversions
plughw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Hardware device with all software conversions
Well I will save you the trouble of googling for hours. Although the RaspberryPi has two audio outputs, they’re both handled by the same hardware device (sound card).
Since you only have 1, the device is hw:0
, that’s the device = hw:0
line in
your config file.
Now that’s where it gets tricky, according to this page from the Pi’s website
The Raspberry Pi has two audio output modes: HDMI and headphone jack. You can switch between these modes at any time.
If your HDMI monitor or TV has built-in speakers, the audio can be played over the HDMI cable, but you can switch it to a set of headphones or other speakers plugged into the headphone jack. If your display claims to have speakers, sound is output via HDMI by default; if not, it is output via the headphone jack. This may not be the desired output setup, or the auto-detection is inaccurate, in which case you can manually switch the output.
I did not succeed in specifying the Jack device directly in the spotifyd.conf
file. But as the RaspberryPi document states, you can invoke amixer cset numid=3 1
to set the audio output to the headphone jack. That why we
have the onstart = amixer cset numid=3 1
in the configuration file. I’m not
sure how this works, but this seems “session specific” as only spotifyd’s audio
output is directed to the jack (the media center continues to output to HDMI).
But hey, it works ! :P
The alsa-utils
package also comes with a player called aplay
, you can go
ahead and test your audio output by typing:
$> amixer cset numid=3 1
$> aplay whatever.wav
If you hear a sound, you’re all set !
Create a Service
It’s nice to have that daemon running and all, but things crash, and having a way to have it relaunched automatically is always a plus. OSMC uses systemd to manage services (which is subject to heated debates).
Create the /lib/systemd/system/spotifyd.service
file with the following
content:
[Unit]
Description=Spotifyd
[Service]
ExecStart=/home/osmc/spotifyd/target/release/spotifyd --no-daemon --config /home/osmc/.config/spotifyd/spotifyd.conf
Restart=always
[Install]
WantedBy=multi-user.target
Then issue the following commands:
$> sudo chmod 644 /lib/systemd/system/spotifyd.service
$> sudo systemctl daemon-reload
$> sudo systemctl enable spotifyd.service
$> sudo systemctl start spotifyd.service
Now run this, and if you have a similar output, everything is setup !
osmc@Videodrome:~$ systemctl status spotifyd.service
● spotifyd.service - Spotifyd
Loaded: loaded (/lib/systemd/system/spotifyd.service; enabled)
Active: active (running) since ven. 2017-06-09 16:43:47 CEST; 5h 54min ago
Main PID: 27502 (spotifyd)
CGroup: /system.slice/spotifyd.service
└─27502 /home/osmc/spotifyd/target/release/spotifyd --no-daemon --config /home/osmc/.config/spotifyd/spotifyd.conf
Systemd will now make sure that this service is running, and relaunch it in the event of a crash !
What does not work
- Volume cannot be adjusted
- The feature is not implemented yet in spotifyd This github issue talks about it.
- Repeat/Shuffle toggles don’t work
- librespot does not implement this yet, this issue talks about it.
Enjoy your setup !