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
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
This is pretty straightforward for the most part, the tricky part being things
related to the audio backend, namely
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
aplay -L (you can
sudo apt-get install alsa-utils if the
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
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
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
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).
/lib/systemd/system/spotifyd.service file with the following
[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 !