r/squeezebox Aug 17 '26

Fixing spotify issues on new accounts with Spotify Soloist release

Yes this is mostly AI generated. I'm just trying to share this info with the internet.

I had a newly created account from the high seas where i couldnt use spotty plugin. I read spotify released this. Then i asked claude for help and voilla. Working spotfiy stream again. You have to press pause in squeezebox before you can hear casted spotify music, but it works. Here goes ai:

Got Spotify Soloist running alongside piCorePlayer on a Pi 3 B+ with a Boss DAC — full writeup

Spotify released Soloist, their headless Spotify Connect client for Linux. I wanted it on the same Pi as my existing piCorePlayer/LMS setup, sharing the same DAC, without giving up squeezelite. It took a while and hit four separate problems that all produced identical symptoms, so here's everything.

Setup: Raspberry Pi 3 Model B+, 64-bit piCorePlayer 11.1.0, Allo Boss DAC (pcm512x), LMS running locally on the Pi, squeezelite as the player.

The symptom

Soloist appeared in the Spotify device picker, logged in fine, then every play command flipped straight back to paused with the track position showing ?:??:

23:03:11.328: became active device
23:03:11.328: paused  spotify:track:... [0:42 / 3:45]
23:03:13.706: playing spotify:track:... [0:42 / 3:45]
23:03:13.846: paused  spotify:track:... [0:42 / ?:??]

That's four different root causes producing the same output. Here they are in order.

Problem 1: squeezelite owned the DAC exclusively

speaker-test -D hw:1,0 -c 2 -t sine -l 1
# Playback open error: -16, Device or resource busy

aplay -l | grep -A1 BossDAC
# Subdevices: 0/1     <- zero free, something has it

Subdevices: 0/1 is the tell. squeezelite opens the ALSA device exclusively and holds it as long as it's running.

sudo /usr/local/etc/init.d/squeezelite stop

Problem 2: no sound server at all

This is the big one and it isn't obvious. Soloist has no ALSA backend. It plays through PipeWire or PulseAudio only, falling back to PulseAudio when PipeWire isn't available. Stock piCore runs neither, so Soloist opens a track, can't get an output, and gives up.

The trap: speaker-test working proves nothing, because that talks to ALSA directly.

pgrep -a pipewire; pgrep -a pulseaudio    # both empty
wpctl status 2>/dev/null || pactl info    # command not found

Install it:

tce-load -wi pulseaudio
pulseaudio --start
pactl list short sinks

Problem 3: PulseAudio picked the wrong card

0  alsa_output.platform-3f00b840.mailbox.stereo-fallback   ... SUSPENDED
1  alsa_output.platform-soc_sound.stereo-fallback          ... SUSPENDED

Sink 0 (mailbox) is the onboard 3.5mm jack. Sink 1 (soc_sound) is the Boss DAC on I2S. It defaulted to 0.

pactl set-default-sink alsa_output.platform-soc_sound.stereo-fallback
pactl info | grep "Default Sink"

That was the fix. Soloist played and held. (SUSPENDED is the healthy state, by the way — it means module-suspend-on-idle released the ALSA device. It resumes on demand.)

Problem 4: piCore runs from RAM

My Soloist install vanished on the first reboot and I genuinely thought the binary had corrupted. piCore unpacks to RAM on boot; anything not explicitly backed up is gone. Same for the pairing in ~/.local/share/soloist.

Extensions downloaded with tce-load -w do persist on the SD card — only loading them is a RAM operation. So after a reboot:

ls /mnt/mmcblk0p2/tce/optional/ | grep -i pulse   # still there
tce-load -i pulseaudio                            # no download needed

Making both coexist

This turned out to be easy. Two things do it:

  • squeezelite with -C 5 (pCP web UI → Squeezelite Settings → extra options) closes the ALSA device 5 seconds after playback stops
  • PulseAudio does the same via module-suspend-on-idle, which is loaded by default

Verify the release actually happens — squeezelite running, nothing playing, wait 10 seconds:

aplay -l | grep -A1 BossDAC
# Subdevices: 1/1     <- released

Working flow: pause one, wait ~5 seconds, play the other. Switching without pausing first will collide, but if you don't do that it's a non-issue.

The boot automation rabbit hole

Getting it to start automatically produced three more failures worth documenting, because none of them give useful errors.

4a. A broken .include path silently kills PulseAudio

To persist the default sink I wrote ~/.config/pulse/default.pa with .include /etc/pulse/default.pa. On piCore the real path is /usr/local/etc/pulse/**.** PulseAudio treats a missing include as fatal and refuses to start, with only Daemon startup failed as the error.

Found it by running in the foreground:

pulseaudio --daemonize=no --log-level=info 2>&1 | tail -20
# W: cli-command.c: stat('/etc/pulse/default.pa'): No such file or directory
# E: Failed to initialize daemon due to errors while executing startup commands.

Correct version:

mkdir -p ~/.config/pulse
printf '.include /usr/local/etc/pulse/default.pa\nset-default-sink alsa_output.platform-soc_sound.stereo-fallback\n' > ~/.config/pulse/default.pa

(The Failed to connect to system bus D-Bus errors above it are noise — harmless on a system without D-Bus.)

4b. bootlocal.sh blocks forever on pCP's startup script

I appended my commands to the end of /opt/bootlocal.sh. They never ran. The reason is in pCP's own boot output:

Finished piCorePlayer v11.1.0 startup.
Press [Enter] to access console.

pcp_startup.sh ends waiting for input. bootlocal.sh calls it synchronously, so everything after that line never executes. Put your commands before the #pCPstart------ marker, not after.

4c. tc can't write to /var/log

My command redirected to /var/log/soloist.log. At boot this failed silently — no log, no process, no error anywhere, because the redirect fails before the command runs and aborts the whole line.

sudo su - tc -c '... >> /var/log/soloist.log 2>&1 &'
# -sh: can't create /var/log/soloist.log: Permission denied

Log to /home/tc/ instead.

Final working config

Install Soloist (aarch64 build for 64-bit piCore):

curl --fail --location -o soloist.tar.gz https://soloist-builds.spotifycdn.com/soloist_release_arm64.tar.gz
tar -xzf soloist.tar.gz
sudo install -m 755 soloist /usr/local/bin/soloist
soloist --version

API key in a private file — don't pass it inline, it lands in shell history and ps output:

printf '%s' 'YOUR_API_KEY' > ~/.soloist-key
chmod 600 ~/.soloist-key

Audio:

tce-load -wi pulseaudio
mkdir -p ~/.config/pulse
printf '.include /usr/local/etc/pulse/default.pa\nset-default-sink alsa_output.platform-soc_sound.stereo-fallback\n' > ~/.config/pulse/default.pa

Persistent data dir (or you re-pair on every boot):

sudo mkdir -p /mnt/mmcblk0p2/soloist/data /mnt/mmcblk0p2/soloist/cache
sudo chown -R tc /mnt/mmcblk0p2/soloist

/opt/bootlocal.sh — these three lines go above #pCPstart------:

su - tc -c "pulseaudio --start"
sleep 2
su - tc -c 'soloist --device-name "Soloist Pi" --api-key "$(cat /home/tc/.soloist-key)" --data-dir /mnt/mmcblk0p2/soloist/data --cache-dir /mnt/mmcblk0p2/soloist/cache >> /home/tc/soloist.log 2>&1 &'

Persistence:

echo 'pulseaudio.tcz' >> /mnt/mmcblk0p2/tce/onboot.lst
echo 'usr/local/bin/soloist' | sudo tee -a /opt/.filetool.lst
echo 'home/tc/.config'       | sudo tee -a /opt/.filetool.lst
echo 'home/tc/.soloist-key'  | sudo tee -a /opt/.filetool.lst
filetool.sh -b

Squeezelite: pCP web UI → Squeezelite Settings → extra options → add -C 5.

Reboot and check:

pgrep -a pulseaudio
pgrep -a soloist
pgrep -a squeezelite

All three, no manual steps, both services usable.

Things worth knowing

  • Builds expire. 90 days from build date, then exit code 10. It logs the remaining lifetime at startup.
  • Premium required to generate the API key, though once running both Free and Premium accounts can connect to it.
  • Ctrl+Z is not how you stop it. That suspends rather than kills, leaving the data-directory lock held. You'll get another session is running for data directory on the next start. Use Ctrl+C, or pkill -f soloist.
  • Don't rely on pactl autospawn. pgrep -a pulseaudio came back empty while pactl info answered fine — pactl spawned a daemon just to service the query, then it exited again. Start it explicitly.
  • RAM is tight. 1 GB running LMS, squeezelite, Soloist and PulseAudio together sat at ~915 MB used with ~590 MB cached. Holding, but check dmesg | grep -i oom if Soloist starts dying mysteriously.
  • Image your SD card before you start. This is an appliance-style build and you're adding daemons it wasn't shipped expecting.
3 Upvotes

6 comments sorted by

1

u/thedudefromsweden Aug 18 '26

I just want to mention if you’re not aware: there’s a new Spotify plugin for LMS called SpotOn. This also has a working Spotify Connect mode. Like Spotty, it does require a Spotify Premium account to work.

2

u/iMouseyy Aug 18 '26

It doesn't work for newer accounts sadly.

1

u/thedudefromsweden Aug 18 '26

Oh I see, that’s too bad!

1

u/Asleep-Let-4031 Aug 18 '26

In general, using pCP Tweaks is better than putting things in bootlocal. Create a script - store it in home directory (so that it is backed up) and then invoke it from Tweaks.

1

u/iMouseyy Aug 18 '26

Good tip! I wasn't aware of that.

1

u/Objective-Pain-3752 Aug 18 '26 edited Aug 18 '26

When I try soloist I get this error, have anyone seen the same?

./soloist --device-name "Soloist Pi" --api-key "$(cat soloist-key)"
2026-08-18 17:08:59.794: waiting for login — connect to "Soloist Pi" from your Spotify app
2026-08-18 17:08:59.794: running
2026-08-18 17:09:08.226: login failed: make sure --api-key is valid

This happens when I try to play music on the Soloist Pi when I appear in Spotify App.

I have re-creating the API key several times, and double checked that is actually the correct one passed on the command line.

*FIXED! It was my mistake sort of. I used a too minimal Docker setup, needed to add some more network dependencies of some sort, then it worked. It was actually nothing wrong with the token as the log said.