TV video stream [MEGOLDVA - szuper]

Okoztam éjjel magamnak egy kis fejtörést, mert nem hallgattam a korábbi hozzászólásokban elhangzottakra, miszerint a real-time video stream szűk keresztmetszete a hardver lesz.
Az elképzelésem az volt, hogy bárhol vagyok, tudjam nézni az otthonról sugárzott TV adásokat. Nagy ábrándjaim közt szerepelt olyan megoldás is, hogy egy egyszerű weblapon keresztül menedzselem a TV adásokat. Úgy véltem, hogy a relatíve nagy feltöltési sebesség (2,5 MiB/s) és az erősnek - gondolt - hardverem (AMD Athlon(tm) 64 X2 Dual Core Processor 4200+) majd megfelelő lesz a feladatra.

A stratégiám ez volt: vlc segítségével beolvastatom a TV tuner kártyáról a videó és audió forrást, majd - ha már amúgy weblapban gondolkodtam a menedzselést illetően - egy weblapba ágyazom, és onnan játszatom le egy flash video player segítségével.

Mivel vlc-vel idáig nem foglalkoztam behatóbban, így csak éjjel tudatosult bennem, hogy ffmpeg-et használ az enkódoláshoz. Rémlett, hogy itt bajok lehetnek, mert nem igazán készülnek csomagok libmp3lame támogatással ffmpeghez. Úgy is lett. Jelenleg Karmic Koala fut a gépemen. A medibuntu-hoz régebben készítettek non-free csomagokat, amiben mp3 kódolóval ellátott libavcodek is volt az ffmpeghez. Ez már már a múlté. Nincs más hátra, forrásból kell fordítani egy ffmpeg-et. A korábbi ffmpeg->unintall a libekkel együtt.


git clone git://git.ffmpeg.org/ffmpeg/
cd ffmpeg
git clone git://git.ffmpeg.org/libswscale/
./configure --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-avfilter \
--enable-avfilter-lavf --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libxvid --enable-shared
make
make install

(Néhány függőség tulajdonképpen természetes módon hiányzott liblameX-dev stb. -dev )

Először az --enable-shared nélkül fordítottam, átsiklottam felettte. Meg is lett az eredménye: az ffmpeg tudta használni a libmp3lame-et, de már a vlc nem:

az avcodec encoder error: cannot find encoder MPEG Audio layer 1/2/3

Nos, hamar beláttam, hogy az --enable-shared opció szükséges.

Így már hiba nélkül futott a vlc egy teszt avi fájl streamelésekor:

vlc --sout "#transcode{vcodec=FLV1,r=30,acodec=mp3,samplerate=11025,ab=16}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8080/stream.flv}" somemovie.avi --loop -vvv --color -I dummy

A cél eléréséhez a JW FLV Player-t használtam. Amihez egy remek felület még segített is a weblapba épülő kód elkészítésében.

A kódot weblapba ágyazva már nézhettem is a streamelt videót és hallottam a hangját. Apróbb pixelhibák és időnkénti hanghibáktól eltekintve még mindig biztos voltam benne, hogy jó úton haladok. Nosza, lássuk, mi is történt mikor a TV kártya jeleit akartam valós időben konvertálni:

clear; vlc -I dummy -vvv 'v4l2:///dev/video1:input-slave=alsa://1,0:audio-method=0:controls-reset:set-ctrls={video_bitrate_mode=1,video_bitrate=4000000,video_peak_bitrate=4000000}:width=720:height=576:tuner=0:tuner-frequency=189250' --sout "#transcode{vcodec=FLV1,r=30,acodec=mp3,samplerate=11025,ab=16}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8080/stream.flv}"

Sajnos szaggat a kimeneti oldalon: a megjelenített kép legfeljebb tájékoztató jellegű adatnak szolgálhat. Nem adom fel, valamit még kitalálok...
Bár, ha van nektek valami ötletetek, miként lehetne folyamatosabbá tenni a TV kártya forrású valós idejű képfolyam továbbítást, örömmel veszem.

Szerk.:
Tegnap már nem is vettem észre, hogy a hang nem ment át a streamelt adattal.
Íme a kód, ami a v4l2 driverhez az ALSA 1,0 hardver streamjét bepakolja az flv fájlba. (Természetesen a videót is.)

vlc -I dummy -vvv  'v4l2:///dev/video1:standard=6:controls-reset:set-ctrls=\
{video_bitrate_mode=1,video_bitrate=4000000,video_peak_bitrate=4000000}\
:width=352:height=288:tuner=0:tuner-frequency=527250' :input-slave=alsa://hw:0,0\
 --sout "#transcode{vcodec=FLV1,acodec=mp3,samplerate=11025,ab=16}\
:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8080/stream.flv}"

Aki régebben már használt vlc-t streameléshez, annak biztosan idegen az 1-es verziójú vlc szintaktikája. Amit kiemelnék, hogy az alsa hivatkozás kívül esik az idézőjeles, macskakörmös részeken. Ez bizony nekem illogikus volt, egy darabig eltartott, míg eltaláltam a szintaktikát.

Nyílván mindenkinek más a TV kártyája, a hangrendszere. Nekem olyan a TV kártyám, aminek nincs külső hangkimenete, hanem egy belső kábelen lehet összekötni a hangkártyával, annak is célszerűen a tuner bemenetére. Még annyit kellett tennem, hogy a hang mixerben a videó csatornára állítottam felvételi bemenetnek.
A másik változás, a streamelt videó felbontásának csökkentése, pedig azt eredményezte, hogy nagyszerűen élvezhető streamelt videót + hangot kapunk!

Remélem, másoknak is segíthettem.

Hozzászólások

Windows XP alatt én ezt úgy oldottam meg, hogy van egy Hauppage WinTV PVR USB2 kártyám, amely hardveres mpeg2 encoder-t tartalmaz.
Van az Orb nevű internetes oldal amelyik támogatja a kártyámat, feltelepítettem a kliens programját, behangoltam a csatornákat.
Ezután bárhol vagyok csak belépek az Orb oldalára kiválasztom, hogy melyik adót szeretném esetleg milyen stream-et (flash, real media, wmv), és nézem.
A feltöltési sebességem 512kbit/sec, a gépen 1,8 GHz core 2 duo. Nem szaggat, nézhető minőségű.

Tudom, hogy ez neked nem segítség, de hátha jó valamire.

Dreambox-ból csak simán kitolom az mpeg stream-et, csatornát is tudok váltani. Egyelőre csak házon belül megy...(wlan-al kivül is :) ) Majd ha a világvégén ahol lakok lesz min 2Mbit-et feltöltés akkor meg már bárhol.

Hasonlo dologgal probalkozok, de en a kovetkezo problemaval kuzdok:
Icecast2 szerverre szeretnek OggTheora streamet kuldeni /dev/video0 eszkozrol. Ez tokeletesen mukodik, egeszet addig mig nem akarok hangot is kuldeni.
Ha mar hanggal egyutt kuldom akkor kb 4 masodpercig megy aztan megall az egesz. A megallas pillanataban a vlc nem ir semmit se a logba, csak annyit latok hogy mar nincs halozati forgalom, az Icecast2 webfeluletebol is eltunik a stream, a VLC meg latszolag dolgozik tovabb.
Ezekkel a parameterekkel probalkozok:
cvlc -vvv v4l2:// :v4l2-dev=/dev/video0 :v4l2-width=720 :v4l2-height=576 :v4l2-fps=25 --input-slave=alsa://hw:1,0 --sout='#transcode{fps=25,vcodec=theo,vb=400,scale=1,acodec=vorb,ab=128,channels=2,samplerate=44100}:std{access=shout,mux=ogg,dst=teszt:teszt@192.168.0.1:8000/video.ogv}'

Log: http://syserr.hu/vlclog.txt

A gepben 2 hangkartya van, mindkettovel ugyanaz a jelenseg.

Debian testing kernel 2.6.31.4