2016. június 26., vasárnap

ffmpeg encoder relay

A nyár során a hétvégéimet általában a Balatonon töltöm, az északi parton a nyaralónkban. Az internetelérés szezonról-szezonra visszatérő probléma szokott lenni, de tavaly óta UPC mobil előfizető vagyok, így jár a korlátlan mobilinternet elérés, 1 Mbps sávszélességgel.

2016-ban teljesen valid kérdés, hogy ekkora sebesség ugyan mégis mire elég (ha elég egyáltalán), de ez a bejegyzés most nem erről fog szólni. Rövidre zárva a gondolatot, 1 Mbps böngészésre jó, és a 480p-s Youtube-os videók is szépen betöltődnek.

Ilyen sebességkorlát mellett az ember azért meggondolja, hogy minek a letöltésével fogja az elkövetkező perceit vagy óráit eltölteni. Pont úgy mint a régi időkben. Ez egyébként még egy megoldható probléma, viszont a mostani hétvégén pont úgy jött ki a lépés, hogy a Defqon 1 élő rádió közvetítését is akartam hallgatni, amit MP3 formátumban streamelnek, 256 kbps-os bitrátával. 1 Mbps-ből (1000 kbps) konstans 256 kbps-ot elvenni azért elég súlyos; ez a sávszélesség negyede. Nyilvánvalóvá vált a feladat: valahogy meg kell oldanom, hogy alacsonyabb bitrátájú streamet hallgathassak. Mivel ilyen csatornát nem üzemeltettek, ezért nekem kellett felállítanom egy olyan átjárót (relayt), ami élőben hatékonyabb tömörítéssel újrakódolja a rádió adást.

Hardver

Mindenképp kell lennie egy szervernek valahol, ami elég erős az folyamatos élő átkonvertáláshoz, illetve ugye a feltöltési sebesség is fontos. Az eredeti stream 256 kbps; ennél jóval kisebb bitrátájú adást akarok sugározni, legfeljebb 128 kbps-osat, szóval ennyi upload kell.

Két helyről tudtam megoldani a feltöltést: a szüleim házában üzemel egy Odroid X2, illetve az albérletemben egy Raspberry Pi 2 látja el a szerver feladatát. Most ez utóbbit választottam a feladatra, mivel úgy 50ms-al kisebb volt a pingem felé. A feltöltés mindkét helyen 10 Mbps, ezzel tehát nincs gond.

Szoftver

Konvertálásokra kérdés nélkül az ffmpeg-et használom, (vagy nagyon ritkán a gstreamer-t). Az ffmpeg több mint egy svájci bicska, amit ez nem tud kezelni, azt valószínűleg más se (mivel hogy sok média lejátszó egyszerűen az ffmpeg-et használja backendként). Az ffmpeg csomag tartalmazza az ffserver programot is, ami majd kiszolgálja az átkonvertált stream-et. Egy fontos kérdés maradt: mivel konvertáljunk?

Encoder

Az MP3 a legnépszerűbb veszteséges audio formátum, de rajta kívül egy csomó modernebb és hatékonyabb tömörítő eljárás létezik még, amik tehát alacsonyabb bitráta mellett is hozzák az MP3 minőségét.

Egyszer szívesen írnék egy nagyobb összehasonlítást a különböző hangkodekekről, mert mindig is imádtam a témát.

Az ffmpeg wikijén találtam egy sorrendet, hogy melyik formátum mennyire hatékony a többihez képest. A libfdk_aac-ot már többször használtam is, és nagyon jó tapasztalataim voltak vele. A libvorbis-al is volt már tapasztalatom, de a libopus új volt nekem, úgyhogy végeztem egy gyors összehasonlítást köztük. Ehhez egy WAV-ban rögzített zenét konvertáltam át a két encoder segítségével, különböző bitrátákkal kombinálva.

A gyors teszt végeredménye alapján a libopus encodert választottam, 64 kbps-os bitrátával.

Forrás minősége

64 kbps-on még a fenti kodekek is érezhetően gyengébb minőséget produkálnak, de az azonos tulajdonságú MP3-hoz képest összehasonlíthatatlanul több marad meg a zenéből, tehát érdemes a konvertálás. A forrás, ami élő közvetítés a fesztiválról, valószínűleg nem a DJ keverőjének outputja, vagy ha mégis akkor elég erős kompresszor van rajta, de ami fontosabb hogy hallható a közönség hangja is. Magyarul tehát a forrás kicsit torz, tele fütyüléssel és ordibálással. A konvertálás során elveszett részletek tehát majd hogy még javítanak is a hang minőségén.

libfdk_aac

Ez az encoder nem része az ffmpeg csomagjának, mivel a licence nem kompatibilis az ffmpeg-ével. Ez rossz pont, de szerencsére mindig saját magam fordítom az ffmpeg-et forrásból (e leírás szerint), és mindig belefordítom ezt a kodeket is, ezért is tudtam elvégezni az összehasonlítást.

libopus

Az Opus egy teljesen szabad formátum, aminek amúgy igen széles a támogatottsága, így akár a telefonomon is tudom hallgatni, még a böngészőből is.

Setup

Na jó, megérkeztünk végre az izgalmas részhez. Az ffserver beállításait egy config fájlba kell írni, ami nagyjából így néz ki:

HTTPPort 8080
HTTPBindAddress 0.0.0.0

MaxHTTPConnections 2
MaxClients 2
MaxBandwidth 1024

<Feed bestofdq1.ffm>
    ACL allow 127.0.0.1
    FileMaxSize 512K
    Launch ffmpeg -i http://audio.true.nl/BESTOFDQ1
</Feed>

<Stream bestofdq1.ogg>
    Feed bestofdq1.ffm

    Format ogg
    AudioCodec libopus
    AudioBitRate 64
    AudioChannels 2
    AudioSampleRate 48000
    AVOptionAudio flags +global_header

    NoVideo
</Stream>

<Stream status.html>
    Format status
</Stream>

Az első két sor írja le hogy a szerver milyen porton és milyen címről fogad kapcsol. A 8080-as portot tehát ki kell nyitni ha router mögött vagyunk, a 0.0.0.0 pedig azt jelenti, hogy bárki kapcsolódhat a szerverre. Az ezt követő három sor a kapcsolatok számát és a maximális kimenő sávszélességet jelöli. A MaxBandwidth mértékegysége kbps.

Ez után a <Feed> jelöli azt a végpontot, ahonnan az ffserver adatot vár majd. Az ffmpeg majd a konvertált adatot ide fogja küldeni. Az ACL sor azt jelöli, hogy milyen címről fogadhat kapcsolatot az ffserver. A példban ez a localhost. A FileMaxSize a szerver buffer mérete. Én nem akartam sokáig bufferelni, ezért ez kellően kicsi érték lett. A Launch mellé kerül az a parancs, amit az ffserver elkezd futtatni amikor a feed életre kel. Itt nagyon egyszerűen csak az ffmpeg-et és az input elérési útvonalát kell megadni. A feed címét az ffserver automatikusan a parancs végére helyezi majd.

A <Stream> szekcióba kerül a stream neve, alá pedig a kódolás tulajdonságai. Tételesen:

  • Feed bestofdq1.ffm: A stream ebből a forrásból fog táplálkozni
  • Format ogg: ogg konténer formátumba kerül beágyazásra az opus stream
  • AudioCodec libopus: Kodeknek a libopus-t használjuk
  • AudioBitRate 64: A bitráta 64 kbps
  • AudioChannels 2: A hang kétcsatornás
  • AudioSampleRate 48000: A mintavételezési frekvencia 48 kHz
  • AVOptionAudio flags +global_header: Header információk bekerülnek a streambe
  • NoVideo: Nincs video stream

Egy <Feed>-hez több <Stream> is tartozhat, azaz ugyan azt a forrást több különböző módszerrel is átalakíthatjuk, és mind egy-egy stream lesz majd.

A fájl végén, a <Stream status.html> egy HTML kiterjesztésű stream-et definiál. Ezen belül a Format status egy olyan formátum, ami a szerver állapotáról szóló weboldalt állít elő.

Futtatás

Most már nincs sok hátra. Mondjuk hogy a fenti fájlt config.conf-nak nevezzük el, akkor így tudjuk elindítani a szervert:

ffserver -f config.conf

Ha minden rendbe van, akkor igazából a verzió információkon kívül semmit sem mutat az ffserver. Nyissuk meg 127.0.0.1:8080/status.html oldalt a böngészőben. Itt látszódni fognak a streamek, ki lehet másolni a címet, és mehet is a foobar-ba, vagy szólhat a böngészőből és kész is.

Zárás

Az eredeti stream mellett 744 kbps maradna böngészésre, így viszont 936 marad, ami 25.8%-al több. Teljesen megérte.

-slp

Nincsenek megjegyzések:

Megjegyzés küldése