PC, ♫ and much more ;)

Raspberry Pi: Webradio extended-Edition

Ein Webradio der besonderen Art…


Unser Ziel:

  • Das Raspberry Pi kann Webradios wiedergeben.
  • Unser Radio ist via Webinterface erreichbar, welches folgende Funktionen bietet:
    • Lautstärke ändern
    • Senderwechsel
    • Aktuellen Sender und falls Musik abgespielt wird den aktuelle Titel und den Interpreten anzeigen.

Erweiterungen (Optional):

  • Das Raspberry Pi verkündet bei jedem Start seine aktuelle IP via Text-to-speech
  • AirPlay-Geräte können via Raspi streamen.
  • Das Webinterface kann mit einem Passwort geschützt werden. Zusätzlich ist es via SSL erreichbar.

Voraussetzungen:

  • 1 Raspberry Pi (Egal welches Modell)
  • Installiertes Raspbian mit SSH Zugriff

Diese Anleitung ist in 5 Kapitel eingeteilt:

  1. Webradio unter Raspbian
  2. Webinterface
  3. Text-to speech
  4. AirPlay
  5. Sicherheit

Kapitel 1: Webradio unter Raspbian

Bevor wir die benötigten Pakete installieren, führen wir folgenden Befehl aus:

sudo apt-get update && sudo apt-get upgrade

Damit werden alle schon installierten Pakete auf den aktuellen Stand gebracht.

Nun installieren wir die Pakete MPD, MPC und ALSA-UTILS:

sudo apt-get install mpd mpc alsa-utils

Der „Kern“ unseres Internetradios ist nun lauffähig. Nun müssen wir aber noch etwas zum Abspielen haben!

Dazu erstellen wir uns eine Playlist:

sudo nano /var/lib/mpd/playlists/sender.m3u

Hier schmeissen wir nun alle URLs zu den Streams unserer Lieblingssender rein. Wichtig: Es darf kein Link zu einer .m3u Datei sein. Solltest du nur einen .m3u Link finden, lade die Datei herunter und öffne sie mit Notepad++ und kopiere die in der Datei enthaltene URL in das Putty Fenster.

Nun sollte die Datei in etwa so aussehen:

http://stream.srg-ssr.ch/m/regi_be_fr_vs/mp3_128
http://stream.srg-ssr.ch/m/drs2/mp3_128
http://stream.srg-ssr.ch/m/drs3/mp3_128
http://stream.srg-ssr.ch/m/drs4news/mp3_128
http://stream.srg-ssr.ch/m/rsp/mp3_128
http://listen.housetime.fm/tunein-aacplus-pls
http://ice33.infomaniak.ch:8000/neo1
http://stream.radio32.ch/radio32

Mit

mpc load sender

laden wir die Playlist in den Player. Wichtig: Diesen Befehl nur einmal ausführen! MPC leert seine Playlist nicht automatisch => Die Playlist wird doppelt geladen. Falls du sie neu laden möchtest, führe zuerst mpc clear aus.

Mit

mpc play

spielen wir unsere Playlist ab. MPC nummeriert die Titel. Das heisst: wenn wir HouseTime FM hören wollen, nutzen wir den Befehl

mpc play 6

Tipp: Weitere Befehle findest du unter dem Befehl man mpc! Es lohnt sich! 🙂


Kapitel 2: Webinterface

Für das Webinterface benötigen wir einen Webserver. Für unsere Zwecke reicht Apache 2, wer etwas Leistungsfähigeres sucht, darf sich an NGINX versuchen!

Falls du bereits einen Webserver auf deinem Raspberry Pi installiert hast, überspringe den folgenden Befehl.

sudo apt-get install apache2 php5

Jetzt können wir mit dem Erstellen des Webinterfaces loslegen!

Dazu wechseln wir in das Verzeichnis des Webservers

cd /var/www/html/

und löschen die vorhandene index.html

sudo rm index.html

Nun gibt es zwei Varianten: Entweder du erstellst selbst eine Seite mit HTML und CSS (die coole Variante) oder du lädst ein fertiges HTML-Template herunter und baust das zum Webinterface um.
(Die langweilige & uncoole Variante..)

Hier noch ein paar Tipps für die wirklich coole Variante:

  1. Weniger ist mehr. Ein simples Design erleichtert die Bedienung enorm, und wirkt aufgeräumt.
  2. Symbole? Font Awesome!
  3. Du wirst das Radio meistens via Handy bedienen. Ein gut festgelegter Viewport ist deshalb empfehlenswert!

Falls du dich für die langweilige & uncoole Variante entschieden hast, empfehle ich dir das „Aerial“ Template von HTML5 UP. Es sieht nicht nur cool aus, sondern ist auch für mobile Geräte optimiert, was falls du das Radio per Handy steuern möchtest Gold wert ist. Lade es mit wget herunter und entpacke es.

sudo wget http://html5up.net/aerial/download && sudo unzip download && sudo rm download

Wenn du nun http://[IP_RASPBERRYPI]/ in deinem Browser öffnest, Solltest du folgendes sehen:

webinterface_template

Damit lässt es sich doch arbeiten, oder?

Das Design haben wir also schon einmal fertig. Jetzt müssen wir es noch anpassen, damit aus dieser Website ein Webinterface wird.

Wir werden PHP verwenden. Deshalb benennen wir die index.html in index.php um.

sudo mv index.html index.php

Bevor wir diese bearbeiten, erstellen wir noch einige andere Dateien, welche danach die Befehle ausführen:

sudo nano play.php

Inhalt der Datei play.php:

<?php
shell_exec('mpc play');
header('Location: /index.php');
?>

sudo nano stop.php

Inhalt der Datei stop.php:

<?php
shell_exec('mpc stop');
header('Location: /index.php');
?>

sudo nano prev.php

Inhalt der Datei prev.php:

<?php
sleep(2);
shell_exec('mpc prev');
header('Location: /index.php');
?>

sudo nano next.php

Inhalt der Datei next.php:

<?php
sleep(2);
shell_exec('mpc next');
header('Location: /index.php');
?>

sudo nano volume-down.php

Inhalt der Datei volume-down.php:

<?php
shell_exec('mpc volume -10');
header('Location: /index.php');
?>

sudo nano volume-up.php

Inhalt der Datei volume-up.php:

<?php
shell_exec('mpc volume +10');
header('Location: /index.php');
?>

Wenn du jetzt im Browser http://[IP_RASPBERRYPI]/play.php öffnest, kannst du den Stream beginnen, und mit http://[IP_RASPBERRYPI]/stop.php wieder anhalten. Yay!

Jetzt passen wir die Datei index.php an:

sudo nano index.php

Unsere Aufmerksamkeit lenken wir auf den Inhalt des <ul> Tags: Hier sind alle Links, welche im Aerial Template später als Knöpfe dargestellt werden, aufgelistet. Da der Ersteller des Templates die FontAwesome für die Knöpfe benutzt, können wir diese ganz leicht anpassen:

  1. Öffne fortawesome.github.io/Font-Awesome/icons/
  2. Suche dir dort das Icon aus, welches am besten zur Funktion, welche du aufrufen willst, passt
  3. Füge den Namen des Icons in den <a> Tag des Links zur Funktion ein.
fa-play

Wiederhole dies mit allen Knöpfen. Am Schluss sollte der <ul> Tag in deiner index.php Seite etwa so aussehen:

index_done_v3

Und wenn du die Seite im Browser öffnest so:

webinterface_remote

Das Webinterface ist nun fast fertig!

In den PHP Dateien haben wir ja mit shell_exec() Befehle ausgeführt. Die Ausgabe dieser Befehle können wir in Variablen speichern => Auf unserer Website anzeigen.

Damit das funktioniert, bauen wir folgenden Code in die index.php ein:

<!-- aktueller Sender -->
<?php
sleep( 1 );
$Status = shell_exec('mpc current');
$Song = shell_exec('mpc --format [%title%] | head -n 1');
$Sender = shell_exec('mpc --format "[%name%]" | head -n 1');
?>
<!-- /aktueller Sender -->

Wichtig: Dieser Codeabschnitt muss über dem <p> Tag stehen!

Nun ersetzen wir den Inhalt des <p> Tags mit

<?php
if ($Status == '')
echo "Im Moment ist kein Sender aktiv.";
else
echo "$Song  &nbsp;&bull;&nbsp;  $Sender";
?>

Nun passen wir noch den <title> und den <h1> Tag an, danach sieht die Seite so aus:

web_off

Info: Nicht alle Sender senden den Songtitel & Sendernamen.


Kapitel 3: Text-to-speech

Damit du nicht jedesmal, wenn du in einem anderen Netz bist (z.B. in den Ferien), das ganze Netz scannen musst, um die IP des Raspberry Pis herauszufinden, werden wir ihn so konfigurieren, dass er bei jedem Start seine aktuelle IP-Adresse „vorliest“.

Das Paket ALSA-UTILS welches wir dafür benötigen sollte jetzt bereits installiert sein. Deshalb können wir direkt mit der Konfiguration beginnen!

Als erstes müssen wir das Kernelmodul snd_bcm2835 in den Kernel einbinden. Dazu öffnen wir die Datei /etc/modules

sudo nano /etc/modules

und fügen am Ende

snd_bcm2835

ein. Ist snd_bcm2835 bereits vorhanden, kannst du diesen Schritt überspringen.

Danach müssen wir noch MPlayer und Festival installieren:

sudo apt-get install mplayer festival

Am Schluss starten wir das Raspberry Pi neu:

sudo reboot

Jetzt testen wir, ob es funktioniert:

echo „The flying smartlearn SSD is so fast!“ | festival –tts

Nachdem uns das Raspi von der enormen Geschwindigkeit der fliegenden SmartLearn-SSD überzeugt hat, basteln wir uns ein Shellskript, welches die Internetkonnektivität überprüft und ggf. die IP via TTS ausgibt. Da es in Raspbian bereits ein Skript gibt, welches beim Systemstart die IP anzeigt, fügen wir unser Skript einfach dort hinzu:

sudo nano /etc/rc.local

Ersetze den Inhalt der Datei /etc/rc.local mit:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %sn" "$_IP"
echo "Hello User! My IP-Adress is $_IP" | festival --tts
else
echo "I'm sorry, but I can't connect to the internet!" | festival --tts
fi

exit 0

Nach einem

sudo reboot

Wird nun die IP verkündet. Falls kein Netz vorhanden ist, wird auch das gemeldet.

Falls du auch bei bestehender Verbindung die Meldung „I’m sorry, but I can’t connect to the internet!“ hörst, stelle sicher, dass in sudo raspi-config die Funktion „4 Wait for Network at Boot“ aktiviert ist.


Kapitel 4: AirPlay

Um das Raspberry Pi AirPlayfähig zu machen, müssen wir einige Pakete installieren:

sudo apt-get install libssl-dev libavahi-client-dev libasound2-dev avahi-daemon

Danach klonen wir shairport ins /tmp Verzeichnis, kompilieren und installieren es.

cd /tmp
git clone https://github.com/abrasive/shairport.git
cd shairport
./configure
make
sudo make install

Damit Shairport automatisch beim Systemstart geladen wird, kopieren wir nun die Konfigurationsdateien:

sudo cp scripts/debian/init.d/shairport /etc/init.d/
sudo cp scripts/debian/default/shairport /etc/default/

Jetzt bearbeiten wir die Konfigurationsdatei:

sudo nano /etc/default/shairport

Lösche alle # welche unten gelöscht sind, und setze den AP_NAME. Du darfst ihn so benennen, wie du willst. Zudem musst du noch die Gruppe nogroup setzen.

# User and group under which shairport should be run
# user should have permission to output sound
# Check the audio output documentation for details.
USER=pi
GROUP=nogroup
...
# Set the AirPlay advertised name.
# Defaults to computer's hostname
AP_NAME=RaspiRadio
...
# Force the mDNS backend
# By default, shairport will try all backends until one works.
# Check 'shairport -h' for details
MDNS=avahi

Nun übernehmen wir diese Einstellungen mit

sudo update-rc.d shairport defaults

und starten den ShairPort:

sudo service shairport start

Der ShairPort startet sich bei jedem Systemstart automatisch.


Kapitel 5: Sicherheit

Auch bei unserem Radioprojekt sollten wir die Sicherheit nicht vergessen.

Wir werden unser Webinterface verschlüsseln, damit nicht jeder unsere Daten mitlesen kann.

Dazu müssen wir zuerst einen Private-Key erstellen:

sudo -i

openssl genrsa -out /etc/ssl/private/apache.key 2048

Nun generieren wir ein selbstsigniertes SSL Zertifikat, welches 365 Tage gültig ist:

openssl req -new -x509 -key /etc/ssl/private/apache.key -days 365 -sha256 -out /etc/ssl/certs/apache.crt

Du wirst aufgefordert, persönliche Informationen anzugeben. Nachdem du diese eingegeben hast, schliesse danach das Pseudo-Root-Terminal mit

exit

Jetzt aktivieren wir das SSL Modul und starten Apache 2 neu.

sudo a2enmod ssl
sudo service apache2 force-reload

Ist dies geschehen, erstellen wir einen neuen Virtual Host. Dazu erstellen wir die Datei /etc/apache2/sites-available/ssl.conf

sudo nano /etc/apache2/sites-available/ssl.conf

und fügen folgende Konfiguration ein:

<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache.crt
SSLCertificateKeyFile /etc/ssl/private/apache.key

# Pfad zum Webinterface
DocumentRoot /var/www/html/
</VirtualHost>

Danach aktivieren wir diesen Vhost mit

sudo a2ensite ssl.conf
sudo service apache2 force-reload

Et voilà: Das Webinterface ist verschlüsselt unter https://[IP_RASPBERRYPI] erreichbar!

Damit nicht jeder unser Radio steuern kann, schützen wir das Webinterface mit einem Passwort.

Zuerst erstellen wir ein Passwort für den Benutzer tux:

sudo mkdir /etc/htpasswd

sudo htpasswd -c /etc/htpasswd/.htpasswd tux

Dieses müssen wir zwei Mal bestätigen.

Nun bearbeiten wir die Apache2 Konfiguration:

sudo nano /etc/apache2/apache2.conf

Ersetze den Inhalt des Tags <Directory /var/www/> mit

Options Indexes FollowSymLinks
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/htpasswd/.htpasswd"
Require valid-user
AllowOverride all
Order allow,deny
Allow from all

Wenn du jetzt https://[IP_RASPBERRYPI] öffnest, musst du dich anmelden. Falls du weitere Benutzer hinzufügen möchtest, kannst du das mit

sudo htpasswd /etc/htpasswd/.htpasswd DEINBENUTZERNAME

erledigen.

Hinweis: Wenn du das Webinterface nicht via https sondern via http öffnest, wird das Passwort unverschlüsselt übertragen!

5 Kommentare

  1. Olli

    Hi, ich komme beim besten willen nicht weiter beim Einbinden der beiden Codeabschnitte in die Index.php. Kenne mich nicht wirklich aus, wie soll das später aussehen? Danke…

    • Fabian

      Hi Olli

      Leider wurden gewisse Codesnippets durch mein CMS zerschossen, vermutlich bist du da dran gescheitert.
      Ich habe die Fehler nun behoben. (An dieser Stelle noch ein grosses Danke an Pieter, der mich auf diese Fehler hingewiesen hat!)

  2. Pieter van der Wolk

    Works like a charm; Thanks! I’m now listening to Swiss web radio (which strains my German comprehension).

  3. Chriss

    Hallo,

    bislang habe ich noch zwei Probleme, bei denen ich nicht weiterkomme, aktuell…
    1) Wenn ich mehr als ein Stream in der playlist habe, wird nichts abgespielt.
    2) Egal welche Funktion ich ansteuere aus der Webseite, ich bekomme immer folgende Meldung und nichts passiert :

    Was habe ich überlesen ?

    Ich würde mich über eine Antwort sehr freuen 🙂

    Danke und Grüße
    Chriss

    • Peter K

      Probieren sie das commandp „mpc play 1“ oder „mpc play 2“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

© 2020 Fabian Flückiger

Theme von Anders NorénHoch ↑