Piradio Streamingbox

Die Idee der Piradio Streamingbox

Die Piradio Streamingbox soll ein Audiosignal in einer Qualität, die für Radiosendungen ausreichend ist, von einem Ort zum anderen übertragen. Sie dient also zur Live-Übertragung von Radiosendungen, kann aber natürlich auch als Live-Stream für Veranstaltungen oder für das Übertragen von Vogelgezwitscher aus dem Baumhaus (mit Internetanschluss) genutzt werden. Gleich zur Warnung vorweg: die gute Tonqualität muss man mit einer vergleichweise langen Verzögerungszeit bezahlen. Vom Hineinsprechen bis zur Ausgabe auf dem entfernten Computer können bis zu 10 Sekunden vergehen. Wenn es auf eine Latenzzeit arme Übertragung eines Audiosignals ankommt und weniger auf die Qualität, dann ist eine Telefonverbindung möglicherweise die bessere Wahl.

Zu ISDN-Zeiten gab es für die Tonübertragung ein technisches Gerät namens „Music Taxi“, für das während der Übertragung zwei ISDN-Leitungen blockiert waren und das in der Anschaffung und den laufenden Telefonkosten unglaublich teuer war. Im Zeiten des schnellen Internets sollte die gleiche Aufgabe viel billiger und einfacher realisierbar sein. Die Kiste soll einen Live-Audio-Stream erzeugen, ohne viele Bedienelemente auskommen, geräuschlos, sicher vor Fehlbedienung und vor allem auch billig sein. Weil der Radiosender für den ich diese Streamingbox brauche, Piradio heißt, liegt es nahe, als Hardware-Plattform einen Raspberry Pi zu wählen. Und so kam die Idee zu einer Raspberry Piradio Streamingbox oder kurz Piradio Streamingbox. Ein ähnliches Projekt für den Raspberry Pi wird auf der Website von Soundtent.org beschrieben. Ich habe die von Soundtent geschriebenen Skripte auseinander genommen, weiterentwickelt und die Box noch komfortabler gestaltet. Insofern kann die Piradio Streamingbox als Fortsetzung der Soundtent Box verstanden werden.

Prinzipiell lässt sich die Box natürlich auch mit einer anderen Hardware realisieren. Billiger als ein Raspberry Pi mit dem ganzen Zubehör (Steckernetzteil, Gehäuse, Audiokarte, WLAN-Stick) ist tatsächlich ein gebrauchter Thin-Client-Computer. Solche kleinen, lüfterlosen Computer mit Intel-CPU gibt es schon ab 20 Euro zu kaufen. Aber das ist ein anderes Projekt, das ich vielleicht einmal wann anders vorstelle.

Alle Dateien, die hier vorgestellt werden sowie ein SD-Karten-Image einer Komplettinstallation (für die eiligen Leser), werden ganz unten beim Download verlinkt.

Installation des Betriebssystems

Als erstes muss der Raspberry Pi zum Laufen gebracht werden. Ich selbst hatte noch ein altes Modell B in der Schublade, das auf eine sinnvolle Anwendung gewartet hat. Natürlich funktioniert die Piradio Streamingbox auch mit einer neueren Version des Raspberry Pi. Mit einem RPi Zero W kann man das auch sehr platzsparend realisieren. Lade eine aktuelle Version des Raspbian Betriebssystem in der schlanken Version ohne grafische Benutzeroberfläche herunter (Jessie Lite). https://www.raspberrypi.org/downloads/raspbian/

Installiere das Betriebssystem auf einer leeren SD-Karte. Eine ausführliche Anleitung für Linux (und andere Betriebssysteme) liegt z.B. hier: https://www.raspberrypi.org/documentation/installation/installing-images/linux.md. Hier ist die Kurzfassung davon, wie die Installation mit Hilfe eines Linux-Rechners durchgeführt werden kann:

  • Stecke eine leere SD-Karte (mindestens 2 GByte) in den Linux-Rechner
  • Öffne ein Terminal-Fenster
  • Wechsele in den Ordner, in dem das Raspbian-Image als img-Datei liegt
  • Suche die Bezeichnung der SD-Karte mit dem Befehl df -h
  • Hänge die SD-Karte mit umount aus
  • Kopiere das Image mit sudo dd auf die SD-Karte, wobei die Partitionsnummer (in meinem Fall die 1 von /dev/sdb1) weggelassen werden muss.

Achtung! Wer das zum ersten mal macht, sollte lieber die ausführliche Anleitung anschauen. Sonst ist schnell die eigentliche System-Festplatte überschrieben.

So sieht das Terminal-Fenster ungefähr bei mir aus (die Bildschirmausgabe ist gekürzt):

$ df -h
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
 /dev/sda1       455G     69G  363G   16% /
 /dev/sdb1        15G     32K   15G    1% /media/ubuntu/3232-3361
$ umount /dev/sdb1
$ sudo dd bs=4M if=2017-04-10-raspbian-jessie-lite.img of=/dev/sdb
 1297862656 Bytes (1,3 GB) kopiert, 82,9348 s, 15,6 MB/s

Nachdem die SD-Karte fertig geschrieben ist, stecke sie aus, setze sie beim Raspberry Pi ein und starte den Minirechner mit einem externen Bildschirm, Tastatur und LAN-Kabel.

Der Default-Login lautet:

  • Benutzername: pi
  • Passwort: raspberry

Achtung! Die Default-Tastatur hat ein englisches Tastaturlayout. Das y ist dort mit dem z vertauscht. Die Passworteingabe muss daher sein:

  • raspberrz

Systemeinstellungen für das Betriebssystem

Bevor der Raspberry Pi voll einsatzfähig ist, müssen noch ein paar Systemeinstellungen vorgenommen werden. Dazu gibt man über die externe Tastatur ein:

 $ sudo raspi-config
  • Ändere das Login-Passwort
  • Stelle die Standorteinstellung auf de_DE.UTF-8 (Localisation Options -> Change Locale)
  • Wähle ein passendes (deutsches) Keyboard-Layout (Localisation Options -> Change Keyboard Layout)
  • Erlaube den SSH-Zugriff (Interfacing options -> SSH). Erst danach kann man den Rechner über SSH und SFTP von außen bedienen
  • Erweitere das Dateisystem auf die komplette SD-Karte (Advanced options -> Expand filesystem)
  • Danach rebooten

Auf den folgenden Bildern werden ein paar der raspi-config Bildschirme gezeigt, durch die man sich durch klicken muss.

Installation der Streaming-Software

Damit man all die jetzt gleich erstellten Dateien auf den Raspberry übertragen kann, ist es einfacher, sich per SSH von einem anderen Rechner aus einzuloggen. Man öffnet also beispielsweise auf einem Linux-Rechner ein Terminal-Fenster und verbindet sich mit dem Raspberry Pi mit:

$ ssh pi@raspberrypi 

Die Streaming-Software, die installiert werden soll, heißt Darkice. Sie ist dafür da, das Signal der Soundkarte abzunehmen und einen mp3- oder ogg-komprimierten Live-Stream über das Internet zu einem externen Streaming-Server zu senden. Der von Darkice erzeugte Stream kann also nicht direkt Punkt-zu-Punkt-mäßig empfangen werden, sondern es ist immer ein Streaming-Server (ShoutCast, IceCast, oder Darwin Streaming Server) dazwischen geschaltet, bevor der Stream wieder zu einem Audio-Player (z.B. VLC, SMPlayer, Audacious) bzw. im einfachsten Fall zu einem Webbrowser geschickt wird. Der Streaming-Server kann sich auch im Heimnetzwerk befinden, damit der Live-Stream nicht durchs ganze Internet geschickt werden muss. Darkice wird wie folgt installiert:

$ sudo apt-get update 
$ sudo apt-get install darkice

Nach der Installation liegt unter /usr/share/doc/darkice/examples/darkice.cfg.gz eine Konfigurationsdatei als Beispiel. Wir legen jedoch eine neue Konfigurationsdatei in dem neu erstellten Ordner /home/pi/piradio/stream_config/ mit dem Namen stream_configuration.cfg an.

$ cd /home/pi
$ mkdir recordings
$ mkdir piradio
$ cd piradio
$ mkdir stream_config
$ cd stream_config
$ nano stream_configuration.cfg

Nach dem Starten des Editors nano kann entweder die nachfolgende Konfigurationsdatei abtippen, oder – sofern man per SSH von einem anderen Rechner aus auf den Raspberry Pi zugreift, diese aus der Zwischenablage mit Shift-Einfg einfügen. Noch einfacher ist es, vom anderen Rechner aus einen Filebrowser zu öffnen und den Raspberry Pi mit sftp://pi@raspberrypi aufzurufen. Dann kann man die Dateien auch mit einer grafischen Benutzeroberfläche erstellen bzw. kopieren.

Zu Testzwecken habe ich hier die Konfigurationsdatei für den Streaming-Server eines Live Worldwide Open Microphones Projektes (//locusonus.org/soundmap/040/) angegeben. Wer einen anderen Streaming-Server nutzen möchte, beispielsweise einen Icecast-Server im eigenen Netzwerk, trägt hier andere Zugangsdaten ein.

#  DarkIce configuration file template for a connection to Locus Sonus; edit as needed; info@soundtent.org for support
# see the darkice.cfg man page for details - //manpages.ubuntu.com/manpages/intrepid/man5/darkice.cfg.5.html


#############################################################
# LOCUS REVEIL: DARKICE CONFIG FOR MONO OR STEREO STREAMING #
#############################################################


# this section describes general aspects of the live streaming session

[general]
duration        = 0         # duration of encoding, in seconds. 0 means forever
bufferSecs      = 5         # size of internal slip buffer, in seconds
reconnect       = yes       # reconnect to the server(s) if disconnected

# this section describes the audio input that will be streamed 
[input]
device          = plughw:1,0    # OSS DSP soundcard device for the audio input
sampleRate      = 44100        # sample rate in Hz. try 44100; reduce to 22050 as necessary, eg for slow connection
bitsPerSample   = 16        # bits per sample. try 16
channel         = 1         # channels. 1 = mono, 2 = stereo

# this section describes a streaming connection to the Locus Sonus server 

# to listen, go to the soundmap at //locusonus.org/soundmap/ and from the upper right choose 'i' for info, then 'login' then choose to set up a microphone
# an email announces your account is activated after verification by the moderator

[icecast2-0]

quality         = 1.0       # from 0.1 to 1.0; controls quality together with bitrate etc; see link at top for details
bitrateMode     = vbr       # vbr (variable bit rate) or cbr (constant bit rate)
format          = mp3    # format of the stream: 'vorbis' for ogg or 'mp3' for mp3
bitrate         = 256       # bitrate of the stream sent to the server; try 128 for slower connections
server          = locus.creacast.com     # name of the host server
port            = 9001      # port of the IceCast2 server, usually 8000; 9001 for Locus Sonus

password        = locusonus1   # locusonus1
mountPoint      = my-piradio-streamingbox.mp3  # mountpoint on icecast server, including .ogg or .mp3 eg london_camberwell.ogg - to appear on map, this must match your locus sonus account details
name            =           #  name of the streamer(s)
description     =           # optional description of the stream eg 'live stream from location'
url             = //qrtxt.de     # reference URL eg '//locusonus.org'

genre           = live streaming audio of everyday    # genre of the stream
public          = no # yes       # advertise this stream?
localDumpFile  = /home/pi/piradio/recordings/recording.mp3 # local dump file where a copy of the stream can be archived

Nach dem Abspeichern der Konfigurationsdatei, kann Darkice gestartet werden:

$ sudo darkice -c stream_configuration.cfg 

Entweder die Verbindung gelingt mit einer Erfolgsmeldung, etwa so:

DarkIce 1.2 live audio streamer, //code.google.com/p/darkice/
Copyright (c) 2000-2007, Tyrell Hungary, //tyrell.hu/
Copyright (c) 2008-2013, Akos Maroy and Rafael Diniz
This is free software, and you are welcome to redistribute it 
under the terms of The GNU General Public License version 3 or
any later version.

Using config file: stream_configuration.cfg
Using ALSA DSP input device: plughw:1,0
Using POSIX real-time scheduling, priority 4

Oder sie scheitert mit einer mehr oder weniger kryptischen Fehlermeldung. Hier stimmt z.B. die Bezeichnung des device (Soundkarte) nicht.:

 DarkIce: DarkIce.cpp:1273: can't open connector [0]

Verändere die Konfigurationsdatei so lange, bis der Stream läuft. Knifflig ist die Auswahl der richtigen Bezeichnung für die Soundkarte. Mit dem shell-Befehl arecord -l kann man sich Hardware-Bezeichnung der verfügbaren Aufnahme-Soundkarten anzeigen lassen. Ihre laufende Nummer taucht nachher bei der Device-Bezeichnung hinter dem Doppelpunkt auf. Mit arecord -L werden die verschiednen Device-Namen angezeigt, die das Audiosystem (ALSA) zur Verfügung stellt. Eine Soundkarte stellt dabei unterschiedliche Device-Namen zur Verfügung. Wie genau der Device-Namen heißt, den Darkice nachher versteht, muss man aber ausprobieren. Bei einer einfachen USB-Stick-Soundkarte hat bei mir device = hw:1,0 funktioniert, bei einem USB-Mischpult hat device = plughw:1,0 geklappt. Die Bezeichnungen werden beim hier installierten Raspian-System von ALSA zur Verfügung gestellt. Soweit ich das verstanden habe, wird mit hw direkt auf die Hardware zugegriffen, weshalb alle übergebenen Parameter (Samplingrate, Bitrate, Kanalanzahl) von dieser unterstützt werden müssen, bei plughw liegt jedoch noch ALSA dazwischen und kümmert sich um das Konvertieren.

Zum Probieren kann man, statt jedesmal Darkice zu starten, auch den shell-Befehl arecord -D plughw:1,0 -c 2 -V stereo /dev/null verwenden, der von der Soundkarte aufnimmt und ein VU-Meter auf der Konsole darstellt. Statt plughw:1,0 probiert man die Device-Bezeichnung, die einem plausibel erscheint. Mit Strg + c wird der Befehl wieder gestoppt. Wenn der Device-Namen funktioniert, sieht die Bildschirmausgabe dann so aus und man kann den Device-Namen in die Darkice-Konfigurationsdatei übertragen:

 $ arecord -D plughw:1,0 -c 2 -V stero /dev/null
Aufnahme: WAVE '/dev/null' : Unsigned 8 bit, Rate: 8000 Hz, stereo
                         +######## 27%|27%#########+

Hilfe zur Konfigurationsdatei findet man auf den Ubuntu Hilfeseiten zu Darkice //manpages.ubuntu.com/manpages/zesty/man5/darkice.cfg.5.html oder https://wiki.ubuntuusers.de/Darkice/.

Nach dem erfolgreichen Start von Darkice mit der Serverbezeichnung server = locus.creacast.com (aus der Konfigurationsdatei oben) wird der Stream auf der Übersicht von locussonus.org der aktiven Server gelistet:

Hier kann der Live-Stream direkt abgehört werden:

WLAN konfigurieren

Bislang lief die Piradio Streamingbox über das Kabel-LAN. Alternativ dazu soll sie nun auch über WLAN funktionieren. Die Modelle Raspberry Pi 3 und Raspberry Pi Zero W haben ein WLAN-Interface bereits integriert. Andere Raspberry Pi Modelle müssen dagegen noch mit einem externen WLAN-Stick nachgerüstet werden. Das Betriebssystem sollte den Stick automatisch erkennen und die benötigten Treiber automatisch laden. Daher müssen wir uns nur noch um die richtigen Zugangsdaten kümmern. Damit wir später nicht immer die root-Rechte benötigen, ändern wir zunächst die Zugriffsrechte für die Konfigurationsdatei wpa_supplicant.conf im Verzeichnis /etc/wpa_supplicant/ auf les- und schreibbar für alle (666):

$ sudo chmod 666 /etc/wpa_supplicant/wpa_supplicant.conf

Anschließend werden die Zugangsdaten (Netzwerknamen und Passwort) in die Konfigurationsdatei geschrieben. Dabei können auch mehrere Netzwerke angegeben werden. Öffne die Datei wpa_supplicant.conf von der Konsole aus mit dem Editor nano. Alternativ dazu kann man die Datei natürlich auch über das Netzwerk öffnen und dann mit einem beliebigen anderen Editor bearbeiten.

$ nano /etc/wpa_supplicant/wpa_supplicant.conf

Der Inhalt der Datei soll in etwa wie nachfolgend aussehen, wobei die Bezeichnung des Netzwerks (ssid) diejenige ist, die beim Scannen der verfügbaren Netzwerke (z.B. am Laptop oder am Smartphone) angezeigt wird und das Passwort (psk) ist das Netzwerk-Passwort. Diese Werte müssen individuell angepasst werden. Der ID-String des Netzwerks (id_str) kann frei gewählt werden und muss nur eindeutig sein.

# Mein erster Router
network={
    ssid="WLANRouter1"
    psk="mein_passwort1"
    id_str="location1"
}

# Mein zweiter Router
network={
    ssid="WLANRouter2"
    psk="mein_passwort2"
    id_str="location2"
}

Speichere und schließe die Datei anschließend: Strg + o, Enter, Strg + x.

Autostart einrichten

Die Streaming-Software soll beim Hochfahren des Raspberry Pi automatisch gestartet werden. Dazu muss sowas wie eine Autostart-Datei eingerichtet werden. Diese gibt es bereits standardmäßig und sie liegt im Verzeichnis /etc/ unter dem Namen rc.local. Öffne diese Datei als root-Benutzer:

$ sudo nano /etc/rc.local

Füge folgende Zeilen gleich vor der letzten Zeile (exit 0) ein:

# start scripts in /home/pi/piradio/run_on_boot/
sh /home/pi/piradio/run_on_boot/run_all_this.sh

Speichere und schließe die Datei anschließend: Strg + o, Enter, Strg + x.

Durch diesen Befehl wird beim Hochfahren des Rechners automatisch die Datei /home/pi/piradio/run_on_boot/run_all_this.sh ausgeführt. Man hätte zwar alle Befehle auch direkt in die Datei rc.local schreiben können, so ist es aber übersichtlicher. Jetzt fehlt nur noch die auszuführende Datei run_all_this.sh im Ordner /home/pi/piradio/run_on_boot/.
Rufe in der Shell wieder den Editor nano auf (diesmal sind keine root-Rechte erforderlich) …

$ nano /home/pi/piradio/run_on_boot/run_all_this.sh

… und füge nachfolgenden Inhalt ein. Für den Anfang reichen folgende Zeilen, die weiter unten nach und nach erweitert werden:

#!/bin/bash
# wechsele in das Verzeichnis mit den Start-Skripts
cd /home/pi/piradio/run_on_boot

# starte Darkice
./start_stream.sh &

Speichere und schließe die Datei anschließend: Strg + o, Enter, Strg + x.
Damit die Datei als Shell-Script ausgeführt wird, müssen noch die Datei-Rechte auf ausführbar gesetzt werden:

$ chmod 755 /home/pi/piradio/run_on_boot/run_all_this.sh

Das kleine Skript macht nichts anderes, als in das Verzeichnis /home/pi/piradio/run_on_boot/ zu wechseln und dort dann ein weiteres Skript aufzurufen, nämlich start_stream.sh. Auch dieses Skript müssen wir noch erstellen:

$ nano /home/pi/piradio/run_on_boot/start_stream.sh

Füge folgenden Inhalt in die Datei start_stream.sh ein:

#!/bin/bash
logfile="/home/pi/piradio/logfiles/stream_output.txt"
darkice_config="/home/pi/piradio/stream_config/stream_configuration.cfg"
darkiceRebootSwitch="/home/pi/piradio/stream_config/darkice_reboot.cfg"

echo started script on $(date) >> $logfile
echo 

cmd_signal_ready="/home/pi/piradio/run_on_boot/blinki.sh ..._1 "
cmd_signal_OK="/home/pi/piradio/run_on_boot/blinki.sh ---_-.-_1 &"
cmd_signal_error="/home/pi/piradio/run_on_boot/blinki.sh ........ &"
cmd_rename_recording="/home/pi/piradio/run_on_boot/rename_recording.sh"

## Make sure the script isn't already running 
################################################################################
if [ `ps -e | grep -c $(basename $0)` -gt 2 ]; then echo $(basename $0) is already running, stopping script; exit 0; fi
################################################################################

running=true

# show that skript has started
$cmd_signal_ready

if pgrep darkice; then
    echo ########
    echo another instance of darkice found, stopping script.
    echo ########
    #running=false

else
    echo no instance of darkice running.
    echo reconnect script initialised, running loop.
    lastSeconds=0
    currentSeconds=0
    failedTries=0
fi

while [ $running = true ]; do
        date >> $logfile
        echo >> $logfile
    lastseconds=$(date +%s)
    $cmd_rename_recording # move the old recording because Darkice will overwrite it on start 
        echo Versuche Darkice zu starten...
    # show that connection was successful
    $cmd_signal_OK
        sudo darkice -c $darkice_config | tee -a ${logfile}
    if [ $(($(date +%s)-$lastseconds)) -lt 20 ]; then
            if grep ON $darkiceRebootSwitch; then    
        failedTries="$((failedTries+1))"
        echo Darkice failed, under 60 secs. It has failed $failedTries times, will reboot at 5 failed tries. | tee -a ${logfile}
        fi
        else
            failedTries=0
        fi
        if [ $failedTries -gt 5 ]; then
        sudo reboot
        fi
        echo darkice crashed, retrying in 10 seconds. | tee -a ${logfile}
    $cmd_signal_error
    sleep 10
done

Speichere und schließe die Datei anschließend: Strg + o, Enter, Strg + x.

Auch hier muss die Datei als ausführbar gesetzt werden:

$ chmod 755 /home/pi/piradio/run_on_boot/start_stream.sh

Das wars fürs Erste. Nach dem Neustart des Raspberry Pi mit sudo reboot sollte Darkice jetzt automatisch starten.

Das Skript ruft noch ein paar andere Skripte auf bzw. nutzt weitere Dateien. Deshalb kommt es beim Aufruf erst mal zu Fehlermeldungen, was uns aber erst mal nicht beunruhigen soll. Die Skripte werden weiter unten noch vorgestellt. Zur Info sind hier die weiteren Dateien und Skripte aufgezählt:

  • /home/pi/piradio/logfiles/stream_output.txt # Logfile: Erfolgs- oder Misserfolgsmeldungen von Darkice (Datei wird automatisch erstellt und ergänzt)
  • /home/pi/piradio/stream_config/stream_configuration.cfg # Konfigurationsdatei für Darkice (siehe oben)
  • /home/pi/piradio/stream_config/darkice_reboot.cfg # Konfigurationsdatei, ob die Piradio Streamingbox neu gebootet werden soll, wenn Darkice 5 mal abstürzt (Inhalt: ON oder OFF)
  • /home/pi/piradio/run_on_boot/blinki.sh # Shell-Skript: siehe Feedback mit Bereitschafts-LED
  • /home/pi/piradio/run_on_boot/rename_recording.sh # Shell-Skript: Ändere den Namen des alten Mitschnitts, siehe Hilfsprogramme

Shutdown-Knopf nachrüsten

Leider haben die Designer des Raspberrry Pi den Ausschalter vergessen. Stattdessen wird der Minirechner einfach vom Stromnetz getrennt und alle Prozesse sterben ab. Das kann manchmal dazu führen, dass die SD-Karte Schaden leidet, insbesondere dann, wenn sie gerade noch beim Schreiben war, als der Strom getrennt wurde. Bei unserer Piradio Streamingbox ist das der Regelfall, denn der Stream wird automatisch auf der SD-Karte mitgeschrieben. Die Folge ist, dass sich der Raspberry Pi möglicherweise nicht mehr starten lässt, die Aufnahme futsch ist und das System komplett neu aufgesetzt werden muss. Aus diesem Grund lohnt sich übrigens auch ein Komplettbackup (eine Kopie der SD-Karte), wenn die Piradio Streamingbox so läuft, wie sie soll.

Wir wollen daher einen Shutdown-Knopf nachrüsten. Beim Druck auf den Shutdown-Knopf soll Darkice gestoppt werden und die Piradio Streamingbox geordnet herunter gefahren werden. Erst danach kann man den Netzstecker ziehen, ohne fürchten zu müssen, irgend etwas zu zerstören.

Der Raspberry Pi bietet mit der GPIO-Schnittstelle elektrische Kontakte, an die man zum Beispiel einen Taster anschließen kann. Weitere Infos zur GPIO-Schnittstelle und der Pin-Belegung der Steckerleiste gibt es z.B. auf der raspberrypi.org Webseite. Wir schließen den Taster als Schließer zwischen den Anschluss GPIO11 (physischer Pin 23 auf der Steckerleiste) und Masse (z.B. physischer Pin 25) und verdrahten den Raspberry Pi wie folgt:

Ein python-Skript überwacht nun den Anschluss GPIO11 und fährt die Piradio Streamingbox herunter, sobald der Taster gedrückt wird. Interessant ist das Skript deshalb, weil es den Pegel nicht in einer Dauerschleife überwacht und damit wertvolle CPU-Leistung verschwendet. Stattdessen wird auf einen fallendenden Pegel gewartet (GPIO.wait_for_edge), der ein Interrupt auslöst und erst dann den shell-Befehl sudo shutdown -h now absetzt. Das Skript habe ich von AndrewH7 von der Webseite instructables kopiert und unter dem Namen off_button.py im Verzeichnis /home/pi/piradio/run_on_boot/ abgespeichert.

#!/bin/python
#This script was authored by AndrewH7 and belongs to him (www.instructables.com/member/AndrewH7)
#You have permission to modify and use this script only for your own personal usage
#You do not have permission to redistribute this script as your own work
#Use this script at your own risk

import RPi.GPIO as GPIO
import os

gpio_pin_number=11 # YOUR_CHOSEN_GPIO_NUMBER_HERE
#Replace YOUR_CHOSEN_GPIO_NUMBER_HERE with the GPIO pin number you wish to use
#Make sure you know which rapsberry pi revision you are using first
#The line should look something like this e.g. "gpio_pin_number=7"

GPIO.setmode(GPIO.BCM)
#Use BCM pin numbering (i.e. the GPIO number, not pin number)
#WARNING: this will change between Pi versions
#Check yours first and adjust accordingly

GPIO.setup(gpio_pin_number, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#It's very important the pin is an input to avoid short-circuits
#The pull-up resistor means the pin is high by default

try:
    GPIO.wait_for_edge(gpio_pin_number, GPIO.FALLING)
    #Use falling edge detection to see if pin is pulled 
    #low to avoid repeated polling
    os.system("sudo shutdown -h now")
    #Send command to system to shutdown
except:
    pass

GPIO.cleanup()
#Revert all GPIO pins to their normal states (i.e. input = safe)

Das python-Skript soll nun direkt nach dem Hochfahren aufgerufen werden. Dazu ändern wir das oben erstellte Shell-Skript run_all_this.sh wie folgt (neue Zeilen sind hervorgehoben):

#!/bin/bash
# wechsele in das Verzeichnis mit den Start-Skripts
cd /home/pi/piradio/run_on_boot

# starte das off-button py-skript
python off_button.py &
echo 'Off-Button scharf gestellt'

# starte Darkice
./start_stream.sh &

Feedback mit Bereitschafts-LED

Als nächstes wird die Streamingbox noch mit einer Anzeige ausgestattet, die zeigt, ob der Stream erfolgreich gestartet wurde bzw. ob irgendwelche Fehler aufgetreten sind. Als einfache Anzeige wird eine LED verwendet, die je nach Betriebszustand unterschiedliche Blinksignale von sich gibt. Die LED wird über einen 220 Ohm Widerstand mit der Masse (physischer Pin 25 an der Steckerleiste) und mit dem Anschluss GPIO10 (physischer Pin 19) verbunden.

Das nachfolgende Shell-Skript mit dem Namen blinki.sh im Verzeichnis /home/pi/piradio/run_on_boot/ kümmert sich jetzt um das Ansteuern der LED. Das Skript wird von den anderen Programmen mit Übergabeparametern aufgerufen. Möchte man also eigene Blinksignale senden, kann man dies einfach mit einem Aufruf in der Form blinki.sh ... --- ... tun, was beispielsweise ein SOS-Signal in Morsezeichen blinken lässt.

#!/bin/bash
#
# Uebergabeparameter:
# "." kurz blinken: an-aus
# "-" lange blinken: an-aus
# "_" lange Pause: aus
# "1" nach Aktion LED anschalten: an

Port="10" # LED-Pin

# Port initialisieren; aber nur, wenn noch nicht erfolgt
if [ ! -f /sys/class/gpio/gpio${Port}/direction ] ; then
  if [ $USER != "root" ]; then
    echo "Der erste Aufruf des Programms muss als root-User erfolgen!"
    exit 1
  fi
  echo "Initialisiere GPIO $Port"
  echo "$Port" > /sys/class/gpio/unexport
  echo "$Port" > /sys/class/gpio/export
  echo "out" >/sys/class/gpio/gpio${Port}/direction
fi

# Check for the existence of a PID from the same script.
# and kill the previously started instances
# Quelle: //unix.stackexchange.com/questions/213288/killing-the-previous-instances-of-a-script-before-running-the-same-unix-script

for pid in $(pidof -x $(basename $0)); do
    if [ $pid != $$ ]; then
        kill -9 $pid
  echo $pid " beendet"
    fi 
done


# erst mal kurz ausschalten
echo "0" > /sys/class/gpio/gpio${Port}/value
sleep 1

# Parameter uebernehmen
blinksignal=$1
laenge=${#blinksignal}
for ((i=0;i<laenge;i++));do
  einzelsignal=${blinksignal:$i:1}
  # echo $i: $einzelsignal
  case "$einzelsignal" in
    ".")
    echo "1" > /sys/class/gpio/gpio${Port}/value
    sleep 0.15 ;;
    "-") 
    echo "1" > /sys/class/gpio/gpio${Port}/value
    sleep 1 ;;
    "_")
    echo "0" > /sys/class/gpio/gpio${Port}/value
    sleep 0.85 ;;
  esac
  echo "0" > /sys/class/gpio/gpio${Port}/value
  sleep 0.15
done

# wieder anschalten, wenn letzte Eintrag "1"
if [ $einzelsignal == "1" ]; then
  echo "1" > /sys/class/gpio/gpio${Port}/value
fi

Nach dem Abspeichern nicht vergessen, die Datei als ausführbar zu setzen:

$ chmod 755 /home/pi/piradio/run_on_boot/blinki.sh

Interaktionen mit einem USB-Stick

Da die Piradio Streamingbox ohne Bildschirm und Tastatur auskommt, soll es trotzdem möglich sein, Dateien hinein und hinaus zu schaufeln. Daher soll die Piradio Streamingbox mit einem USB-Speicherstick interagieren: Sobald ein USB-Speicherstick eingesteckt wird, sollen folgende Aktionen ausgeführt werden:

  • Kopiere ein neues Darkice-Konfigurationsfile vom Stick auf die Piradio Streamingbox
  • Kopiere ein neues WLAN-Konfigurationsfile vom Stick auf die Piradio Streamingbox
  • Kopiere den letzten Mitschnitt (die recording-Datei) von der Piradio Streamingbox auf den USB-Stick
  • Werfe den USB-Stick wieder aus (umount)

Dazu werden erst einmal zwei neue Programme auf dem Raspberry Pi installiert:

$ sudo apt-get install usbmount
$ sudo apt-get install at

Nach der Installation muss man noch die Datei usbmount.conf im Ordner /etc/usbmount/ anpassen, damit lesend und schreibend auf den Stick zugegriffen werden kann:

$ sudo nano /etc/usbmount/usbmount.conf

Hier sucht man nach folgender Zeile:

$ FS_MOUNTOPTIONS=""

und ändert sie in:

$ FS_MOUNTOPTIONS="-fstype=vfat,gid=users,dmask=0007,fmask=0117"

Speichere und schließe die Datei anschließend: Strg + o, Enter, Strg + x.

Etwas ausführlicher wird das Installieren von usbmount auf der Webseite https://www.elektronik-kompendium.de/sites/raspberry-pi/1911271.htm beschrieben.

Lege das Shell-Skript 50_usbstick_plugged im Ordner /etc/usbmount/mount.d/ an, das beim Einstecken eines USB-Sticks ausgeführt wird:

$ sudo nano /etc/usbmount/mount.d/50_usbstick_plugged

Inhalt des Skripts ist folgender:

#!/bin/bash
echo Mountpoint: $UM_MOUNTPOINT Device: $UM_DEVICE >> /home/pi/piradio/logfiles/usbstick.log
# echo xxx.sh | at now breaks the connection between the calling script and the xxx.sh script
echo /home/pi/piradio/run_on_boot/usbstick_plugged.sh $UM_MOUNTPOINT | at now
exit 0

Jetzt noch die Datei usbstick_plugged.sh im Verzeichnis /home/pi/piradio/run_on_boot/ erstellen …

$ nano /home/pi/piradio/run_on_boot/usbstick_plugged.sh

… und mit folgendem Inhalt füllen:

#!/bin/bash
# This script is called from /etc/usbmount/mount.d/50_usbstick_plugged
# usge: usbstick_plugged.sh [MOUNTPOINT]
# If a USB storage is plugged in, this script copies the recorded audio to the USB storage
# and unmounts the USB storage if finished 
# Quelle: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=125495#

## Make sure the script isn't already running from a previous disk connection
################################################################################
if [ `ps -e | grep -c $(basename $0)` -gt 2 ]; then exit 0; fi
################################################################################
#
sleeptime=5
logfile=/home/pi/piradio/logfiles/usbstick.log
destination=/media/usb0 # wenn kein Parameter uebergeben wird, nimm den ersten USB-Stick
# source=/home/pi/piradio/recordings/recording.ogg # wird jetzt aus dem confif-file gezogen
darkice_config=/home/pi/piradio/stream_config/stream_configuration.cfg # Quelle fuer recording-file

function recfilename {
  shopt -s extglob
  while IFS='= ' read lhs rhs
  do
      if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then
    rhs="${rhs%%\#*}"    # Del in line right comments
    rhs="${rhs%%*( )}"   # Del trailing spaces
    rhs="${rhs%\"*}"     # Del opening string quotes 
    rhs="${rhs#\"*}"     # Del closing string quotes 
    # echo $lhs="$rhs"
    # declare $lhs="$rhs"
    if [ $lhs == localDumpFile ]; then 
      declare $lhs="$rhs"
    fi
      fi
  done < $darkice_config
  echo $localDumpFile
}

source=$(recfilename)

MaxTries=20
cmd_signal_ready="/home/pi/piradio/run_on_boot/blinki.sh ---_ &"
cmd_signal_error="/home/pi/piradio/run_on_boot/blinki.sh ........1"
cmd_signal_OK="/home/pi/piradio/run_on_boot/blinki.sh ---_-.-_1 &"
cmd_update_configfiles_from_usb="/home/pi/piradio/run_on_boot/update_configfiles_from_usb.sh"

function addTimestampToFilename {
    # this function adds a timestamp to a filename which is passed together with its path
    # returns only filename (without path)
    filenameWithPath=$1;
    datestring=$(stat --printf='%y' $filenameWithPath) # get the modification date of file
    datestring=${datestring%.*} # cut it after "."
    datestring=${datestring// /_}  # replace all (//) Spaces by "_"
    datestring=${datestring//:/.}  # replace all (//) ":" by "."
    # datestring=$(echo "$datestring" | tr ' ' '_') # replace Space by "_"
    # datestring=$(echo "$datestring" | tr ':' '.') # replace : by "."
    echo $datestring\_${filenameWithPath##*/}
}

if [ ! -z "$1" ]; then
    let destination=$1 # $1 ist der Mountpoint, der aus dem Trigger-Skript uebergeben wird
fi


echo "Script Started" | tee -a ${logfile}
date >> $logfile
# Test if the Destination disk is connected.
ActualTry=1
until [ $ActualTry -gt $MaxTries ]
do
 echo "Versuch: $ActualTry/$MaxTries" | tee -a ${logfile}
 if [ -w $destination ] # -w: writeable
 then
    mountpoint=$(df --output=source $destination | tail -n +2)
    $cmd_signal_ready
    destinationfile=$(addTimestampToFilename $source)
    echo "USB Storage unter $mountpoint gefunden" | tee -a ${logfile}
    # hostname -I > $destination/ip_address_$(date +%Y.%m.%d_%H-%M-%S).txt
    hostname -I > $destination/ip_address.txt
    echo "IP-Adresse auf USB Storage geschrieben" | tee -a ${logfile}
    # NEU! Kopiere (darkice) Configfile vom USB Storage auf lokal
    $cmd_update_configfiles_from_usb $destination # | tee -a ${logfile}
    if [[ $? -eq 0 ]] ; then
  # ja, es war ein neueres Configfile auf dem USB Storage, also breche das Skript hier ab 
  echo "Unmount the USB storage $mountpoint" | tee -a ${logfile}
  sudo umount $destination >> $logfile 2>&1
  echo "Script Complete" | tee -a ${logfile}
  echo "===============" | tee -a ${logfile}   
  echo | tee -a ${logfile}
  echo | tee -a ${logfile}
  echo | tee -a ${logfile}
  exit 0
    fi
    echo "== Copying of $destinationfile started ==" | tee -a ${logfile}
    cp $source $destination/$destinationfile >> $logfile 2>&1
    # rsync -avzh $source $destination/$destinationfile >> $logfile 2>&1 # rsync klappt nicht, weil sich Datei sich noch aendert, solange Darkice laeuft
    echo "Kopieren der Datei $destinationfile abgeschlossen" | tee -a ${logfile}
    echo "Unmount the USB storage $mountpoint" | tee -a ${logfile}
    sudo umount $destination >> $logfile 2>&1

    date >> $logfile
    echo "== Copy Complete ==" | tee -a ${logfile}
    let ActualTry=$MaxTries
 else
    echo "== USB Storage nicht gefunden ==" | tee -a ${logfile}
    $cmd_signal_error
    sleep $sleeptime
 fi
 let ActualTry++
done
echo "Script Complete" | tee -a ${logfile}
echo "===============" | tee -a ${logfile}   
echo | tee -a ${logfile}
echo | tee -a ${logfile}
echo | tee -a ${logfile}
$cmd_signal_OK

Damit die Datei als Shell-Script ausgeführt wird, müssen auch hier die Rechte auf ausführbar gesetzt werden:

$ chmod 755 /home/pi/piradio/run_on_boot/usbstick_plugged.sh

Das Skript usbstick_plugged.sh ruft ein weiteres Shell-Skript im gleichen Verzeichnis /home/pi/piradio/run_on_boot/ mit dem Namen update_configfiles_from_usb.sh auf, das nach dem gleichem Muster erstellt und auf ausführbar gesetzt werden muss:

#!/bin/bash
# Parameter $1 is the USB-Drive e.g. /media/usb0

logfile="/home/pi/piradio/logfiles/usbstick.log"
darkice_config="/home/pi/piradio/stream_config/stream_configuration.cfg"
cmd_darkice_restart="/home/pi/piradio/help_scripts/stream_restart.sh"
wlan_config="/etc/wpa_supplicant/wpa_supplicant.conf"
# wlan_config="/home/pi/piradio/help_scripts/wlan-setup.conf"
cmd_wlan_restart="/home/pi/piradio/help_scripts/wifi_reconnect.sh"
usbdrive=$1
exitstatus=1

function copyIfDifferent {
    # kopiere nur, wenn Unterschiede
    fileToCopy=$1
    if $(cmp --silent $usbdrive/${fileToCopy##*/} $fileToCopy); then
  # keine Unterschiede gefunden
  # 1 = false
  return 1
    else
  renamedfile=$(addTimestampToFilename $fileToCopy) # packe timestamp davor
  mv $fileToCopy ${fileToCopy%/*}/$renamedfile # nenne lokales configfile um
  sudo cp $usbdrive/${fileToCopy##*/} $fileToCopy # ${fileToCopy%/*}/ # kopiere von usb nach lokal
  sudo chown pi $fileToCopy # aendere den eigentuemer auf pi
  echo "== ${fileToCopy##*/} von USB auf lokal kopiert ==" | tee -a ${logfile}
  # 0 = true
  return 0 
    fi
}

function addTimestampToFilename {
    # this function adds a timestamp to a filename which is passed together with its path
    # returns only filename (without path)
    filenameWithPath=$1;
    datestring=$(stat --printf='%y' $filenameWithPath) # get the modification date of file
    datestring=${datestring%.*} # cut it after "."
    datestring=${datestring// /_}  # replace all (//) Spaces by "_"
    datestring=${datestring//:/.}  # replace all (//) ":" by "."
    echo $datestring\_${filenameWithPath##*/} # dieser Wert wird an Aufrufer zurueck gegeben
}  

if [ -w $usbdrive ]; then # -w: writeable --> USB Storage is mounted
  # Checke Darkice Configfile 
  if [ -f $usbdrive/${darkice_config##*/} ]; then # Config File exists on USB Storage
    # copysuccess=$(copyIfDifferent $darkice_config)
    if copyIfDifferent $darkice_config; then 
      sudo $cmd_darkice_restart >/dev/null & 
      echo "--> Darkice neu gestartet" | tee -a ${logfile}
      let exitstatus=0			
    else
      echo "-- Darkice Configfile gefunden, aber nicht kopiert, weil Datei ${darkice_config##*/} identisch --" | tee -a ${logfile}
    fi
  else
    echo "-- kein Darkice Configfile auf dem USB Storage gefunden --" | tee -a ${logfile}
  fi
  # Checke WLAN Configfile 
  if [ -f $usbdrive/${wlan_config##*/} ]; then # WLAN-Config File exists on USB Storage
    if copyIfDifferent $wlan_config; then 
      sudo $cmd_wlan_restart >/dev/null & 
      echo "--> WLAN neu gestartet" | tee -a ${logfile}
      let exitstatus=0			
    else
      echo "-- WLAN Configfile gefunden, aber nicht kopiert, weil Datei ${darkice_config##*/} identisch --" | tee -a ${logfile}
    fi
  else
    echo "-- kein WLAN Configfile auf dem USB Storage gefunden --" | tee -a ${logfile}
  fi
 else
    echo "== USB Storage nicht gefunden ==" | tee -a ${logfile}
 fi
exit $exitstatus

Danach das System neu starten:

$ sudo reboot

Wenn alles nach Plan gelaufen ist, kann man jetzt in der Datei /home/pi/piradio/logfiles/usbstick.log nachlesen, was beim Einstecken eines USB-Sticks alles passiert ist. Am einfachsten geht das mit dem Shell-Befehl:

$ tail -f /home/pi/piradio/logfiles/usbstick.log

… mit dem man Änderungen des Logfiles beim Einstecken eines USB-Sticks live beobachten kann. Abbruch des Befehls mit Strg + c.

Weitere Hilfsprogramme

Zu der Piradio Streamingbox gehören noch ein paar weitere nützliche Hilfsprogramme.

Eines davon wird bereits gleich nach dem Starten der Piradio Streamingbox aufgerufen (siehe Autostart). Das Skript mit dem Namen rename_recording.sh im Ordner /home/pi/piradio/run_on_boot/ sucht sich den Namen des Recording-Files aus der Darkice-Konfigurationsdatei und ändert den Namen der letzten Aufnahme, indem es ihm einen Zeitstempel mit dem Aufnahmedatum voranstellt. Aus recording.mp3 wird dann beispielsweise 2017-06-21_15.00.05_recording.mp3 mit dem Muster YYYY-MM-DD_hh.mm.ss_oldfilename. Dadurch wird verhindert, dass der neu gestartete Livestream die alte Aufnahme überschreibt und es wird gleichzeitig ein sortierbares Archiv mit allen alten Livestreams angelegt. Kleiner Haken: irgendwann ist die SD-Karte voll und die alten Aufnahmen müssen wieder gelöscht werden.

Hier ist das zugehörige Skript rename_recording.sh:

#!/bin/bash
darkice_config="../stream_config/stream_configuration.cfg"

## Make sure the script isn't already running 
################################################################################
if [ `ps -e | grep -c $(basename $0)` -gt 2 ]; then echo $(basename $0) is already running, stopping script; exit 0; fi
################################################################################

function addTimestampToFilename {
    # this function adds a timestamp to a filename which is passed together with its path
    # returns only filename (without path)
    filenameWithPath=$1;
    datestring=$(stat --printf='%y' $filenameWithPath) # get the modification date of file
    datestring=${datestring%.*} # cut it after "."
    datestring=${datestring// /_}  # replace all (//) Spaces by "_"
    datestring=${datestring//:/.}  # replace all (//) ":" by "."
    echo $datestring\_${filenameWithPath##*/}
}  

function recfilename {
  shopt -s extglob
  while IFS='= ' read lhs rhs
  do
      if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then
    rhs="${rhs%%\#*}"    # Del in line right comments
    rhs="${rhs%%*( )}"   # Del trailing spaces
    rhs="${rhs%\"*}"     # Del opening string quotes 
    rhs="${rhs#\"*}"     # Del closing string quotes 
    # echo $lhs="$rhs"
    # declare $lhs="$rhs"
    if [ $lhs == localDumpFile ]; then 
      declare $lhs="$rhs"
    fi
      fi
  done < $darkice_config
  echo $localDumpFile
}

file_to_rename=$(recfilename)
# if [ $file_to_rename ]; then echo Filename is: $file_to_rename; fi
if [ $file_to_rename ]; then
  # if [ -f $file_to_rename ] && [ $(stat -c%s "$file_to_rename") ];
  if [ -f $file_to_rename ] && [ -s $file_to_rename ]; # exists (-f) and is not zero size (-s)
    then
      destinationfile=$(addTimestampToFilename $file_to_rename)
      if mv $file_to_rename ${file_to_rename%/*}/$destinationfile
      then
        echo Recording-Datei $destinationfile erfolgreich geschrieben
      else
        echo "Fehler beim Umbenennen der Recording-Datei, exit status $?"
      fi
    else
      echo "Recording-Datei $file_to_rename existiert nicht!"
  fi
fi

 

Was sonst noch verbessert werden könnte

  • Erkennen, wenn die SD-Karte voll ist.
  • Ausgabe des Audio-Signals auf ein VU-Meter.
  • Streamingbox als Recordingbox verwenden.

To be continued…

Download

Die hier vorgestellten Dateien und Programme habe ich auf GitHub (https://github.com/flupppuppe/piradio-streamingbox) abgelegt. Dort kann man durch die Ordnerstruktur browsen und sieht noch einmal alle Dateien im Überblick.

Zusätzlich habe ich hier ein SD-Karten-Image (353 MB) abgelegt, das eine Komplettinstallation enthält:

  • Raspbian Jessie Lite (Kernel version: 4.4, Release date: 2017-04-10)
  • darkice
  • fping
  • locate
  • usbmount
  • at
  • plus alle Dateien bzw. Skripte für die Piradio Streamingbox

Die Installation des SD-Karten-Images mit Hilfe eines Linux-Rechners wird nachfolgend beschrieben. Achtung! Wer zum ersten mal eine SD-Karte für den Raspberry Pi präpariert, sollte lieber die ausführlichere Anleitung auf der raspberrypi.org-Webseite anschauen. Sonst ist schnell die eigentliche System-Festplatte überschrieben. Als Image-Datei muss natürlich die entpackte Datei piradio-streamingbox.img verwendet werden. Mit einem Windows-Rechner nutzt man statt der Anleitung unten am besten ein grafisches Werkzeug, wie Win32DiskImager.

Installation auf SD-Karte:

  • Download der Komplettinstallation: //www.qrtxt.de/wp-content/uploads/2017/06/piradio-streamingbox.zip (353 MB).
  • Entpacke die ZIP-Datei auf der lokalen Linux-Festplatte.
  • Im entpackten Ordner piradio-streamingbox/ liegt jetzt eine Installationsanleitung install.html und die img-Datei piradio-streamingbox.img mit der Komplettinstallation.
  • Stecke eine leere SD-Karte (mindestens 2 GByte) in den Linux-Rechner (ggf. Adapter benutzen).
  • Öffne ein Terminal-Fenster.
  • Wechsle in den Ordner, in dem die img-Datei liegt.
  • Suche die Bezeichnung der leeren SD-Karte mit dem Befehl df -h (z.B. /dev/sdb1).
  • Hänge die SD-Karte mit umount /dev/sdb1 aus.
  • Kopiere das Image mit sudo dd bs=4M if=piradio-streamingbox.img of=/dev/sdb auf die SD-Karte, wobei die Partitionsnummer (in meinem Fall die 1 von /dev/sdb1) weggelassen werden muss.
  • Nachdem die SD-Karte fertig geschrieben ist, stecke sie aus.

Wenn die Piradio Streamingbox per WLAN verbunden werden soll, müssen zuerst die Zugangsdaten eingestellt werden (siehe WLAN konfigurieren). Dafür die SD-Karte wieder in den Linux-Rechner einstecken und die Datei MOUNTPOINT/etc/wpa_supplicant/wpa_supplicant.conf anpassen. MOUNTPOINT ist dabei der automatisch zugeteilte Pfad zur SD-Karte (z.B. /media/ubuntu/f2100b2f-ed84-4647-b5ae-089280112716). Danach wird die SD-Karte ausgeworfen und in den Raspberry Pi eingesetzt.

Inbetriebnahme:

  • Schließe die Soundkarte, das LAN-Kabel oder ggf. den WLAN-Stick an den Raspberry Pi an.
  • Starte den Minirechner durch Verbinden mit dem USB-Netzteil.
  • Wenn der Raspberry Pi direkt am LAN-Netzwerk hängt oder die WLAN-Verbindung erfolgreich war, verbindet sich die Streamingbox automatisch mit dem Icecast-Server, der in der Konfigurationsdatei festgelegt wurde (siehe Installation der Streaming-Software). Voraussetzung ist jedoch, dass die Soundkarte auf Anhieb erkannt wurde.
  • Zum Ändern der Konfigurations-Files kann man sich jetzt per SSH (ssh pi@raspberrypi) oder SFTP mit der Streamingbox verbinden.
  • Der Default-Login lautet: Benutzername: pi, Passwort: raspberry
  • Nicht vergessen: nach dem ersten Login raspi-config aufrufen, das Passwort ändern und das Dateisystem auf die komplette SD-Karte erweitern (Advanced options -> Expand filesystem). Sonst ist die Karte ruckzug mit dem recording-File vollgeschrieben.

Stand: 27.06.2017

Nutzungsbedingungen

  • Die Nutzung dieses Dienstes (qrtxt.de) zur Veröffentlichung von QR-Texten und Erzeugung von QR-Codes ist kostenlos.
  • Die Nutzer sind damit einverstanden, dass ihre Inhalte (z.B. Texte, Bilder oder Videos) uneingeschränkt und unentgeltlich veröffentlicht werden.
  • Es dürfen hier nur Inhalte veröffentlicht werden, die nicht gegen das in Deutschland geltende Recht verstoßen. Verboten sind beispielsweise die Veröffentlichung von:
    • urheberrechtlich geschütztem Material, sofern der Nutzer nicht der Rechteinhaber ist,
    • jugendgefährdenden, sexistischen oder rassistischen Inhalten,
    • Inhalten, die dazu geeignet sind, das Persönlichkeitsrecht von anderen zu verletzen.
  • Inhalte, die dem Betreiber des Dienstes suspekt oder unerwünscht erscheinen, können vom Betreiber jederzeit und ohne Begründung gelöscht werden.
  • Bei der Eintragung von Inhalten auf dieser Seite wird die IP-Adresse des Nutzers erfasst. Mithilfe dieser IP-Adresse kann auf den Nutzer rückgeschlossen werden. Die so gesammelten Daten werden vom Betreiber weder verkauft, veröffentlicht oder an Dritte weitergegeben.
  • Aus der Nutzung dieses Dienstes können keinerlei Rechte abgeleitet werden.
    • Dies beinhaltet:
    • Es besteht kein Recht auf die sichere und dauerhafte Aufbewahrung der Inhalte und Daten.
    • Die vom Nutzer erstellten Inhalte werden in keiner Weise vergütet.
    • Wenn Inhalte verloren gehen, beispielsweise durch gezielte Löschung oder technische Defekte, kann der Betreiber dafür nicht haftbar gemacht werden.
  • Die erstellten QR-Texte und Inhalte dürfen auf der Webseite qrtxt.de verlinkt und auf Sammelseiten (z.B. Archiven) eingebunden sowie durch Suchmaschinen erfasst werden.
  • Die Nutzer haben die Möglichkeit, die Löschung von selbst erstellten Inhalte zu beantragen.
    • Wer von dieser Möglichkeit Gebrauch machen möchte, schreibt bitte eine eine E-Mail an den Betreiber und nennt die URL sowie zum Nachweis der Urheberschaft das Datum und die Uhrzeit der Erstellung des jeweiligen Beitrages. Der Betreiber nimmt nach eigenem Ermessen dann eine Löschung vor.
  • Die Nutzungsbedingungen (dieses Dokument) können jederzeit verändert werden.
    • Wer nach der Änderung der Nutzungsbedingungen nicht mehr mit der Veröffentlichung seines Inhalts einverstanden ist, kann die Löschung (siehe vorangehender Punkt) seines Inhalts beantragen.

Stand: 01.09.2014

Veröfentlicht in Info

1. Schritt

QR-Text schreiben

1. Schritt
Schreibe hier auf QRTXT eine Kurzbotschaft. Füge Links, Bilder oder Videos aus externen Quellen ein.

2. Schritt

QR-Code ausdrucken

2. Schritt
Nach dem Speichern wird automatisch ein QR-Code erzeugt, den du ausdrucken kannst. Der QR-Code verweist auf deinen Kurztext.

3. Schritt

QR-Code verteilen

3.Schritt
Verteile den QR-Code als Aufkleber, Flyer oder Postkarte. Wer deinen Code mit dem Smartphone scannt, kann deine Kurzbotschaft lesen.