Lokales Multiroom-Audio Part 2 - Wechsel zu Snapcast

Bisher hatte ich für das lokale Multiroom-Audio-Setup Lyrion Music Server im Einsatz. Grundsätzlich funktioniert das - es gibt allerdings einige Punkte, die mich stören.

Was mir fehlt bzw. was mich stört

Spotify Connect

Das Lyrion-Plugin für Spotify hatte ursprünglich Unterstützung für Spotify Connect, auch wenn das schon immer eher hakelig war und schnell die Verbindung verloren hat. Dieses Feature musste der Entwickler vom Plugin allerdings irgendwann entfernen, seit dem ist die Wiedergabe nur noch über LMS selbst möglich. Auf diesem Weg lässt sich zwar immer noch Musik von Spotify wiedergeben, trotzdem ist es deutlich schneller und angenehmer, einfach von der Spotify-App aus das Audio-Setup als Ziel auswählen zu können. Dieser Umweg hat auch dafür gesorgt, dass meine Partnerin das Soundsystem alleine ungefähr nie benutzt.

Synchronisierung

Die Synchronisierung von Lautsprechern funktioniert generell gut. Bei Verbindungsproblemen wird bei LMS allerdings die Wiedergabe auf allen Lautsprechern kurz unterbrochen. Snapcast lässt alle anderen Lautsprecher weiterlaufen, der Lautsprecher mit Verbindungsproblemen synchronisiert sich dann selbst wieder zum Rest. Die Aussetzer betreffen also nur den Player, der die Verbindungsprobleme hat.

Zu viele Features

Wir brauchen zuhause eigentlich nur Spotify Connect. Lyrion bringt ein eigenes WebUI inkl. Verwaltungsmöglichkeiten für eine eigene Mediathek mit, das brauchen wir nicht. Snapcast ist insgesamt spürbar schlanker und braucht weniger Ressourcen.

Das neue Setup

Bisher hatte ich bei den drei Playern jeweils piCorePlayer im Einsatz, das ist eine minimalistische Linux-Distribution speziell für die Nutzung eines Raspberry Pis für Squeezelite bzw. Lyrion Music Server. LMS selbst lief in Docker in einem LXC, mit einer Squeezelite-Instanz daneben für lokale Wiedergabe.

Server

Der Server ist ein Debian 13 mit installiertem snapserver. Librespot für Spotify Connect habe ich aus den Quellen selbst kompiliert, um eine möglichst neue Version zu haben. Ich habe zusätzlich noch snapweb installiert, das ist ein moderner Webclient für Snapserver, der vor allem Gruppierung und Lautstärkeregelung ermöglicht und für Mobilgeräte optimiert ist. Damit entfällt die Notwendigkeit einer eigenen App für die Steuerung.

Meine Konfiguration sieht wie folgt aus (/etc/snapserver.conf):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[server]

[http]
enabled = true
doc_root = /usr/share/snapweb # for snapweb

[tcp-control]
enabled = true

[stream]
source = pipe:///tmp/snapfifo?name=default
source = librespot:///librespot?name=Spotify%201&devicename=Home%201&bitrate=320&volume=90
source = librespot:///librespot?name=Spotify%202&devicename=Home%202&bitrate=320&volume=90

[streaming_client]
initial_volume = 80

Die Config ist generell sehr minimal gehalten. Für Spotify Connect habe ich zwei Quellen definiert, damit beispielsweise ich im Arbeitszimmer und meine Freundin im Wohnzimmer verschiedene Musik hören können.

Clients

Thin-Clients

Im Arbeitszimmer stehen an beiden Arbeitsplätzen Lautsprecher, diese sind mit je einem meiner Thin-Clients (Futro S740) verbunden. Der eine snapclient läuft im selben LXC wie der Server, ich habe die Audiogeräte dafür durchgereicht. Für den zweiten läuft ein weiterer LXC, der eigentlich nur snapclient installiert hat.

Die Config (/etc/defaults/snapclient):

1
SNAPCLIENT_OPTS="--hostID arbeitszimmer-1 --soundcard hw:CARD=PCH,DEV=0 tcp://[Snapserver-IP]"

Raspberry Pis

Hier bin ich einen anderen Weg gegangen als vorher. Alle drei Pis haben Raspberry Pi OS Lite bekommen, also die Variante ohne GUI.

Auch hier ist Snapclient installiert, die Config sieht minimal anders aus (/etc/defaults/snapclient):

1
SNAPCLIENT_OPTS="--soundcard plug:plugequal --hostID wohnzimmer tcp://[Snapserver-IP]"

Das Zielgerät ist hier ein virtuelles Gerät von Alsa, um über den Equalizer Korrekturen vornehhmen zu können.

Daher sieht die Konfiguration für Alsa so aus (/etc/asound.conf):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ctl.equal {
  type equal;
}

pcm.plugequal {
  type equal;
  slave.pcm "plughw:CARD=Audio,DEV=0"
}

pcm.equal {
    type plug;
    slave.pcm plugequal;
}

Die Steuerung vom Equalizer ist via sudo -u snapclient alsamixer -D equal möglich.

Relais für Verstärker

An zwei Pis hängt an den GPIOs jeweils ein Relais, was einen Verstärker steuert. piCorePlayer hatte native Unterstützung dafür, dort musste ich nur den GPIO-Pin einstellen. Für Snapcast brauchte ich eine eigene Lösung.

Das Ergebnis ist ein kleines Script, was in Dauerschleife prüft, ob auf einer Soundkarte Audio abgespielt wird und darüber einen GPIO-Output steuert.

Das Script liegt bei mir unter /usr/local/bin/amp-control.sh.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash

GPIO=14

CHECK_INTERVAL=2
POWER_ON_DELAY=3
IDLE_TIMEOUT=30

amp_on=0
last_audio=0
audio_detected=0

pinctrl set $GPIO op
pinctrl set $GPIO dl

while true; do

    if grep -q RUNNING /proc/asound/card*/pcm*/sub*/status; then
        audio_detected=1
        last_audio=$(date +%s)
    else
        audio_detected=0
    fi

    now=$(date +%s)

    # Amp einschalten
    if [[ $audio_detected -eq 1 && $amp_on -eq 0 ]]; then
        pinctrl set $GPIO dh
        amp_on=1
        sleep $POWER_ON_DELAY
    fi

    # Amp ausschalten
    if [[ $amp_on -eq 1 && $((now-last_audio)) -gt $IDLE_TIMEOUT ]]; then
        pinctrl set $GPIO dl
        amp_on=0
    fi

    sleep $CHECK_INTERVAL

done

Dazu gehört natürlich dann auch ein Systemd-Service, damit das ganze beim Systemstart mitstartet. Der Service liegt unter /etc/systemd/system/amp-control.service.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Unit]
Description=Snapclient Amp Control
After=snapclient.service

[Service]
ExecStart=/usr/local/bin/amp-control.sh
Restart=always

[Install]
WantedBy=multi-user.target
Read-Only-Root

Nach der fertigen Konfiguration habe ich die SD-Karte via overlayfs als Read-Only gemoutet, damit das System das Trennen vom Strom problemlos übersteht. Das geht einfach via raspi-config.

Fazit

Ich habe Snapcast jetzt seit wenigen Wochen im Einsatz, bisher bin ich zufrieden damit. Nach dem initialen Setup musste ich mich nicht mehr darum kümmern, Spotify Connect läuft auch sehr zuverlässig damit.