Internetradio mittels icecast2 und ices2 senden: „dirty ALSA hack“

Mein Hörspielserver sendet derzeit sein Audiosignal per Kabel an einen kleinen Verstärker. Dieser verteilt den Sound per Kabel an weitere Verstärker. So kann ich im ganzen Haus Musik hören.

Jetzt fehlte eigentlich nur noch, dass die Musik zusätzlich ins Netz gestreamt wird. So kann ich dann z.B. im Garten mit dem eeePC per W-Lan mithören. Der Hörspielserver soll also auch als Netzradio-Station dienen.

 

1. Radioserver installieren

Zunächst benötigt man einen Radioserver. Dieser ist ausschließlich dazu da , ein „fertiges“ Audiosignal als Stream ins Netzwerk zu senden. Es gibt verschiedene Server für Linux, ich verwende icecast2. Zusätzlich benötigt man noch ein Programm, welches ein fertiges Audiosignal an den Server (icecast2) sendet. Ich verwende hierfür ices2, da ich darkice nicht stabil ans Laufen bringe. Zu beachten ist allerdings, dass ices2 nur OGG-Streams beherrscht!
Es gibt eine sehr schöne Anleitung von Falko Timme, die beschreibt, wie man icecast2 und ices2 installiert und konifguriert.

Ich bin bei meinem System so vorgegangen:

 
1.1 icecast2
Zunächst installiere ich icecast2:

sudo apt-get install icecast2

Icecast2 wird über die Datei /etc/icecast2/icecast.xml konfiguriert (benötigt root-Rechte). Eine umfangreiche Erklärung der Einstellungen findes du im Wiki der ubuntuusers.de, ich habe lediglich im Abschnitt <authentication> … </authentication> die Passwörter geändert.

Damit icecast2 auch wirklich startet, muss in der Datei /etc/default/icecast2 der Eintrag ENABLE=false auf ENABLE=true gesetzt werden. Jetzt kann man icecast2 starten per

sudo /etc/init.d/icecast2 start

Wenn der Server läuft, wird ein Webinterface auf Port 8000 gestartet. Du erreichst es also mit einem Browser unter http://IP.DES.SERVERS:8000
Wenn du das Webinterface sehen kannst, scheint alles richtig zu laufen. Wundere dich nicht, dass unter „Server Status“ noch nichts angezeigt wird. In dieser Sektion werden die verfügbaren Radioprogramme angezeigt, und da wir ja zur Zeit noch kein „fertiges“ Audiosignal an den Server übermitteln, und somit noch kein Radioprogramm existiert, ist dieser Bereich leer.

Das soll sich nun ändern.

 
1.2 ices2
Zum übermitteln des Streams verwende ich ices2.

sudo apt-get install ices2

Bei der Installation werden zwei wichtige Verzeichnisse und eine Logdatei nicht erstellt, das holen wir nun nach:

sudo mkdir /etc/ices2
sudo mkdir /var/log/ices2
sudo touch /var/log/ices2/ices2.log

In das Verzeichnis /etc/ices2 hinterlegen wir die Konfigurationsdateien für ices2 (Beispiele hierzu liegen im Ordner /usr/share/doc/ices2/examples/). Wie diese Dateien bei mir aussehen, möchte ich nun erklären.

 

2. Radio senden

Ich möchte auf meinem System zwei verschiedene Radiostationen laufen lassen:

  1. Eine Playliste wird gesendet
  2. Das aktuelle Audiosignal der Soundkarte wird gestreamt

Für jeden Radiosender muss eine eigene ices2-Instanz mit entsprechender Konfigurationsdatei laufen.

 
2.1 Playliste senden
Der Playlist-Sender ist recht einfach eingerichtet.
Im Ordner /etc/ices2 hinterlegen wir die Konfigurationsdatei ices-playlist.xml mit folgendem Inhalt:

<?xml version="1.0"?>
<ices>
    <background>1</background>
    <logpath>/var/log/ices2</logpath>
    <logfile>ices2.log</logfile>
    <!-- 1=error,2=warn,3=info,4=debug -->
    <loglevel>4</loglevel>
    <consolelog>0</consolelog>

    <stream>
        <metadata>
            <name>Hoerspiel-Server Playlist</name>
            <genre>produnis</genre>
            <description>Hier spielt die playlist.txt des Hoerspiel-Servers</description>
        </metadata>

        <input>
            <module>playlist</module>
            <param name="type">basic</param>
            <param name="file">/etc/ices2/playlist.txt</param>

            <!-- random play -->
            <param name="random">0</param>
            <!-- if the playlist get updated that start at the beginning -->
            <param name="restart-after-reread">0</param>
            <!-- if set to 1 , plays once through, then exits. -->
            <param name="once">0</param>
        </input>

        <instance>
            <hostname>localhost</hostname>
            <port>8000</port>
            <password>hackme</password>
            <mount>/Playlist.ogg</mount>

            <reconnectdelay>2</reconnectdelay>
            <reconnectattempts>5</reconnectattempts>

            <maxqueuelength>80</maxqueuelength>


            <encode>
                <nominal-bitrate>128000</nominal-bitrate> <!-- bps. e.g. 64000 for 64 kbps -->
                <samplerate>44100</samplerate>
                <channels>2</channels>
            </encode>
        </instance>

        </stream>
</ices>

Du musst hier noch das Passwort „hackme“ gemäß deiner icecast2-Einstellungen anpassen. Es handelt sich hierbei um das Passwort, welches in /etc/icecast2/icecast.xml unter „source-password“ eingetragen wurde.

Neben dieser Konfigurationsdatei benötigen wir noch eine Textdatei namens „playlist.txt“ im Ordner /etc/ices2, in welcher die Pfade zu den einzelnen Ogg-Dateien angegeben werden:

sudo vim /etc/ices2/playlist.txt

Bei mir sieht das so aus:

/media/Musik/Drei.Fragezeichen/01_Superpapagei.ogg
/media/Musik/Prof.van.Dusen/Trifft.Kaiser.Wilhelm.ogg
/media/Musik/Gabriel.Burns/03_Experiment.Stille.ogg

Jetzt kann ices2 wie folgt gestartet werden:

sudo ices2 /etc/ices2/ices-playlist.xml

Im Webinterface von icecast2 wird nun unter „Server Status“ der Playlist-Sender angezeigt, und die potentiellen Zuhörer können über die Webseite den Stream abgreifen.

 
2.2 ALSA-Sound senden
In einem weiteren Radiosender soll der aktuelle ALSA-Sound gestreamt werden, also genau das Signal, welches auch über die Stereoanlagen zu hören ist. Auch hierfür verwende ich eine eigene ices2-Instanz mit eigener Konfigurationsdatei namens ices-current-alsa.xml:

sudo vim /etc/ices2/ices-current-alsa.xml

Diese erhält folgenden Inhalt:

<?xml version="1.0"?>
<ices>
    <background>1</background>
    <logpath>/var/log/ices2</logpath>
    <logfile>ices2.log</logfile>
    <loglevel>4</loglevel>
    <consolelog>0</consolelog>



    <stream>
        <metadata>
            <name>Hoerspiel-Server current ALSA</name>
            <genre>produnis</genre>
            <description>Hier wird die aktuelle ALSA-Soundausgabe des Hoerspielservers gestreamt</description>
        </metadata>


<input>
<module>alsa</module>
 <param name="rate">44100</param><!-- # Samplerate in Hertz, manche Treiber bevorzugen 48000hz-->
 <param name="channels">2</param> <!--# 2 für Stereo, 1 für Mono-->
 <param name="device">hw:0,0</param> <!--# die Soundkarte-->
 <param name="buffer-time">500</param><!-- # Buffergröße in Millisekunden-->
 <param name="metadata">1</param><!-- # Metadaten-Update für Artist und Titel-->
 <param name="metadatafilename">/home/ices2/metadata</param><!-- # Datei aus der Metadaten gelesen werden sollen-->
</input>

        <instance>
            <hostname>localhost</hostname>
            <port>8000</port>
            <password>hackme</password>
            <mount>/ALSA.ogg</mount>

            <reconnectdelay>2</reconnectdelay>
            <reconnectattempts>5</reconnectattempts>

            <maxqueuelength>80</maxqueuelength>

            <encode>
                <nominal-bitrate>128000</nominal-bitrate> <!-- bps. e.g. 64000 for 64 kbps -->
                <samplerate>44100</samplerate>
                <channels>2</channels>
            </encode>
        </instance>

        </stream>
</ices>

Auch hier muss wieder das Passwort „hackme“ gemäß deiner icecast2-Einstellungen anpasst werden. Es handelt sich hierbei um das Passwort, welches in /etc/icecast2/icecast.xml unter „source-password“ eingetragen wurde.

Des Weiteren wird eine Datei namens /etc/ices2/metadata benötigt

sudo vim /etc/ices2/metadata

welche bei mir folgenden Inhalt bekommt:

artist=Hoerspiel-Server
title=current ALSA Stream

Jetzt kann ices2 gestartet werden per

sudo ices2 /etc/ices2/ices-current-alsa.xml

Im Webinterface sollte nun unter „Server Status“ auch dieser Sender aufgelistet werden, so dass die Zuhörer den Stream abgreifen können.

 
2.2.1 Bugfix
Bei mir war es zunächst so, dass ich zwar den ALSA-Stream an meinem Laptop empfangen konnte, dieser jedoch nur Rauschen und Knartzen enthielt. Ein kleiner Blick im Terminal per

cat /proc/asound/devices

zeigt bei mir folgendes an:

0: [ 0] : control
1: : sequencer
4: [ 0- 0]: hardware dependent
16: [ 0- 0]: digital audio playback
24: [ 0- 0]: digital audio capture
33: : timer

Meine Einstellung in der Konfigurationsdatei /etc/ices2/ices-current-alsa.xml ist mit
<param name="device">hw:0,0</param> zwar richtig gesetzt, allerdings sitzen sowohl „playback“ als auch „capture“ jeweils auf Kanal „0“.
ices2 scheint aber nur auf dem capture-Kanal zu lauschen anstatt den playback-Kanal anzuzapfen.
Ich habe daher einfach hinten am PC mit einem Kabel den „Line-Out“ direkt mit dem „Mic“-Eingang verbunden. Per alsamixer (im Terminal) hab ich die Signalstärke etwas angepasst, und jetzt funktioniert es.
alsamixer
Wichtig ist der Eintrag ganz rechts: Die „Input Source“ muss von „Mic“ auf „Stereo M“ ungestellt werden (siehe Abbildung).

Das ist etwas dirty, aber es klappt… 🙂
Bestimmt gibt es aber auch eine Softwarelösung, mit welcher man das Line-Out Singal der Soundkarte auf den Mic-Eingang umleiten kann… ich hab aber „auf die Schnelle“ nix gefunden.

 

3. Startscript

Leider kommt ices2 ohne Init-Script daher, so dass man es von Hand starten und stoppen muss. Falko Timme beschreibt jedoch, wie man das Init-Script von icecast2 umändern kann, so dass icecast2 und ices2 immer zusammen starten und stoppen. Das ist eigentlich genau das, was ich gern für meinen ALSA-Radiosender hätte.

Man editiert mit root-Rechten die Datei /etc/init.d/icecast2

sudo vim /etc/init.d/icecast2

und ändert folgende (rot hinterlegten) Stellen:

#! /bin/sh
#
# icecast2
#
#                Written by Miquel van Smoorenburg <miquels@cistron.nl>.
#                Modified for Debian
#                by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
#                Further modified by Keegan Quinn <ice@thebasement.org>
#                for use with Icecast 2
#

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/icecast2
NAME=icecast2
DESC=icecast2
ICES=/usr/bin/ices2
ICES_CONF=/etc/ices2/ices-current-alsa.xml

test -x $DAEMON || exit 0

# Defaults
CONFIGFILE="/etc/icecast2/icecast.xml"
CONFIGDEFAULTFILE="/etc/default/icecast2"
USERID=icecast2
GROUPID=icecast
ENABLE="false"

# Reads config file (will override defaults above)
[ -r "$CONFIGDEFAULTFILE" ] && . $CONFIGDEFAULTFILE

if [ "$ENABLE" != "true" ]; then
        echo "$NAME daemon disabled - read $CONFIGDEFAULTFILE."
        exit 0
fi

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --chuid $USERID:$GROUPID
                --exec $DAEMON -- -b -c $CONFIGFILE
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_CONF
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --oknodo --quiet --exec $ICES

        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        echo "$NAME."
        ;;
  reload|force-reload)
        echo "Reloading $DESC configuration files."
        start-stop-daemon --stop --oknodo --quiet --exec $ICES
        start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_CONF
        ;;
  restart)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --oknodo --quiet --exec $ICES

        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        sleep 3
        start-stop-daemon --start --quiet --chuid $USERID:$GROUPID
                --exec $DAEMON -- -b -c $CONFIGFILE
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_CONF
        echo "$NAME."
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
        exit 1
        ;;
esac

exit 0

Jetzt startet und stoppt icecast2 immer zusammen mit ices2 im ALSA-Modus – auch beim Hochfahren.

 
Ich betreibe hier ja zwei Sender, und falls beide beim Booten „anspringen“ sollen, verwende ich folgende Einstellungen:

#! /bin/sh
#
# icecast2
#
#                Written by Miquel van Smoorenburg <miquels@cistron.nl>.
#                Modified for Debian
#                by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
#                Further modified by Keegan Quinn <ice@thebasement.org>
#                for use with Icecast 2
#

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/icecast2
NAME=icecast2
DESC=icecast2
ICES=/usr/bin/ices2
ICES_ALSA-CONF=/etc/ices2/ices-current-alsa.xml
ICES_PLAYLIST-CONF=/etc/ices2/ices-playlist.xml

test -x $DAEMON || exit 0

# Defaults
CONFIGFILE="/etc/icecast2/icecast.xml"
CONFIGDEFAULTFILE="/etc/default/icecast2"
USERID=icecast2
GROUPID=icecast
ENABLE="false"

# Reads config file (will override defaults above)
[ -r "$CONFIGDEFAULTFILE" ] && . $CONFIGDEFAULTFILE

if [ "$ENABLE" != "true" ]; then
        echo "$NAME daemon disabled - read $CONFIGDEFAULTFILE."
        exit 0
fi

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --chuid $USERID:$GROUPID
                --exec $DAEMON -- -b -c $CONFIGFILE
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_ALSA-CONF
        start-stop-daemon --start --quiet --exec $ICES $ICES_PLAYLIST-CONF
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --oknodo --quiet --exec $ICES

        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        echo "$NAME."
        ;;
  reload|force-reload)
        echo "Reloading $DESC configuration files."
        start-stop-daemon --stop --oknodo --quiet --exec $ICES
        start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_ALSA-CONF
        start-stop-daemon --start --quiet --exec $ICES $ICES_PLAYLIST-CONF
        ;;
  restart)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --oknodo --quiet --exec $ICES

        start-stop-daemon --stop --oknodo --quiet --exec $DAEMON
        sleep 3
        start-stop-daemon --start --quiet --chuid $USERID:$GROUPID
                --exec $DAEMON -- -b -c $CONFIGFILE
        sleep 3
        start-stop-daemon --start --quiet --exec $ICES $ICES_ALSA-CONF
        start-stop-daemon --start --quiet --exec $ICES $ICES_PLAYLIST-CONF
        echo "$NAME."
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
        exit 1
        ;;
esac

exit 0

Mein Server ist durch das encodieren und streamen nicht wirklich beeinträchtigt, der Prozessor ist zu 60% IDLE und durchschnittlich sende ich pro Zuhörer ca 60 kbps ins Netz.

Viel Spaß beim streamen!

 

Links

This entry was posted in Ubuntu, ubuntuusers. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback.

3 Comments

  1. Cee
    Posted 9. Februar 2010 at 00:06 | Permalink

    Danke für das tolle Tutorial! Auch wenn ich momentan die Zeit nicht finde dies umzusetzen, sind es genau solche Beiträge, die ich mag!

  2. Alex
    Posted 8. Juni 2010 at 22:35 | Permalink

    Hallo,

    hab alles genau so gemacht wie sie beschrieben haben. Es läuft auch alles wunderbar. Aber ices mit dem Icecast beim hochfahren zusammen zu starten klappt nicht. Wird nur ein „ices-playlist.xml“ gestartet, „ices-playlist2.xml“ dagegen nicht. Hab alles 10 mal überprüft, hab alles richtig gemacht, aber es läuft nicht. Bitte helfen sie mir.

    Danke!

  3. Andreas
    Posted 1. Februar 2018 at 20:29 | Permalink

    Hallo,
    ich bekomme den Ices2 über den 3. Startscript nicht ans laufen, ich glaube ich bin dafür zu blöd. Kann man Ices2 nicht seperat starten?
    gruß

Schreibe einen Kommentar

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

Your email address will never be published.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.