Audio streming

Project owner: dron
Interested:
Related:
License: Uveďte původ-Zachovejte licenci CC BY-SA

Základní motivace tohoto projektu je realizace audio streamu ze stage do studia na jednom milém malém festivalu (Letní zvěř 2016). Nicméně tyto principy lze použít kdykoli na cokoli…

Možností a nástrojů jak dostat audio z jednoho místa na druhé je spousta. Zde několik, o kterých vím (určitě to nebude úplný seznam, klidně doplňte…). Samozřejmě se bavím pouze o otevřených systémech a aplikacích…

  • PulseAudio - tento audioserver umí přímo vytvářet a připojovat vzdálené zdroje audio signálu. S úspěchem používám, ale na kabelu. Audio posílám nekomprimovaně, což je náročné na šířku pásma a chybovost média. Dost pravděpodobně naprosto nevhodné pro bezdrát (ale netestováno…)
  • IceCast - stremingový server. Umí streamovat enkodované audio mnoha připojeným klientům pomocí http.

Co se týče konkrétně Letní zvěře, tak to zkusíme udělat s IceCastem a posléze se uvidí, jestli to bylo dobré řešení…

  • Stage:
    • audio výstup z mixu, line-out
    • PC bazmek s line-in vstupem Raspberry PI s externí USB zvukovkou (digitalizace, streaming)
    • WiFi client
  • Studio:
    • WiFi AP
    • PC bazmek s line-out výstupem (příjem streamu)
    • mix
    • výstup z mixu je už streamován na skutečný stream server

Nejjednodušší setup je klient - AP, ale aktuálně použijeme setup původně určený pro UfoBufo2016, což je na třech TP-Link TL-WDR4300 a OpenWRT postavené WDS. Milé je, že LAN porty jsou probridgeované s WLAN, tak stačí APčka zapnout a připojit na každé straně jedno PC (Stage a studio). Detailně popíšu jindy… TODO

Adresace

  • WDS používá subnet 10.0.0.0/21 (255.255.248.0)
  • 3 AP mají adresy 10.0.0.1 - 3
  • PC Stage bude staticky 10.0.0.10/21
  • PC Studio bude staticky 10.0.0.11/21

Na stage bude PC s Line-in vstupem z mixu. Budeme zde típat input source a posílat do ices, který to bude enkodovat a stremovat na druhou stranu do studia.

V Linuxu existuje docela dost audio serverů… Zmíním nastavení pro dva

Alsa sound

Tohle se bude týkat spíše varianty s RB Pi (a externí zvukovkou).

lsusb
lsmod | grep snd.usb.audio

Vypsání audio výstupů

aplay -l

Vypsání audio vstupů

arecord -l

Je potřeba si poznačit Card a Device numbers - alsa device ja pak označeno jako hw:Card,Device (např. hw:0,1).

Nainstalujeme a připravíme config Ices (pozor na řádek <param name=“device”>hw:0,1</param>).

yum install ices
nano /etc/ices.conf
<?xml version="1.0"?>
<ices>
    <!-- run in background -->
    <background>1</background>
    <!-- where logs, etc go. -->
    <logpath>/var/log/ices</logpath>
    <logfile>ices.log</logfile>
    <!-- 1=error,2=warn,3=info,4=debug -->
    <loglevel>4</loglevel>
    <!-- set this to 1 to log to the console instead of to the file above -->
    <consolelog>0</consolelog>

    <!-- optional filename to write process id to -->
    <!-- <pidfile>/home/ices/ices.pid</pidfile> -->

    <stream>
        <!-- metadata used for stream listing (not currently used) -->
        <metadata>
            <name>Letni zver main stage stream</name>
            <genre>Psychedelic</genre>
            <description>Live stream from main stage of Letni zver 2016 festival...</description>
        </metadata>

<input>
    <module>alsa</module>
    <param name="rate">44100</param>
    <param name="channels">2</param>
    <param name="device">hw:0,1</param>
    <param name="periods">2</param>
    <param name="buffer-time">500</param>
</input>

<instance>
    <!-- icecast server, kam budeme audio posilat -->
    <hostname>10.0.0.11</hostname>
    <port>8000</port>
    <password>heslo</password>
    <mount>/letnizver.ogg</mount>
    <reconnectdelay>2</reconnectdelay>
    <reconnectattempts>5</reconnectattempts>
    <maxqueuelength>80</maxqueuelength>
    <encode>
        <nominal-bitrate>64000</nominal-bitrate> <!-- bps. e.g. 64000 for 64 kbps -->
        <samplerate>44100</samplerate>
        <channels>2</channels>
    </encode>
</instance>

	</stream>
</ices>

a spustíme ices

ices /etc/ices.conf

Pulse audio

Situace spíše s plnotučnou moderní Linuxovou distribucí (např. Fedora).

yum install paman ices
nano /etc/ices.conf
<?xml version="1.0"?>
<ices>
    <!-- run in background -->
    <background>0</background>
    <!-- where logs, etc go. -->
    <logpath>/var/log/ices</logpath>
    <logfile>ices.log</logfile>
    <!-- 1=error,2=warn,3=info,4=debug -->
    <loglevel>4</loglevel>
    <!-- set this to 1 to log to the console instead of to the file above -->
    <consolelog>0</consolelog>

    <!-- optional filename to write process id to -->
    <!-- <pidfile>/home/ices/ices.pid</pidfile> -->

    <stream>
        <!-- metadata used for stream listing (not currently used) -->
        <metadata>
            <name>Letni zver main stage stream</name>
            <genre>Psychedelic</genre>
            <description>Live stream from main stage of Letni zver 2016 festival...</description>
        </metadata>

<input>
    <module>stdinpcm</module>
    <param name="rate">44100</param>
    <param name="channels">2</param>
</input>

<instance>
    <!-- icecast server, kam budeme audio posilat -->
    <hostname>10.0.0.11</hostname>
    <port>8000</port>
    <password>heslo</password>
    <mount>/letnizver.ogg</mount>
    <reconnectdelay>2</reconnectdelay>
    <reconnectattempts>5</reconnectattempts>
    <maxqueuelength>80</maxqueuelength>
    <encode>
        <nominal-bitrate>64000</nominal-bitrate> <!-- bps. e.g. 64000 for 64 kbps -->
        <samplerate>44100</samplerate>
        <channels>2</channels>
    </encode>
</instance>

	</stream>
</ices>

Nyní je potřeba zjistit, jaký source (vstup) budeme streamovat. Zajímá nás název source (druhý sloupec, např. alsa_input.pci-0000_00_1b.0.analog-stereo).

pactl list short sources

Poznámka: Pokud má source příponu .monitor, tak se jedná o monitor (odposlech) toho, co hraje na odpovídajícím výstupu.

Poznámka: Pokud bychom chtěli posílat přímo výstup nějaké konkrétní, audio výstup produkující, aplikace, tak viz. https://wiki.archlinux.org/index.php/PulseAudio/Examples#Monitor_specific_output

Ices nemá podporu přímo pro Pulseaudio, ale lze to obejít pomocí modulu stdinpcm a posíláním audia do stdin ices.

parec -d alsa_input.pci-0000_00_1b.0.analog-stereo --raw | ices /etc/ices.conf

Debug

tail -f /var/log/ices/ices.log

Ve studiu bude také PC, kde poběží Icecast…

yum install pulseaudio-utils icecast
nano /etc/icecast.xml
<icecast>
    <limits>
        <clients>100</clients>
        <sources>2</sources>
        <threadpool>5</threadpool>
        <queue-size>524288</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <!-- If enabled, this will provide a burst of data when a client 
             first connects, thereby significantly reducing the startup 
             time for listeners that do substantial buffering. However,
             it also significantly increases latency between the source
             client and listening client.  For low-latency setups, you
             might want to disable this. -->
        <burst-on-connect>0</burst-on-connect>
        <burst-size>65535</burst-size>
    </limits>

    <authentication>
        <source-password>heslo</source-password>
        <relay-password>heslo</relay-password>

        <admin-user>admin</admin-user>
        <admin-password>heslo</admin-password>
    </authentication>

    <hostname>localhost</hostname>

    <listen-socket>
        <port>8000</port>
        <!-- <shoutcast-mount>/stream</shoutcast-mount> -->
    </listen-socket>


    <fileserve>1</fileserve>

    <paths>
        <!-- basedir is only used if chroot is enabled -->
        <basedir>/usr/share/icecast</basedir>

        <!-- Note that if <chroot> is turned on below, these paths must both
             be relative to the new root, not the original root -->
        <logdir>/var/log/icecast</logdir>
        <webroot>/usr/share/icecast/web</webroot>
        <adminroot>/usr/share/icecast/admin</adminroot>
        <pidfile>/var/run/icecast/icecast.pid</pidfile>

        <alias source="/" dest="/status.xsl"/>
    </paths>

    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <!-- <playlistlog>playlist.log</playlistlog> -->
        <loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
        <logsize>10000</logsize> <!-- Max size of a logfile -->
        <!-- If logarchive is enabled (1), then when logsize is reached
             the logfile will be moved to [error|access|playlist].log.DATESTAMP,
             otherwise it will be moved to [error|access|playlist].log.old.
             Default is non-archive mode (i.e. overwrite)
        -->
        <!-- <logarchive>1</logarchive> -->
    </logging>

    <security>
        <chroot>0</chroot>
        <changeowner>
            <user>icecast</user>
            <group>icecast</group>
        </changeowner>
    </security>
</icecast>
service icecast start

a bacha na firewall… (stopnout, nebo povolit přístup na port 8000/tcp)

service firewalld stop

nebo

service iptables stop

Stream je pak dostupný na lokální adrese a portu 8000 např. přes browser.

Tento setup stačí pro stremování audia mnoha dalším uživatelům - záleží na dosažitelnosti adresy icecast serveru.

Pokud chceme stream přehrát přímo na icecast serveru, pak např. utilitkou ogg123 (mpg123, mplayer,…)

ogg123 http://10.0.0.11:8000/letnizver.ogg

Debug

Poslouchá icecast na portu 8000?

netstat -lntp
...
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      3070/icecast
...

A co se děje v logu?

tail -f /var/log/icecast/*.log
  • Příště je potřeba dovézt uchozené a otestované kompletní řešení. Bastlit to na místě bylo mírně stresující…
  • Reálně byl na stage použit malý NB s externí zvukovkou a streamerem BUTT. Problém byl s uchozením externí zvukovky na RbPi (aspoň v rámci časového presu - otestovat a dopsat TODO).
  • WiFi fungovala bezproblémově, ale to se celkem čekalo, bylo to na cca 75m a přímou viditelnost (https://mapy.cz/s/12INt)
  • Nakonec byl místo ogg streamu použit mp3 192kbit stream. Ogg se z neznámých důvodů dost sekal (streamer bylo RbPi, které se ale nakonec nepoužilo)
  • Na stage běžel Icecast na RbPi a load minimální (ale reálně byl jen 1 klient, ).
  • Z nouze byl mezi Icecastem a mixem ještě vetknutý můj notebook, který přijímal stream a hrál jej pomocí mpg123 na lokální zvukovce.

tmp

Tohle je jen dočasný bordel z předchozího pokusu. Protřídit TODO…

instalace na labkovy centos6

yum install pulseaudio-utils icecast
yum localinstall ftp://ftp.pbone.net/mirror/li.nux.ro/download/nux/dextop/el6/i386/ices-2.0.1-10.el6.nux.i686.rpm

seznam sinku na starsi verzi pactl

LANG=C pactl list | grep -A2 'Source #' | grep 'Name: ' | cut -d " " -f2