» »

Gstreamer -- švicarski nož za mešetarjenje z videom

Vsakdo si je že kdaj zaželel posneti kakšno malenkost s svojo spletno kamero in potem to stvar objaviti nekje v spletu. Marsikdo si je zaželel tudi predvajanja v živo. Spletna kamera, splet in subjekt pred kamero so tri poglavitne sestavine, ki jih potrebujemo za takšen projekt. Manjka še ena malenkost v obliki računalnika in programske opreme, ki vam na koncu omogočata, da vašo kreativnost prelijete na trdi disk in kasneje v splet. Računalnikov in programske opreme je malo morje zato se bomo omejili na precej ozko področje, uporabili bomo osebni računalnik in s pomočjo proste programske opreme posneli kratek video in ga objavili v spletu.

Navodila v tem članku so bila preizkušena na Ubuntu 9.10 (Karmic Koala) z GStreamer 0.10.25. Od bralca se pričakuje, da so mu domače osnove ukazne vrstice ter da se ne boji po potrebi namestiti dodatnih paketkov.

GStreamer je odprto-kodno ogrodje za razvoj multimedijskih aplikacij in je sestavljeno iz osnovne knjižnice s programerskim vmesnikom in sistemom za razhroščevanje. Na vrhu tega pa čepi en kup vtičnikov (pluginov), ki skrbijo za milijon različnih stvari vse od branja različnih video in avdio formatov do raznih posebnih efektov.

GStreamer sam po sebi ne ni bil kaj preveč uporaben za slehernika a na srečo obstaja tudi gst-launch. Majhen program, ki ga zaženemo iz ukazne vrstice in omogoča delo s prav vsemi deli GStreamerja. Gst-launch je precej močno orodje in z njim lahko počnemo tisoč in eno stvar. Omejujeta nas samo nabor vtičnikov in dodatkov za Gstreamer ter domišljija.

Skozi oči kamere

Spletne kamere se ponavadi povezujejo z računalnikom preko USB vmesnika, na vrhu tega čepi nabor gonilnikov, ki se jim reče video4linux2, ki skrbi tudi za marsikatero drugo stvar poleg spletnih kamer. Seznam podprtih spletnih kamer je kar obširen in se veča iz dneva v dan. Najnovejši seznam pa se nahaja na http://linux-uvc.berlios.de/ - gre za standardiziran razred naprav na USB vodilu, ki se sistemu predstavljajo kot kamere oziroma viri slike in videa. USB Video Class ali UVC na kratko tako zajema vse od spletnih kamer, do digitalnih kamer in TV kartic. Vse te naprave pa lahko kontroliramo z enim samim standardiziranim gonilnikom. Vsaj v teoriji.

Sedaj, ko je spletna kamera priklopljena na računalnik lahko s pomočjo GStreamerja in programa gst-launch preizkusimo ali kamera v resnici tudi deluje.

gst-launch v4l2src device=/dev/video0 ! \
'video/x-raw-yuv,width=640,height=480,framerate=30/1' ! \
xvimagesink


Mami, lej k sem na televiziji!



GStreamer in z njim program gst-launch deluje na principu cevovoda. Najprej določimo izvir potem sestavimo cevovod in na koncu določimo ponor. V našem primeru smo za izvir določili video4linux2 in določili napravo /dev/video0. Slednjega sicer ni potrebno storiti saj gst-launch vzame prvo napravo, ki je na voljo. Posebnost GStreamerja je tudi to, da za ločevanje posameznih elementov v cevovodu uporablja klicaj (!) z obveznimi presledki pred in za njim. V primeru, da izpustite kak presledek se bo ukazni lupini skegljalo in boste ostali brez vtipkanega ukaza. Bodite pozorni.

Sedaj, ko smo določili izvor videa pa je potrebno povedati kak format videa bomo zahtevali od izvora. To storimo z naslednjim elementov s katerim povemo, da bi radi video v surovi obliki dimenzij 640x480 pik in s trideset slikami na sekundo.

Na koncu pa cevovod zaključimo s ponorom in v našem primeru bo to kar zaslon.

Zapiši me nežno

Prejšnji ukaz bo na ekranu pokazal okno in v njem bo direkten prenos slike s kamere. Takole samega sebe gledati je sicer lepo ampak koristi pa žal ni nobene, zato bomo v nadaljevanju video spravili v datoteko.

gst-launch v4l2src ! 'video/x-raw-yuv,width=640,height=480,framerate=30/1' ! \
queue ! videorate ! 'video/x-raw-yuv,framerate=30/1' ! theoraenc ! \
queue ! oggmux ! filesink location=oporoka.ogg


V ukazi, ki se je razlezel v malo daljšo klobaso je nekaj sprememb. Prvi novi element je videorate kateremu sledi še nekaj lastnostni. Videorate poskrbi za pravilno podajanje videa naslednjemu elementu v cevovodu. Pri zajemanju videa s kamere se lahko zgodi, da kamera pošilja video hitreje ali pa počasneje, čeprav smo ji rekli naj dela s tridesetimi slikami na sekundo. Naslednji element je Theora kodirnik, ki dobljeni video pretvori v zapis theora in ga poda multiplekserju oggmux, ki video zapakira v ogg vsebnik (container). Na koncu se cevovod zaključi z datotečnim ponorom, ki celoten tok zapiše v datoteko z imenom oporoka.ogg. Naj na hitro omenim še element queue, ki skrbi za čakalno vrsto pred določenimi elementi, ki zahtevajo, da podatki prihajajo v določenem zaporedju.

Po zagonu tega ukaza se bo vključila kamera in posnetek se bo zapisoval v ogg datoteko. Prvi problem je verjetno ta, da med snemanjem ne vidimo kaj v resnici snemamo. Precej neprijetna zadeva in poizkusili jo bomo popraviti s pomočjo novega elementa tee, ki ga bomo vstavili v cevovod.

gst-launch v4l2src ! 'video/x-raw-yuv,width=640,height=480,framerate=30/1' ! \
tee name=vid ! queue ! xvimagesink sync=false vid. ! queue ! videorate ! \
'video/x-raw-yuv,framerate=30/1' ! theoraenc ! queue ! oggmux ! \
filesink location=oporoka.ogg


Takoj na začetku naš tok pošljemo v element tee, ki zna tok razdeliti na več enakih tokov s katerimi lahko potem hkrati delamo. Prvi tok pošljemo v ponor xvimagesink, ki tok prikaže na zaslonu, drugi tok pa pošljemo v kodirnik in potem v multiplekser in ga na koncu zapišemo v datoteko.

Torej s pomočjo elementa tee smo združili dva prva primera v eni ukazni vrstici in hkrati opravili dve stvari. Prikazali video na ekranu in ga hkrati zapisali v datoteko. Čista zmaga! Vse skupaj pa potem zgleda nekako takole:



Prisluhnimo tišini

Slika brez zvoka je nekaj kar so gledali na začetku prejšnjega stoletja zato bomo naši oporoki dodali še zvok:

gst-launch v4l2src ! 'video/x-raw-yuv,width=640,height=480,framerate=30/1' ! \
tee name=t_vid ! queue ! xvimagesink sync=false t_vid. ! queue ! videorate ! \
video/x-raw-yuv,framerate=30/1 ! theoraenc ! queue ! mux. \
alsasrc device=hw:1,0 ! audio/x-raw-int,rate=48000,channels=2,depth=16 ! \
queue ! audioconvert ! queue ! vorbisenc ! queue ! mux. \
oggmux name=mux ! filesink location=oporoka.ogg


Sedaj se stvari v resnici zakomplicirajo, tisto prej so bile pa otročarije. ;) Sprememb je kar nekaj ampak bomo šli lepo po vrsti. Najprej izberemo video4linux2 kot izvor, ki ga usmerimo v tee s katerim ga razdelimo na dva dela, eden gre na ekran, drugi se pa zaključi v neki čudni zadevi imenovani mux. To je naš multiplekser, ki ga bomo ustvarili na koncu. Z videom smo opravili z levo roko, sedaj se bomo lotili še zvoka. Navesti moramo nov vir, v tem primeru je to alsasrc, kateremu določimo še napravo, ki jo mora uporabiti (hw:1,0), saj smo želeli, da se zvok zajema z mikrofona, ki je vgrajen v našo spletno kamero. Tako kot za video je tudi tukaj potrebno povedati v kakšni obliki bi radi zvok, kar se je naredilo z naslednjim elementom. Vse skupaj se je potem preusmerilo v element audioconvert, ki skrbi za usklajevanje posameznih avdio formatov. Audioconvert je tako brihten, da sam ugotovi v kakšnem formatu je prišel tok ter v kakšnem formatu ga pričakuje naslednji element in naredi takojšnjo pretvorbo. Na koncu v cevovod vključimo še vorbisenc - kodirnik, ki surov zvok pretvori v vorbis format in ga potem, tako kot video, zaključimo s pošiljanjem v multiplekser mux. Glede na to, da smo izvor slike in zvoka zaključili v nekem multiplekserju, ki ga takrat še ni bilo, bi se spodobilo, da ga ustvarimo. Na koncu multipleksiran zvok in sliko pošljemo v datoteko oporoka.ogg.

Kvantiteta je kvaliteta

Na koncu se bomo dotaknili še problema kvalitete posnetka. Theora in Vorbis sta formata, ki sta primerna za internetno oddajanje vendar kvaliteta videa v vsakem primeru trpi, ne glede na to kakšno kvaliteto kodiranja nastavimo. Rešitev je preprosta, video je potrebno posneti v nekem drugem formatu, ki je bolj prizanesljiv s kvaliteto. Video smo že na začetku zajemali v surovem načinu, vendar smo ga kasneje prekodirali v manj potraten format. Kaj pa če vse skupaj pustimo kar v izvornem, surovem formatu?

gst-launch v4l2src ! 'video/x-raw-yuv,width=640,height=480,framerate=30/1' ! \
tee name=t_vid ! queue ! videoflip method=horizontal-flip ! \
xvimagesink sync=false t_vid. ! queue ! \
videorate ! 'video/x-raw-yuv,framerate=30/1' ! queue ! mux. \
alsasrc device=hw:1,0 ! audio/x-raw-int,rate=48000,channels=2,depth=16 ! queue ! \
audioconvert ! queue ! mux. avimux name=mux ! \
filesink location=oporoka.avi


Takole. Odstranili smo elementa theoraenc in vorbisenc. Prav tako smo oggmux zamenjali z avimux. Izvorni video in zvok bomo tokrat multipleksirali v avi vsebnik. Pozorno oko bralca bo opazilo še en nov element, ki smo ga uporabili, videoflip. Z njim smo prezrcalili video preden smo ga prikazali na zaslonu. Vse skupaj bi lahko pustili kar takole vendar smo si naredili dva problema. Prvi je dolžina datoteke. Nekompresiran video in zvok bosta zasedla približno 1GB trdega diska za minuto posnetka, to bi še preživeli. Drugi, precej bolj pereč problem je pa to, da se Kdenlive, prosti program za urejanje in montažo ob odpiranju takšnega videa enostavno sesuje. Poiskati moramo torej format pri katerem bo kvaliteta slike in zvoka dovolj dobra, format mora Kdenlive brez težav prebrati in ga tudi obdelati. Takole bomo storili:

gst-launch filesrc location=oporoka.avi ! \
decodebin name=decode decode. ! queue ! x264enc ! mp4mux name=mux ! \
filesink location=oporoka.mp4 decode. ! \
queue ! audioconvert ! faac ! mux.


Sedaj smo za izvor uporabili kar datoteko. Potem smo vse skupaj poslali v decodebin, univerzalni dekodirnik, ki prepozna format datoteke in jo dekodira. Decodebin se obnaša podobno kot tee in tako lahko en tok obravnavamo večkrat. Najprej tok pošljemo v x264enc, ki video pretvori v format H.264 nato ga pošljemo v mp4mux, multiplekser, ki vsebino zapiše v mp4 vsebnik. Ko z videom zaključimo, moramo poskrbeti še za zvok. Zvok pošljemo skozi audioconvert in faac, ki zvok pretvorita v obliko primerno za mp4 vsebnik. Na koncu pa vse skupaj zapišemo še v datoteko oporoka.mp4.

Tale zadnji ukaz zna trajati kar nekaj časa ampak v končni fazi se čakanje izplača. Pretvorjeni video posnetek, ki ga dobimo se skoraj ne razlikuje od originala. Poleg tega pa ga bo moč urejati s Kdenlive brez kakršnih koli težav.

Z ramo ob rami

Je kvantiteta res kvaliteta? V primeru videa je to praviloma res. Več prostora kot zaseda video, kvalitetnejši je. Testni video, ki je bil posnet je bil dolg 11.6 sekunde. Velikosti datotek so takšne kot jih prikaže ukaz ls -lh.

Surov izvor, 157 MB


H.264, 4.9 MB


Theora, 479 kB



Na koncu ostane samo še upload H.264 formata na YouTube:



Kako naprej?

V tem prvem delu članka smo si pogledali osnovno delo z Gstreamerjem, naučili smo se kako dostopati do video in avdio naprav in kako zajeti podatke, ki jih te naprave vračajo. Prav tako sedaj znamo pretvarjati med različnimi formati video in avdio zapisov. V nadaljevanju se bomo poigrali z zajemanjem vsebin in internetnemu oddajanju le-teh. Naučili se bomo kako naredimo svoj pretočni strežnik in kako svojo vsebino ponudimo vsem, ki bi si jo želeli ogledati.
Gledanje digitalne TV (DVB-T) pod Linuxom

Gledanje digitalne TV (DVB-T) pod Linuxom

Ker je radiofrekvenčni spekter omejen, analogno oddajanje oz. analogni signali pa zasedajo preveliko pasovno širino, so se nekatere države leta 2006 dogovorile, da bodo TV hiše v prihodnosti oddajale samo še digitalni signal. Digitalni način oddajanja prinaša številne ...

Preberi cel članek »

ASCII Videowall

ASCII Videowall

Gradnja takšne kuriozitete spominja na kuhanje mojstrovine. Za veščega je proces povsem enostaven, samorazviden in zabaven, za nesrečnega opazovalca pa mističen in strašljiv. Povsem po nepotrebnem, bomo rekli. Naš recept je tako sestavljen iz opisa za vešče, ki sovpada s spiskom sestavin, ...

Preberi cel članek »

DirectX 9.0 - Osnove programiranja

DirectX 9.0 - Osnove programiranja

V prejšnjih dveh člankih smo si ogledali vse novosti, ki jih je Microsoft uvedel v DirectX. Ker verjamem, da mnogi med vami niso ravno programerji, vas pa vseeno zanima, kako izgleda življenje na drugi strani, sem se odločil, da vam to vsaj malo približam. V tem članku bo ...

Preberi cel članek »

Novosti DirectXa 9 - 1. del

Novosti DirectXa 9 - 1. del

No pa smo vendarle dočakali novo, dolgo pričakovano, različico knjižnice DirectX, ki jo je zlobni Microsoft, bolj ali manj skrbno skrival pred radovednimi očmi javnosti. V približno enaki tajnosti sta nastala tudi ta dva članka, ki vam bosta, vsaj upam tako, uspela ...

Preberi cel članek »