Vysílání a přenos audio signálu ve velmi vysoké kvalitě do sítě Internet - rozvoj projektu
Technická zpráva CESNETu
číslo 16/2004
k dispozici též ve formátech PDF,
PostScript a
XML.
Miloš Wimmer
12. 12. 2004
1 Úvod
V roce 2003 jsme zahájili živé vysílání programu stanic Českého rozhlasu do sítě Internet ve velmi vysoké kvalitě.
Vytvořili jsme experimentální systém využívající technologii vysílání audio signálu v kompresních formátech MPEG (mp3) a ogg v šířce pásma 128 kb/s, později jsme vysílání rozšířili o stream ogg se šířkou pásma 256 kb/s.
Technické řešení bylo z důvodů odlišných nároků procesu kódování a streamování rozloženo na dva stroje - server pro kódování a server pro streamování. Na úrovni programového vybavení jsme zvolili na pozici enkodérů aplikaci DarkIce [6], na pozici streamovacího serveru aplikaci icecast2 [3]. Oba produkty jsou vyvíjeny jako OpenSource projekty a lze je použít volně. Na obou strojích běžel operační systémem Linux v distribuci Debian [7].
Server pro kódování zpracovával vstupní signály z analogových tunerů připojených na zvukové karty Sound Blaster Audigy. Aplikace DarkIce prováděla přes rozhraní OSS vzorkování (44.1 kHz, 16 bitů, 2 kanály) a kódování analogových signálů do streamů obou formátů (ogg a mp3) a toků (128 kb/s a 256 kb/s) současně. Hotové streamy pak vysílala aplikačnímu serveru icecast na streamovacím serveru, k němuž se připojovali jednotliví klienti, kteří chtěli vysílání přijímat. Tímto způsobem jsme zajišťovali vysílání rozhlasových stanic ČRo1 - Radiožurnál, ČRo2 - Praha a ČRo3 - Vltava.
Podrobný popis celého experimentálního systému a procesu zpracování byl publikován v technické zprávě Cesnetu číslo 24/2003 [1].
2 Zpracování analogového signálu v reálném čase více aplikacemi současně
Při použití výše uvedeného systému jsme mohli vkládat aktualizovaná metadata (doprovodné textové informace o právě vysílaném programu) jen do streamů vysílaných ve formátu mp3, protože aplikace DarkIce přidávání metadat nepodporuje a icecast server umožňuje vzdálené zadávání metadat přes http požadavek jen pro mp3 streamy (navíc je to považováno za zastaralou funkci).
Řešením mohlo být rozdělení produkce ogg a mp3 streamů mezi dvě aplikace - ogg streamy by generovala aplikace ices2, která vkládání metadat podporuje a vytváření mp3 streamů by se ponechalo aplikaci DarkIce. Původní verze DarkIce 0.13 však podporovala jen zvuková zařízení s ovladači pro rozhraní OSS, které vícenásobný přístup ke zvukovému zařízení vylučuje - na rozdíl od moderního rozhraní Alsa [8].
V první polovině roku 2004 jsme použili novou verzi DarkIce 0.14, která již Alsa rozhraní a ovladače podporovala.
Pro možnost vícenásobného čtení z jedné zvukové karty je třeba v konfiguračním souboru Alsa subsystému definovat virtuální zařízení pluginem dsnoop. Ukázka konfigurace Alsa v souboru /etc/asound.conf pro dvě zvukové karty otevřené se vzorkovací frekvencí 44.1 kHz:
pcm.karta0 {
type dsnoop
ipc_key 100000
ipc_key_add_uid true
slave {
pcm "hw:0"
rate 44100
}
}
pcm.karta1 {
type dsnoop
ipc_key 100001
ipc_key_add_uid true
slave {
pcm "hw:1"
rate 44100
}
}
V konfiguraci klienta, který čte data z příslušné zvukové karty, je pak vstupní zařízení definováno zápisem:
device = karta0
namísto původního OSS zařízení:
device = /dev/dsp
nebo "obyčejného" Alsa zařízení:
device = plughw:0,0
Tímto způsobem se nám podařilo dosáhnout stavu, kdy aplikace DarkIce generovala jen mp3 stream a aplikace ices2 generovala ogg streamy. Obě aplikace četli vstupní data ze stejné zvukové karty současně prostřednictvím virtuálních zařízení definovaných pluginem dsnoop. Metadata byla do mp3 streamu vkládána vzdáleně http požadavkem pomocí příkazu:
curl -s -u USER:HESLO "http://radio.cesnet.cz:8000/admin/metadata?mount=/STANICE.mp3&mode=updinfo&song=VLASTNI_TEXT"
Aplikace ices2 podporuje vkládání metadat do ogg streamů přímo a to definicí textového souboru metadat ve svém konfiguračním souboru. Soubor metadat obsahuje informace o názvu stanice a aktuálním programu ve formátu:
artist=CRo2 title=Dobre odpoledne preje Jan Burda
Metadata získáváme z XML dat programového systému Českého rozhlasu.
Při zaslání signálu -USR1 běžícímu procesu aplikace ices se načte aktuální
obsah metadatového souboru a vloží se do vysílaného ogg streamu.
S běžným vstupním Alsa zařízením funguje ices skvěle, ale při použití
virtuálního zařízení definovaném pluginem dsnoop jsme zjistili chybu
icesu. Při poslání signálu -USR1 se totiž jeho běh ukončí.
Použili jsme proto neoficiální verzi icecast-2.0-kh22 serveru [4], která
podporuje vzdálené vkládání metadat http požadavkem pro mp3 i ogg streamy.
Přesto považujeme technologii konkurenčního přístupu více aplikací k jednomu zvukovému zařízení za významnou, protože umožňuje kombinovat různé druhy zpracování vstupního signálu současně (např. jej kódovat do různých formátů streamů a přitom zaznamenávat do archivu na disk).
Po dobu tří měsíců jsme vysílali ogg i mp3 streamy všech tří stanic Českého rozhlasu s kompletními metadaty. Na začátku léta jsme s Českým rozhlasem dospěli k dohodě, že vysílání mp3 streamů ukončíme. K tomuto rozhodnutí nás vedla především skutečnost, že formát MP3 je zatížen patentovými nároky a licencemi. Od této doby vysíláme streamy 128 kb/s a 256 kb/s pouze ve formátu ogg. Tyto streamy jsou produkovány aplikací ices s přímo vkládanými metadaty.
2.1 Zpracování signálu z DVB-S
Dalšího zvýšení kvality přenášeného zvuku jsme dosáhli změnou vstupního signálu. Analogové tunery jsme nahradili DVB-S kartou a vysílání stanic ČRo1, 2, 3 a nově Čro6 a Region přebíráme přímo ze satelitu Eurobird 1. Výsledný zvuk je v porovnání se signálem přebíraným z analogových tunerů čistější, více detailní a má lépe separované kanály.
Zpracování signálů z DVB-S karty, jejich transkódování a produkci ogg streamů provádí nový server tun2.cesnet.cz umístěný na sále Západočeské univerzity v Plzni.
Fyzicky jde o server v konfiguraci:- Dell PowerEdge 1800
- 2x procesor P4 Xeon/3.4GHz, 1GB RAM
- síťová karta Intel PRO/1000 Fibre
- DVB-S karta Hauppauge WinTV NOVA-S-CI vybavená CI slotem
- zvuková karta Sound Blaster Audigy
Při primárním zpracování signálů 7-mi stanic a jejich transkódování do 14-ti výstupních ogg streamů vykazuje server zatížení/load kolem 1.5 a idle kolem 65%.
Na serveru jsou nainstalovány tyto klíčové komponenty:
- operační systém Linux Debian (sid)
- jádro 2.6.9
- glibc-2.3.2
- alsa-1.0.6a
- libvorbis-1.0.1
- libdvb-0.2.2
- vls-0.5.6
- vlc-0.8.1
- libshout-2.0-kh29
- ices-2.0-kh59
- linuxtv-dvb-apps-1.1.0
Do jádra je vložena podpora DVB karty následujícími parametry:
- DVB For Linux
- DVB Core Support
- STV0299 based DVB-S frontend (QPSK)
- Budget cards with onboard CI connector
Vzhledem k tomu, že potřebujeme zpracovávat několik programů rozhlasových stanic současně,
použili jsme pro příjem programů aplikační server vls [5]. Ten dokáže
přijímat všechny programy vysílané v daném paketu (v našem případě Czechlink) najednou,
oddělit je od sebe a pak je v nezměněném formátu (MPEG-TS) poskytnout k dalšímu zpracování
- např. vysílat na určené multicastové nebo unicastové adresy.
V našem řešení vysílá vls server programy ČRo1, 2, 3, 6, Region a BBC v originálním
formátu MPEG Transport Stream na vyhrazené multicastové adresy v síti Cesnet. Tím
umožňujeme uživatelům, kteří mají k multicastu v síti Cesnet přístup, přijímat
streamy v nezměněné podobě. Ke zpracování těchto streamů doporučujeme použít klienta
vlc [5], který je vyvíjen jako OpenSource projekt a lze jej volně použít na řadě
dnes dostupných operačních systémů.
Každý MPEG-TS stream vysílaný aplikací vls přijímá na témže serveru klient vlc,
který stream dekóduje do podoby čistého PCM signálu, který je následně zpracováván
aplikací ices. Ta jej kóduje do ogg streamů v rychostech 128 a 224 kb/s a vysílá
na stremovací server amp.cesnet.cz umístěný na sále Cesnetu v Praze, k němuž
se pak připojují běžní klienti/posluchači.
Pro větší srozumitelnost popíšeme rozdíl mezi vysílanými MPEG-TS a ogg streamy.
MPEG-TS streamy vysílané aplikací vls z kódovacího serveru tun2.cesnet.cz nejsou
poznamenány žádnou následnou konverzí a jsou vysílány v originální podobě
získané při příjmu ze satelitu (MPEG-TS, vzorkovací frekvence 48 kHz,
tok 192 kb/s).
vls server vysílá vždy daný stream na určenou adresu, takže tento způsob nelze
použít pro připojování běžných (unicastových) klientů. S výhodou lze použít
vysílání na multicastovou adresu, přes kterou mohou daný stream přijímat všichni
klienti, kteří se k ní mohou připojit - v našem případě jde o omezené množství
uživatelů sítě Cesnet, jejichž počítače mají multicastovou konektivitu.
Ogg streamy vysílané aplikací icecast ze serveru amp.cesnet.cz prošly transkódovacím
procesem z formátu MPEG-TS do PCM a poté do ogg (vzorkovací frekvence 48 kHz,
toky 128 nebo 224 kb/s), ale tato konverze je při běžném poslechu a dosažené
vysoké kvalitě neznatelná. Ogg streamy nabízené icecast serverem jsou přitom
dostupné běžným protokolem HTTP všem uživatelům v Internetu.
Pro příjem vysílání požadované stanice DVB-S kartou je třeba do příslušného konfiguračního souboru zapsat parametry satelitu (Eurobird 1), paketu (Czechlink) i jednotlivých programů. Obsah našeho souboru dvbrc vypadá takto:
LNB ID 0 TYPE 1 LOF1 9750000 LOF2 12800000 SLOF 11700000 DISEQCNR 3 SAT ID 999 NAME "Eurobird" LNBID 0 FMIN 11200000 FMAX 12800000 TRANSPONDER ID 001 SATID 999 TYPE 0 FREQ 12607000 POL H SRATE 27500000 FEC 3/4 CHANNEL ID 12 NAME "CRo 1" SATID 999 TPID 1 SID 12 TYPE 0 CHANNEL ID 13 NAME "CRo 2" SATID 999 TPID 1 SID 13 TYPE 0 CHANNEL ID 14 NAME "CRo 3" SATID 999 TPID 1 SID 14 TYPE 0 CHANNEL ID 15 NAME "Proglas" SATID 999 TPID 1 SID 15 TYPE 0 CHANNEL ID 16 NAME "CRo 6" SATID 999 TPID 1 SID 16 TYPE 0 CHANNEL ID 17 NAME "CRo Region" SATID 999 TPID 1 SID 17 TYPE 0 CHANNEL ID 18 NAME "BBC" SATID 999 TPID 1 SID 18 TYPE 0
Konfigurační soubor aplikace vls obsahuje definice vstupních zařízení (v našem případě dvb), definice cílových adres a portů určených pro vysílání MPEG-TS streamů a příkazy pro zahájení vysílání jednotlivých programů na určené adresy. Podstatné položky souboru vls.cfg obsahujícího definice pro vysílání dvou programů ČRo1 a ČRo2 mají tuto podobu:
# vls configuration file (Example) # Application wide settings BEGIN "Vls" LogFile = "/usr/opt/vls/logs/vls.log" # log file ScreenLog = "enable" # log to the console SystemLog = "disable" # log to the systemlog END # Streams sources declaration BEGIN "Inputs" dvb = "dvb" # Video input example (DVB card) END # Video input (DVB) configuration BEGIN "dvb" DeviceNumber = "0" # /dev/dvb/adapter SendMethod = "0" # 0 - Send All Pids # 1 - Send only MPEG2 datas END # Channel (outputs) declaration BEGIN "Channels" localhost = "network" multicast1 = "network" multicast2 = "network" END # Channels configuration BEGIN "localhost" # The client is on the same host as the server DstHost = "127.0.0.1" DstPort = "1234" END BEGIN "multicast1" Type = "multicast" TTL = "10" DstHost = "233.11.36.1" DstPort = "1234" END BEGIN "multicast2" Type = "multicast" TTL = "10" DstHost = "233.11.36.2" DstPort = "1234" END # Commands automatically lanched on Startup # Commands shall be like they would be typed in a telnet console. BEGIN "LaunchOnStartUp" command1 = "start CRo_1 multicast1 dvb" command2 = "start CRo_2 multicast2 dvb" END
Označení CRo_1 přitom odpovídá definici "CRo 1" v souboru dvbrc.
Jak jsme uvedli výše, jednotlivé MPEG-TS streamy vysílané do počítačové sítě
aplikací vls přijímáme na témže stroji klienty vlc připojenými na příslušné
multicastové adresy na defaultní port 1234. Klienta používáme k dekódování
streamu do PCM dat a protože vlc nepodporuje výstup dat na standardní výstup
a my potřebujeme z PCM dat generovat výsledný ogg stream, necháme klienta
vlc zapisovat PCM data do pojmenované roury (tedy do souboru odpovídajícího
frontě FIFO).
Obsah pojmenované roury přivádíme na standarní vstup aplikace ices2, která
z něj produkuje výsledný ogg stream, který posílá na cílový icecast server,
k němuž se připojují klienti (např. xmms, winamp, zinf, qcd) koncových posluchačů.
Podstatné položky konfiguračního souboru ices-cro1.xml programu ices pro produkci ogg streamů vysílání ČRo 1 v rychlostech 128 a 224 kb/s vypadají takto:
<?xml version="1.0"?>
<ices>
<background>0</background> <!- run in background? (unimplemented) ->
<logpath>/usr/opt/ices/logs</logpath> <!- where logs, etc go. ->
<logfile>ices-cro1.log</logfile>
<loglevel>3</loglevel> <!- 1=error,2=warn,3=info,4=debug ->
<logsize>204800</logsize> <!- the size the log file must be before rotation ->
<consolelog>0</consolelog> <!- logfile is ignored if this is set to 1 ->
<pidfile>/usr/opt/ices/run/ices-cro1.pid</pidfile> <!- file to write process id to ->
<stream>
<name>CRo1 - Radiozurnal</name>
<genre>news</genre>
<description>News and current affairs station</description>
<input>
<module>pcm</module>
<param name="rate">48000</param>
<param name="channels">2</param>
<param name="metadatafilename">/usr/opt/ices/meta/cro1.meta</param> -> <!- read metadata from file on USR1 ->
<param name="timeout">5</param> <!- If missing or zero then no timeout on reading PCM ->
</input>
<runner>
<instance>
<shout>
<hostname>amp.cesnet.cz</hostname>
<port>8000</port>
<password>toto_neni_skutecne_heslo_;-)</password>
<mount>/cro1.ogg</mount>
<yp>1</yp> <!- allow stream to be advertised on YP, default 0 ->
<reconnectdelay>5</reconnectdelay>
<reconnectattempts>-1</reconnectattempts>
</shout>
<encode>
<quality>4</quality>
</encode>
</instance>
<instance>
<shout>
<hostname>amp.cesnet.cz</hostname>
<port>8000</port>
<password>ani_toto_neni_skutecne_heslo_;-)</password>
<mount>/cro1-256.ogg</mount>
<yp>1</yp> <!- allow stream to be advertised on YP, default 0 ->
<reconnectdelay>5</reconnectdelay>
<reconnectattempts>-1</reconnectattempts>
</shout>
<encode>
<quality>7</quality>
</encode>
</instance>
</runner>
</stream>
</ices>
Vlastní proces transkódování MPEG-TS streamu vysílaného aplikací vls (v našem případě CRo1) do ogg streamu je tedy tvořen vzájemnou komunikací mezi běžícími procesy vlc a ices spuštěnými s těmito parametry:
vlc -intf dummy -aout file -audiofile-file $PIPE -no-audiofile-wav -volume 500 -server-port 1234 udp://@233.11.36.1 >/dev/null 2>&1 & echo $! > $VLCPIDFILE cat $PIPE | ices ices-cro1.xml >/dev/null 2>&1
3 Technické podrobnosti
Naše původní představy o vylepšení experimentálního systému pro přenos audio signálu ve velmi vysoké kvalitě do sítě Internet byly založeny na tom, že rozdělíme proces primárního zpracování vstupního signálu a proces jeho transkódování mezi dva vzdálené stroje. Chtěli jsme použít málo výkonný server s DVB-S kartou, který by aplikací vls posílal MPEG-TS streamy přijaté ze satelitu do sítě multicastem (k tomu není třeba velkého výpočetního výkonu ani jiných systémových zdrojů). Ze sítě by pak stream mohli přijímat libovolní klienti - tedy i klient na našem kódovacím serveru, který je vybaven patřičným výkonem CPU potřebným na transkódování streamu.
Zjistili jsme však kritické nároky na zajištění zcela rovnoměrné datové propustnosti mezi serverem s aplikací vls a serverem s klientem vlc. Přestože byly oba servery připojeny na gigabitovou páteřní síť do stejné VLAN, objevovaly se v PCM datech klienta vlc občasné poruchy v podobě "frekvenčního uklouznutí" zvuku. Slyšitelé to bylo např. při hře smyčcových nástrojů nebo zpěvu, kdy se zdálo, že hudebníci zahráli falešně. K těmto potížím docházelo zřídka a jen na několik sekund, takže odhalit příčinu nebylo snadné. Problém částečně eliminovalo zařazení několikasekundového bufferu na vstup klienta vlc a použití protokolu rtp, ale nebyl odstraněn zcela. Po provední různých měření jsme dospěli k závěru, že na problému se podílí chvilkové vyšší zatížení propojovacích aktivních prvků (jinak však dostatečně dimenzovaných). Experimentálně jsme ověřili, že by vyhovovalo vzájemné propojení obou serverů kříženým kabelem, ale při tom by musely být oba servery ve stejné lokalitě a blízko sebe, takže oddělení přijímací části (vls) od produkce ogg streamů by pozbylo smyslu. Proto jsme se rozhodli umístit obě části na stejný server s dostatečným výkonem s tím, že do sítě vysílá originální MPEG-TS i transkódované ogg streamy současně. Přenos ogg streamů z kódovacího serveru na icecast server již není na případné nerovnoměrnosti datové propustnosti kritický a výsledný zvuk je bez chyby.
Dále jsme se setkali s tím, že při výpadku trasy mezi kódovacím serverem a icecast
serverem na dobu delší než několik sekund nenaváže aplikace ices se serverem
nové spojení, přestože v systému zůstává v běhu. K těmto situacím ztráty vzájemné
konektivity téměř nedochází, ale vyloučit zcela je nelze.
Použili jsme proto upravenou neoficiální verzi aplikace ices-2.0-kh59 [4], která se
chová tak, že se při přerušení spojení s icecast serverem ukončí. My spouštíme
celý proces transkódování v shellu ve smyčce, takže v případě ukončení běhu ices
počkáme několik sekund a proces opět spustíme. Tím jsme zajistili automatické
obnovení funkce celého systému po znovuzískání konektivity mezi oběma servery.
4 Popis současného zapojení systému
Primárním kódovacím serverem je nyní tun2.cesnet.cz umístěný na Západočeské univerzitě v Plzni. Tento stroj produkuje z programů získávaných z DVB-S streamy rozhlasových stanic ČRo 1, 2, 3, 6 a Region a také BBC. Dále generuje stream stanice ČRo Plzeň získavané primárně ze signálu analogového tuneru připojeného na zvukovou kartu serveru. Všechny výstupní streamy jsou vysílány ve formátu ogg a v rychlostech variabilní šířky pásma (VBR) 128 a 224 kb/s na původní icecast server běžící na stroji amp.cesnet.cz. Kromě toho jsou streamy získávané primárně z DVB-S vysílány v nezměněném formátu MPEG-TS multicastem na přidělené adresy.
Původní kódovací server tun1.cesnet.cz produkuje ogg streamy stanice ČRo Regina, která je primárně získávána ze signálu analogového tuneru připojeného na zvukovou kartu serveru a vysílá je na icecast server amp.cesnet.cz. Oba stroje tun1.cesnet.cz i amp.cesnet.cz jsou umístěny na sále Cesnetu v Praze.
Vysílané ogg streamy jsou dostupné z WWW stránky serveru na adrese http://radio.cesnet.cz/ [2] a také na stránkách živého vysílání Českého rozhlasu.
Server vysílá tytéž streamy i v IPv6 na adrese amp-ipv6.cesnet.cz a portech 8006.
MPEG-TS streamy jsou vysílány multicastem na adresy
- ČRo 1: udp://@233.11.36.1
- ČRo 2: udp://@233.11.36.2
- ČRo 3: udp://@233.11.36.3
- ČRo 6: udp://@233.11.36.4
- ČRo Region: udp://@233.11.36.6
Topologii zapojení celého systému zachycuje obrázek.
Obrázek 1: Schéma zapojení zařízení
Použitá literatura
| [1] | http://www.cesnet.cz/doc/techzpravy/2003/icecast/ |
| [2] | http://radio.cesnet.cz/ |
| [3] | http://www.icecast.org/ |
| [4] | http://mediacast1.com/~karl/ |
| [5] | http://www.videolan.org/ |
| [6] | http://darkice.sourceforge.net/ |
| [7] | http://www.debian.org/ |
| [8] | http://www.alsa-project.org/ |