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…
Setup
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 vstupemRaspberry 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
WiFi
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
Stage
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
Studio
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
Poznámky ze Zvěře
- 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