Part 7 — Spotify (Raspotify →Spotifyd)

A much appreciated feature in recent connected amplifiers is the ability to play music from streaming services. Even if I have a huge media library, everything is not in it, so I wanted to add support of Spotify on my HiFi server.

The obvious choice was Raspotify, a Raspberry Spotify client based on librespot, an open source Spotify client. However, a premium Spotify account is required.

The installation is very easy :

$ curl -sL https://dtcooper.github.io/raspotify/install.sh | sh

The configuration file is located at /etc/default/raspotify

# /etc/default/raspotify --Arguments/configuration for librespot

# Device name on Spotify Connect
DEVICE_NAME=”onkyo-raspotify”

# Bitrate, one of 96 (low quality), 160 (default quality), or 320 (high quality)
BITRATE=”160"

# Additional command line arguments for librespot can be set below.
# See `librespot -h` for more info. Make sure whatever arguments you specify
# aren’t already covered by other variables in this file. (See the daemon’s
# config at `/lib/systemd/system/raspotify.service` for more technical details.)
#
# To make your device visible on Spotify Connect across the Internet add your
# username and password which can be set via “Set device password”, on your
# account settings, use ` --username` and ` --password`.
#
# To choose a different output device (ie a USB audio dongle or HDMI audio out),
# use ` --device` with something like ` --device hw:0,1`. Your mileage may vary.
#
#OPTIONS=” --username <USERNAME> --password <PASSWORD>”

# Uncomment to use a cache for downloaded audio files. Cache is disabled by
# default. It’s best to leave this as-is if you want to use it, since
# permissions are properly set on the directory `/var/cache/raspotify’.
#CACHE_ARGS=” --cache /var/cache/raspotify”

# By default, the volume normalization is enabled, add alternative volume
# arguments here if you’d like, but these should be fine.
VOLUME_ARGS=”--linear-volume --initial-volume=100"
#VOLUME_ARGS=”--enable-volume-normalisation --linear-volume --initial-volume=100"

# Backend could be set to pipe here, but it’s for very advanced use cases of
# librespot, so you shouldn’t need to change this under normal circumstances.
#BACKEND_ARGS=”--backend alsa”

First I modified the DEVICE_NAME, which will be the name of the Pi in the Spotify App.

For performance issues, I kept the 160 bitrate, 320 seems too stressful for the Raspberry B+ processor, and I removed the enable-volume-normalisation option which often created annoying pauses or cracks when playing music, especially the ones using silences. I also noticed that the audio quality was way better without it.

Edit 20/04/2021: After an update I noticed pulsaudio and librespot CPU usage had dropped significantly and I can now use the 320 kbps birate without performance issues, which is pretty nice for such an old Raspberry model.

We now have to restart raspotify for the changes to be taken into account

$ sudo systemctl restart raspotify

As you may have noticed, Raspotify use ALSA as audio backend. If you read the rest of this guide, you know I use Pulseaudio and it’s really bad to have a program accessing ALSA directly in this setup. Fortunately there’s a way to configure ALSA to work with Pulseaudio without troubles. All you have to do is add a few lines to /etc/asound.rc

pcm.!default {
type pulse
}

ctl.!default {
type pulse
}

I’m afraid I don’t exactly how to restart ALSA without rebooting, but after this when using Raspotify, you can run this command and see ALSA being managed by Pulseaudio

$ pactl list sink-inputs

Sink Input #49
Driver: protocol-native.c
Owner Module: 11
Client: 69
Sink: 0
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Format: pcm, format.sample_format = “\”s16le\”” format.rate = “44100” format.channels = “2” format.channel_map = “\”front-left,front-right\””
Corked: no
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Buffer Latency: 407709 usec
Sink Latency: 19516 usec
Resample method: copy
Properties:
media.name = “ALSA Playback”
application.name = “ALSA plug-in [librespot]”
native-protocol.peer = “TCP/IP client from 127.0.0.1:57936”
native-protocol.version = “32”
application.process.id = “417”
application.process.user = “raspotify”
application.process.host = “Ampli-BT”
application.process.binary = “librespot”
application.language = “C”
application.process.machine_id = “94407542ae804e6f9e791df75037e3d2”
module-stream-restore.id = “sink-input-by-application-name:ALSA plug-in [librespot]”

In January 2022, I experienced issues with Raspotify, the new released versions were too CPU intensive for my old B+. The solution I found was to downgrade to a specific version and prevent it from upgrade using :

$ wget https://github.com/dtcooper/raspotify/releases/download/0.31.3/raspotify_0.31.3.librespot.v0.3.1-19-gbbd575e_armhf.deb
$ sudo dpkg -i raspotify_0.31.3.librespot.v0.3.1–19-gbbd575e_armhf.deb
$ sudo apt-mark hold raspotify

The following version also works but introduces configuration changes I won’t cover here since I changed of software soon after.

Spotifyd

I was not really happy being stuck with an old software version, API changes in Spotify would break my install, so I looked for an alternative to Raspotify. I noticed HifiBerryOS was using Spotifyd, an alternative written in Rust, so I decided to give it a try. Documentation is available here.

First we need to install the appopriate version

$ sudo wget https://github.com/Spotifyd/spotifyd/releases/download/v0.3.3/spotifyd-linux-armv6-slim.tar.gz -P /opt/
$ sudo tar xf /opt/spotifyd-linux-armv6-slim.tar.gz
$ sudo mv /opt/spotifyd /opt/bin

Then we create our configuration file. I assume you already configured Pulseaudio and ALSA together as mentionned above.

$ mkdir /home/pi/.config/spotifyd
$ vim /home/pi/.config/spotifyd/spotifyd.conf

[global]
#username = “USER”
#password = “PASS” # Those are optional if you plan to use it with Spotify Connect
backend = “alsa”
device = “default” # Given by `aplay -L`
mixer = “PCM”
volume-controller = “alsa” # or alsa_linear, or softvol
#onevent = command_run_on_playback_event
device_name = “rasponkyo”
bitrate = 320
#cache_path = “cache_directory”
volume-normalisation = false
normalisation-pregain = 0

We now need a systemd unit to run Spotifyd at boot

$ vim ~/.config/systemd/user/spotifyd.service

[Unit]
Description=A spotify playing daemon
Documentation=
https://github.com/Spotifyd/spotifyd
Wants=sound.target
After=sound.target
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/opt/bin/spotifyd --no-daemon
Restart=always
RestartSec=12

[Install]
WantedBy=default.target

$ systemctl --user daemon-reload
$ systemctl --user enable spotifyd.service
$ systemctl --user start spotifyd.service

We can see spotifyd running in journalctl

$ journalctl -f -u spotifyd.service

Apr 02 13:55:40 rasponkyo systemd[552]: Started A spotify playing daemon.
Apr 02 13:55:41 rasponkyo spotifyd[5985]: Loading config from “/home/pi/.config/spotifyd/spotifyd.conf”
Apr 02 13:55:41 rasponkyo spotifyd[5985]: No username specified. Checking username_cmd
Apr 02 13:55:41 rasponkyo spotifyd[5985]: No username_cmd specified
Apr 02 13:55:41 rasponkyo spotifyd[5985]: No password specified. Checking password_cmd
Apr 02 13:55:41 rasponkyo spotifyd[5985]: No password_cmd specified
Apr 02 13:55:41 rasponkyo spotifyd[5985]: No proxy specified
Apr 02 13:55:41 rasponkyo spotifyd[5985]: Using software volume controller.
Apr 02 13:55:51 rasponkyo spotifyd[5985]: Connecting to AP “ap.spotify.com:443”
Apr 02 13:55:51 rasponkyo spotifyd[5985]: Authenticated as “**************” !
Apr 02 13:55:51 rasponkyo spotifyd[5985]: Country: “FR”
Apr 02 13:55:51 rasponkyo spotifyd[5985]: Using Alsa sink with format: S16

You might have already guessed it since I took the time to write this solution, it does work better than Raspotify without any feature loss, so that’s a great win. Unforunately there aren’t as many configuration possible.

Be aware that since no repository are available for Spotifyd we’ll need to keep an eye on the repository to be informed of new releases. Fortunately Github has a feature exactly for this :

To use Spotify Connect, you need a Spotify application on a computer or phone running on the same network as the Raspberry, and then can redirect the audio output to Raspotify.

Tap the bottom left speaker icon to open the screen below, and select your fresh Raspotify client.

You could argue it’s not really interested when using the computer, since the audio output is already set to the Raspberry pulseaudio sink, but this way you can poweroff your computer after starting your playlist, and take over control on your phone without losing the playlist.

There’s also a way to install a Spotify client in UpMPDCli, the DLNA renderer I talked previously about. It’s pretty convenient to mix songs from Spotify and my NAS, but it’s not exactly a recommanded way to stream from Spotify since it’s using the deprecated libspotify library, so I won’t detail it here.

--

--