28. April 2024

SBC als audio streaming client

In diesem Projekt erfährst du, wie du mit einem preisgünstigen SBC (BananaPi M2 Plus) einen einfachen audio streaming client aufbauen kannst der folgende Netzwerk Empfänger unterstützt:

Durch diese drei clients wird ein Großteil der Netzwerk Empfänger abgedeckt, welche aktuell weit verbreitet sind.

Apple AirPlay ermöglicht allen Apple Anhängern einen problemlosen Transfer der Audio Quelle auf dem iPhone/iPad/Mac, z.B. von Spotify, Amazon Music, Tidal oder Qobuz, über das WLAN zu dem Streaming Client. Die Einschränkung dabei, liegt in der begrenzten Bitrate und der Auflösung (44,1 kHz bei 16Bit Auflösung). Das entspricht der HiFi Qualität einer normalen Audio-CD und ist in den meisten Fällen völlig ausreichend.

Der Spotify Connect client ermöglicht zudem, das native Abspielen der Musik direkt über die Spotify App auf dem Handy (Apple/Android), als auch über die nativen Applikationen für die Betriebssysteme (MacOs/Windows/Linux) und über den Hauseigenen WebPlayer. Hier wird die Musik, je nach Einstellung, mit einer maximalen Bitrate von 320kbps bei einer Auflösung von 16Bit übertragen. Es zeichnet sich ab, dass Spotify zukünftig auch ein HiFi Abonnement im Angebot haben wird, in dem wohl auch lossless Audio (44,1 kHz / 16Bit) und UHD Flac Formate bis 192kHz/24Bit mit dabei seien werden. Wann es da soweit ist, steht momentan noch nicht fest. Sicher ist aber, dass die Mitbewerber (Amazon Music Unlimited, Tidal, Apple Music, Qobuz) bereits solche Formate im Programm haben und diese auch teilweise ohne Aufpreis streamen.

Um diese anderen Anbieter möglichst ohne Verluste durch erneute Konvertierung zu dem kleinen BananaPi streamen zu können, hilft hier der DLNA media renderer, der mittels der gmrender-resurrect Implementierung nachgerüstet wurde. Dies ermöglicht das Streamen von mp3/flac Dateien aus dem lokalen Netzwerk, z.B. von einem NAS oder vom USB stick, an der Fritz! Box.
Des Weiteren ermöglichen Apps wie z.B. mconnect Player (Apple/Android) oder Bubble UPnP(Android) das native Abspielen von Tidal oder auch Qobuz Music ohne neue Konvertierung auf dem DLNA Renderer.

Die Idee hinter diesem Projekt entstand nach dem letzten Umbau im Wohnzimmer. In einer Raumecke entstand ein kleine Rückzugsecke mit schönem Sessel und anschließendem High-board. In dieser „Relax“ Zone wollte ich ab und zu mit einem Kopfhörer und der passenden Musik entspannen. Ich hatte noch einen kleinen Kopfhörerverstärker von Pro-Ject (mit USB DAC) zur Hand und meinen unbenutzten Allwinner H3 SBC von BananaPi. Der USB DAC vom Kopfhörerverstärker versprach eine verlustfreie Weitergabe von digitalem Audiomaterial und der BananaPi hat sich als WLAN client angeboten.

Nun aber genug der Vorgeschichte. Hier eine Liste der benötigten Komponenten für den Aufbau des Netzwerk Audio Empfängers:

  1. Die Motivation sich mit der Kommandozeile von Linux zu beschäftigen
  2. Ein SBC mit Allwinner H3 Chip ( in meinem Fall ein BananaPi M2 Plus ). Andere Anbieter wie NanoPi oder OrangePi sollten es auch tun, soweit sie von Armbian unterstützt werden.
  3. Eine microSD Karte + Adapter für das Betriebssystem vom Netzwerkplayer
  4. Ein Browser deiner Wahl
  5. Ein Programm zum Übertragen der Image Datei auf die microSD Karte (balenaEtcher, win32 disk imager …)
  6. Ein Netzwerkanschluss für das 1. Einrichten des SBC
  7. Ein USB WLAN stick, falls das Board kein WLAN hat bzw. keine Antenne zur Hand ist
  8. Einen USB DAC als Kopfhörerverstärker, z.B. von Pro-Ject oder Douk Audio
  9. Einen Kopfhörer deiner Wahl, ich bin mit meinem Sennheiser HD599 sehr zufrieden

Wir gehen nun Schritt für Schritt die Anleitung durch:


Vorbereitung des Betriebssystems für den Single Board Computer

Für mein Projekt habe ich ein vorbereitetes Image von Armbian benutzt, bitte folge der Reihenfolge um einen reibungslosen Ablauf zu gewährleisten.

  1. Download des letzten Debian Images für den BananaPi M2 Plus ( in meinem Fall Bullseye )
  2. Kopieren des Betriebssystem-Images auf die microSD Karte ( in meinem Fall mit balenaEtcher )

Erstinbetriebnahme vom Single Board Computer

Nachdem der Flashvorgang über balenaEtcher beendet ist und die microSD Karte in den SBC eingesteckt wurde, erfolgt nun der Erststart des kleinen Streamers. Dazu muss der SBC zunächst mit dem LAN-port vom Router oder einem anderen Accesspoint verbunden werden. Nach dem Anschließen der Versorgungsspannung, fährt der kleine Rechner nun mit dem Armbian OS das erste mal hoch.

Nach ca. 2-3 Minuten ist das Linux soweit hochgefahren, um sich nun über einen SSH Terminal zu verbinden. Unter MacOs benutze ich hierfür direkt den ssh Befehl, gleiches gilt für Windows unter der Powershell.

Der neue Rechner sollte unter dem Namen „bananapim2plus“ im Netzwerk auftauchen. Da Armbian automatisch einen SSH server mitinstalliert, ist der Rechner über den Root-User „root“ und dem default Passwort „1234“ erreichbar:

Anmeldung am linux SSH server

Beim ersten Anmelden am SSH Server muss zunächst der authentication key local akzeptiert ( mit „yes“ bestätigen ), danach als Passwort „1234“ bestätigen werden.

Als erster Schritt wird nun zunächst ein neues „root“ – Passwort vergeben und im Anschluss noch ein lokaler Benutzer eingerichtet:

der Einfachheit halber bitte bash wählen
es muss noch ein lokaler Nutzer angelegt werden

Im Anschluss wird noch die Sprache und der Ort bestimmt und die Option 1 ausgewählt

1) de_DE.UTF-8
Spracheinstellungen auf deutsch wechseln

Das generieren der Locales kann etwas dauern. Nach erfolgreicher Erstellung kehren wir zum Prompt zurück

Hier sollten wir nun eine kleine update/upgrade Prozedur starten:

:~# apt update

Generell bitte nicht wundern, der kleine braucht seine Zeit 🙂

Nach dem erfolgreichen Beenden vom update Befehl, kommt vermutlich eine Meldung, dass „upgradeable“ Pakete da sind. Also führen wir jetzt noch das Upgrade durch:

:~# apt upgrade

Ein Fortschrittsbalken informiert über den Ablauf:

das upgrade läuft …

zum Abschluss der Ersteinrichtung führen wir nun, nach erfolgtem Upgrade, einen Neustart des Systems aus:

:~# shutdown -r now

Einrichten des WLAN

Bitte stecke den USB WLAN – Stick in einen freien Port vom BananaPi

Nach dem Neustart, dauert es wieder ca. 1-2 min. bis der Rechner für die Anmeldung bereit ist. Wir gehen wieder mit SSH auf den kleinen Rechner:

ACHTUNG !! neues Passwort

Nicht vergessen, das default Passwort „1234“ wurde geändert !

Nach erfolgreicher Anmeldung, begrüßt uns nun der kleine mit dem Login screen:

Willkommen im Armbian OS !

Um nun den WLAN Adapter konfigurieren zu können, stellt uns Armbian ein Werkzeug zur Verfügung, armbian-config. Mit diesem Tool lassen sich alle wichtigen Eigenschaften des SBC’s konfigurieren. Neben Netzwerk und Systemparametern können auch zusätzliche SW Pakete nach installiert werden. Für’s erste wollen wir uns nun aber mit der WLAN Konfiguration begnügen:

:~# armbian-config
Einstellung des WLAN Adapters

Wir wählen „Network“ und danach „WiFi“ aus:

WiFi settings

Hier nun bitte den entsprechenden SSID deines WLAN’s auswählen, mit dem richtigen Key aktivieren und im Anschluss über „Quit“ / „Back“ / „Exit“ das Konfigurationsprogramm beenden. Abschließend ein Reboot und das LAN Kabel ziehen ( Achtung, nicht anders herum 🙂 )

:~# shutdown -r now

Armbian OS auf das interne eMMC installieren

Für den BananaPi M2 Plus gibt es noch die Möglichkeit das gesamte System auf das interne eMMC flash auszulagern. Dies ermöglicht im Anschluss das Entfernen der microSD-Karte um sie für andere Zwecke zu nutzen. Die Installation wird über das Hauseigene Werkzeug „armbian-install“ erledigt:

:~# armbian-install
Auswahldialog für die unterschiedlichen Installationsoptionen

Damit alles unabhängig von der eingesteckten microSD Karte wird, wählt man die Option 2 aus.

Anschließend die Warnung bestätigen:

WARNING !!!
Filesystem Auswahl auf dem eMMC

Ich habe hier das althergebrachte ext4 gewählt.

Danach geht es für ca. 4 Minuten ans kopieren:

Zum Abschluss, das System herunterfahren und die microSD Karte entfernen. Nach erneutem Versorgungsspannungswechsel startet das System neu, aber diesmal komplett vom internen eMMC flash 🙂

Das war’s abschalten !

Installation der client Dienste für die Musikwiedergabe

Nun ist es soweit, die Vorarbeiten sind erledigt und der SBC wartet auf die richtigen Zutaten, um als Streaming client arbeiten zu können. Ich werde nun der Reihenfolge nach erklären, wie die folgenden Dienste installiert werden können:

  1. shairport-sync (Apple AirPlay)
  2. raspotify (Spotify Connect)
  3. gmrender-resurrect (DLNA renderer)

Je nachdem was du benötigst, kannst du dir einen oder mehrere von diesen Diensten installieren. Sie arbeiten unabhängig von einander.

Fangen wir nun mit dem Ersten an.

shairport-sync (Apple AirPlay)

auf GitHub ist das Projekt gehostet:
https://github.com/mikebrady/shairport-sync/blob/master/BUILD.md

In der Debian Distribution ist bereits ein Installationspaket für shairport-sync hinterlegt, welches man normalerweise einfach über „apt install shairport-sync“ installieren könnte, aber ich habe hier keine guten Erfahrungen gemacht. Die verlinkten Pakete sind nicht mehr die aktuellsten und in meinem Fall, konnte ich im Anschluss shairport-sync nicht überreden mit meinem externen USB-DAC zusammen zu arbeiten.

Besser ist es, wenn man die Build and Install Anleitung auf der GitHub Seite befolgt. Wenn die neuste Version von AirPlay gebaut werden soll, wird zusätzlich noch NQPTP benötig, welches das AirPlay 2 Timing ermöglicht.

Ich beschreibe hier nochmal den Ablauf der Installation in verkürzter Form, allerdings können sich mit neuen Versionen auch die Abläufe ändern. Wenn es also Fehlermeldungen gibt, bitte der Anleitung auf der GitHub Seite folgen

1. Installation der Build Umgebung und der benötigten Hilfslibraries:

:~# apt update
:~# apt upgrade # this is optional but recommended
:~# apt install --no-install-recommends build-essential git autoconf automake libtool \
    libpopt-dev libconfig-dev libasound2-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev \
    libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev uuid-dev libgcrypt-dev xxd

2. Installation von NQPTP

:~# cd ~
:~# git clone https://github.com/mikebrady/nqptp.git
:~# cd nqptp
:~# autoreconf -fi
:~# ./configure --with-systemd-startup
:~# make
:~# make install

2.1 Service enablen und starten

:~# systemctl enable nqptp
:~# systemctl start nqptp

3. Installation von shairport-sync

:~# cd ~
:~# git clone https://github.com/mikebrady/shairport-sync.git
:~# cd shairport-sync
:~# autoreconf -fi
:~# ./configure --sysconfdir=/etc --with-alsa \
    --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-airplay-2
:~# make
:~# make install

3.1 Service enablen und starten

:~# systemctl enable shairport-sync
:~# systemctl start shairport-sync

Danach sollte der AirPlay Receiver bereits über das iPhone / iPad / Mac sichtbar und auswählbar sein.

Bevor aber nun der Audiogenuss über den Kopfhörer starten kann, müssen noch drei Einstellungen in der shairport-sync verändert werden. Zum einen der angezeigte Name des AirPlay Receivers und zum anderen die ausgewählte Sound-Karte vom externen USB DAC und der Mixer control Name. Damit dies funktioniert, solltest du jetzt den externen Kopfhörerverstärker an den SBC anschließen.

Ihr könnt im Anschluss über die Abfrage von „aplay -l“ prüfen, wie diese neue externe Soundkarte heißt:

:~# aplay -l

In meinem Beispiel taucht der externe USB DAC hier als „card 1: Audio ….“ auf

Neben dem Namen der Soundkarte brauchen wir auch noch den Namen des Mixer Kontrollkanals, hierfür am besten über den „alsamixer“ auf die externe USB Soundkarte wechseln und unter dem Hauptkanal den Namen notieren ( in diesem Fall „Headphones“ )

mixer_control_name = „Headphones“

Diese Einstellungen werden wir nun der Konfigurationsdatei von shairport-sync zusammen mit einem selbst gewählten Service Namen anpassen. Ich benutze normalerweise „nano“ als editor für die Konfigurationsdateien, aber für diejenigen, die aus der Windows/Dos Welt kommen, wähle ich einen etwas vertrauteren Editor „mcedit“. Dieser Editor ist Teil von der Midnight Commander Applikation „mc“. Dies ist ein Klon des alt bekannten Norton Commander „NC“ ( Für die Leute mittleren Alters sollte das noch ein Begriff sein 🙂 ) und bereits Bestandteil von Armbian.

Starten wir also nun die Konfiguration des shairport-sync Dienstes ( /etc/shairport-sync.conf )

:~# mcedit /etc/shairport-sync.conf
mcedit nach dem öffnen der Konfigurationsdatei

Wer möchte kann noch gerne die Zeilennummern mit einschalten, dazu einmal <ALT> + <RECHTS> drücken um in das mcedit Menü zu kommen.

dann „Command“ / „Toggle line state“ auswählen und die Zeilennummern erscheinen 🙂

Auswahl Zeilennummern einschalten

in Zeile 9 kannst du nun den Anzeigenamen vom AirPlay Receiver anpassen. Achtung !! die Zeile ist standardmäßig auskommentiert, also bitte die beiden frontslashes am beginn der Zeile entfernen.

Weiter geht es mit der Einstellung der Soundkarte, weiter oben habe ich bereits mit dem Befehl „aplay -l“ herausgefunden, dass mein USB DAC als zweite Soundkarte erscheint ( „card 1: Audio …“ ). „hw:Audio“ ist hierbei der name der Soundkarte und den trage ich nun in Zeile 100 ( „output_device“ ) ein. In der nächsten Zeile noch den „mixer_control_name“ eintragen, für meinen USB-DAC hier „Headphones“.

Konfiguration output_device und mixer_control_name

Bei dir können sich die Namen natürlich unterscheiden, aber das hast du ja bei der Abfrage über „aplay -l“ und „alsamixer“ herausgefunden. Achtung ! Auch hier wieder daran denken, die beiden frontslashes am Anfang der Zeile zu entfernen.

Abschließend nun noch mit <F2> speichern und mit <F10> schließen.

Für einen ersten Testlauf machen wir nun wie gewohnt einen Reboot.

:~# shutdown -r now

Nun sollte auf dem iPhone / iPad / Mac der neu ausgewählte Name als AirPlay Receiver auftauchen und die Musik sollte endlich aus den Kopfhörern kommen 🙂

Damit ist die shairport-sync service Installation beendet. Für die Apple Nutzer unter uns kann jetzt hier abgebrochen werden es sein denn es sollen noch hochauflösende Formate ohne neu Konvertierung an den USB DAC gestreamt werden, dann muss noch der DLNA renderer installiert werden ( gmrender-resurrect )