Envoyé par unreal
Autre article initialement écrit pour une mailing list...
Prérequis
Cet tutorial a été réalisé sur une machine FreeBSD et une machine OS X,
mais il devrait marcher sans grand soucis sur toute autre plateforme
Unix-Like récente.
Il est nécessaire d'avoir installé les utilitaires habituels :
Introduction
Le but de ce tutorial est réaliser un serveur de streaming vidéo optimisé
à base de VLC. Dans mon cas, le but était de pouvoir regarder certaines
chaînes du multiposte Free quand je n'étais pas chez moi (VH1 à tout
hasard ).
Il est possible d'utiliser la version pré-compilée mais cela induit deux
inconvénients :
Ce tutorial s'articule autour des points suivants :
Téléchargement
J'ai commencé par télécharger les fichiers suivants dans un dossier "src"
(qu'on appellera $SRC par la suite) :
Compilation
Nous allons réaliser un binaire VLC statique, c'est-à-dire où tous les
codecs sont contenus directement dans le binaire (par contre, les libs
système seront linkées dynamiquement).
Environnement de compile :
FAAC :
(sur OS X, le make peut se terminer avec une erreur, mais ce n'est pas
gênant)
FFMpeg :
LibDVBPSI :
Live555 :
Mpeg2Dec :
X264 :
VLC :
C'est là où les choses peuvent se compliquer en fonction des besoins de
chacun.
Exemple de configuration très minimaliste :
Puis : make ou gmake
Ah mince, ça ne compile pas :
Corrigeons ce petit bug dans le code :
et on remplace p_sys->oc->pb = p_sys->io; par p_sys->oc->pb = &p_sys->io;
Et on relance le make. Cool ça passe cette fois.
Et pour finir : make install (après avoir fait un "su").
Utilisation
Maintenant que j'ai compilé et installé avec succès une version de VLC
adaptée à mes besoins, il est temps d'essayer une diffusion.
Le schéma suivant résume ce que je souhaite faire :
[ Free Multiposte ] -------> [ VLC ] --------> [ Diffusion ]
MPEG dans TS via RTSP Resize/Deinterlace H264/MP4a dans ASF via HTTP
Heureusement que VLC dispose d'un CLI puissant permettant de tout
paramétrer via un script.
Exemple d'utilisation :
Les paramètres sont relativement explicites, mais en gros il s'agit de
convertir du flux de la FreeBox vers un flux avec les caractéristiques
suivantes :
* Mais d'après mes expérimentations, le conteneur TS nécessitera qu'un
keyframe soit transmis au client avant l'apparition de l'image)
Intégration avec Apache
Un des avantages à utiliser une diffusion de type HTTP est qu'il est
possible d'héberger un ou plusieurs serveurs de diffusion derrière un
serveur Apache. En effet, en diffusion HTTP le client va faire banalement
une requête "GET" et va recevoir en réponse le flux ; il est donc possible
d'utiliser un proxy, comme mod_proxy.
Pour cela, il suffit d'activer et configurer mod_proxy dans sa
configuration Apache :
Conclusion
Grâce à des solutions logicielles flexibles comme VLC et des algos de
compression efficaces, il est possible aujourd'hui de diffuser du contenu
vidéo à relativement faible débit (200kbit/s), ouvrant ainsi les portes de
la diffusion personnelle.
J'espère que ce tuto vous a plu, et n'hésitez pas à faire part de vos
remarques !
Prérequis
Cet tutorial a été réalisé sur une machine FreeBSD et une machine OS X,
mais il devrait marcher sans grand soucis sur toute autre plateforme
Unix-Like récente.
Il est nécessaire d'avoir installé les utilitaires habituels :
- GCC + gmake
- automake + autoconf
Introduction
Le but de ce tutorial est réaliser un serveur de streaming vidéo optimisé
à base de VLC. Dans mon cas, le but était de pouvoir regarder certaines
chaînes du multiposte Free quand je n'étais pas chez moi (VH1 à tout
hasard ).
Il est possible d'utiliser la version pré-compilée mais cela induit deux
inconvénients :
- Il n'est pas forcément souhaitable d'installer X11, Gnome ou WXWindow
sur un serveur
- La compression H264 est particulièrement lourde en temps CPU, tout gain
de performance est la bienvenue (comprendre : avec la version
pré-compilée, prévoyez du Core Duo 2GHz pour autre chose que 320x240)
Ce tutorial s'articule autour des points suivants :
- Compilation et installation de VLC
- Recompression d'un flux vidéo
- Intégration avec Apache et mod_proxy
Téléchargement
J'ai commencé par télécharger les fichiers suivants dans un dossier "src"
(qu'on appellera $SRC par la suite) :
- faac-1.26.tar.gz (pour la compression AAC)
- ffmpeg-export-snapshot.tar.bz2
- libdvbpsi5-0.1.6.tar.gz (gestion du conteneur TS)
- live555-latest.tar.gz (flux réseaux)
- mpeg2dec-0.4.1.tar.gz (décodage MPEG2)
- x264-snapshot-20080102-2245.tar.bz2
- vlc-0.8.6d.tar.gz
Compilation
Nous allons réaliser un binaire VLC statique, c'est-à-dire où tous les
codecs sont contenus directement dans le binaire (par contre, les libs
système seront linkées dynamiquement).
Environnement de compile :
export SRC= <nom du dossier src>
export CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer -msse2
-I$SRC/faac/include"
export CXXFLAGS=$CFLAGS
export LDFLAGS=-L$SRC/faac/libfaac/.libs
export CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer -msse2
-I$SRC/faac/include"
export CXXFLAGS=$CFLAGS
export LDFLAGS=-L$SRC/faac/libfaac/.libs
FAAC :
./bootstrap
./configure --enable-static --enable-shared=no
make (ou gmake)
./configure --enable-static --enable-shared=no
make (ou gmake)
(sur OS X, le make peut se terminer avec une erreur, mais ce n'est pas
gênant)
FFMpeg :
ln -s ffmpeg-export-2008-01-02 ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-pp --disable-shared --enable-static
--disable-debug --arch=i686 --cpu=pentium4 --enable-libfaac
--enable-pthreads --extra-ldflags="-L$SRC/faac/libfaac/.libs"
--extra-cflags="-I$SRC/faac/include"
make (ou gmake)
cd ffmpeg
./configure --enable-gpl --enable-pp --disable-shared --enable-static
--disable-debug --arch=i686 --cpu=pentium4 --enable-libfaac
--enable-pthreads --extra-ldflags="-L$SRC/faac/libfaac/.libs"
--extra-cflags="-I$SRC/faac/include"
make (ou gmake)
LibDVBPSI :
ln -s libdvbpsi5-0.1.6 libdvbpsi
cd libdvbpsi
./bootstrap
./configure --enable-static --enable-shared=no --enable-release
make (ou gmake)
cd libdvbpsi
./bootstrap
./configure --enable-static --enable-shared=no --enable-release
make (ou gmake)
Live555 :
./genMakefiles macosx|freebsd|linux
make (ou gmake)
make (ou gmake)
Mpeg2Dec :
ln -s mpeg2dec-0.4.1 mpeg2dec
cd mpeg2dec
./configure --enable-static --enable-shared=no
make (ou gmake)
cd mpeg2dec
./configure --enable-static --enable-shared=no
make (ou gmake)
X264 :
ln -s x264-snapshot-20080102-2245 x264
cd x264
./configure --enable-pthread
make (ou gmake)
cd x264
./configure --enable-pthread
make (ou gmake)
VLC :
C'est là où les choses peuvent se compliquer en fonction des besoins de
chacun.
Exemple de configuration très minimaliste :
./configure \
--prefix=/usr/local/vlc \
--enable-release \
--enable-static \
--enable-sout \
--enable-live555 \
--enable-ffmpeg \
--with-ffmpeg-faac \
--enable-libmpeg2 \
--enable-x264 \
--enable-dvbpsi \
--disable-x11 \
--disable-mad \
--disable-growl \
--disable-notify \
--disable-dvdnav \
--disable-gnomevfs \
--disable-libcdio \
--disable-libcddb \
--disable-cdda \
--disable-vcd \
--disable-screen \
--disable-ogg \
--disable-mkv \
--disable-mod \
--disable-mpc \
--disable-quicktime \
--disable-a52 \
--disable-dts \
--disable-vorbis \
--disable-speex \
--disable-png \
--disable-cmml \
--disable-xvideo \
--disable-glx \
--disable-xinerama \
--disable-opengl \
--disable-sdl \
--disable-sdl-image \
--disable-freetype \
--disable-fribidi \
--disable-libxml2 \
--disable-fb \
--disable-oss \
--disable-alsa \
--disable-macosx-audio \
--disable-wxwidgets \
--disable-visual \
--disable-daap \
--disable-bonjour \
--disable-gnutls \
--disable-skins2 \
--with-live555-tree=/home/unreal/src/live \
--with-ffmpeg-tree=/home/unreal/src/ffmpeg \
--with-libmpeg2-tree=/home/unreal/src/mpeg2dec \
--with-x264-tree=/home/unreal/src/x264 \
--with-dvbpsi-tree=/home/unreal/src/libdvbpsi \
--with-included-gettext
--prefix=/usr/local/vlc \
--enable-release \
--enable-static \
--enable-sout \
--enable-live555 \
--enable-ffmpeg \
--with-ffmpeg-faac \
--enable-libmpeg2 \
--enable-x264 \
--enable-dvbpsi \
--disable-x11 \
--disable-mad \
--disable-growl \
--disable-notify \
--disable-dvdnav \
--disable-gnomevfs \
--disable-libcdio \
--disable-libcddb \
--disable-cdda \
--disable-vcd \
--disable-screen \
--disable-ogg \
--disable-mkv \
--disable-mod \
--disable-mpc \
--disable-quicktime \
--disable-a52 \
--disable-dts \
--disable-vorbis \
--disable-speex \
--disable-png \
--disable-cmml \
--disable-xvideo \
--disable-glx \
--disable-xinerama \
--disable-opengl \
--disable-sdl \
--disable-sdl-image \
--disable-freetype \
--disable-fribidi \
--disable-libxml2 \
--disable-fb \
--disable-oss \
--disable-alsa \
--disable-macosx-audio \
--disable-wxwidgets \
--disable-visual \
--disable-daap \
--disable-bonjour \
--disable-gnutls \
--disable-skins2 \
--with-live555-tree=/home/unreal/src/live \
--with-ffmpeg-tree=/home/unreal/src/ffmpeg \
--with-libmpeg2-tree=/home/unreal/src/mpeg2dec \
--with-x264-tree=/home/unreal/src/x264 \
--with-dvbpsi-tree=/home/unreal/src/libdvbpsi \
--with-included-gettext
Puis : make ou gmake
Ah mince, ça ne compile pas :
mux.c: In function 'OpenMux__ffmpeg':
mux.c:136: error: incompatible types in assignment
mux.c:136: error: incompatible types in assignment
Corrigeons ce petit bug dans le code :
vi ./modules/codec/ffmpeg/mux.c
et on remplace p_sys->oc->pb = p_sys->io; par p_sys->oc->pb = &p_sys->io;
Et on relance le make. Cool ça passe cette fois.
make[2]: Nothing to be done for `all'.
Et pour finir : make install (après avoir fait un "su").
Utilisation
Maintenant que j'ai compilé et installé avec succès une version de VLC
adaptée à mes besoins, il est temps d'essayer une diffusion.
Le schéma suivant résume ce que je souhaite faire :
[ Free Multiposte ] -------> [ VLC ] --------> [ Diffusion ]
MPEG dans TS via RTSP Resize/Deinterlace H264/MP4a dans ASF via HTTP
Heureusement que VLC dispose d'un CLI puissant permettant de tout
paramétrer via un script.
Exemple d'utilisation :
/usr/local/vlc/bin/vlc \
-I dummy \
'rtsp://mafreebox.freebox.fr/freeboxtv/stream?id=201' \
vlc:quit --loop --sout \
'#transcode{vcodec=h264,vb=128,acodec=mp4a,ab=32,channels=1,samplerate=48000,width=240,height=176,deinterlace}:standard{mux=asf,dst=:8080,access=http}:sout-transcode-soverlay=0'
\
--no-interact
-I dummy \
'rtsp://mafreebox.freebox.fr/freeboxtv/stream?id=201' \
vlc:quit --loop --sout \
'#transcode{vcodec=h264,vb=128,acodec=mp4a,ab=32,channels=1,samplerate=48000,width=240,height=176,deinterlace}:standard{mux=asf,dst=:8080,access=http}:sout-transcode-soverlay=0'
\
--no-interact
Les paramètres sont relativement explicites, mais en gros il s'agit de
convertir du flux de la FreeBox vers un flux avec les caractéristiques
suivantes :
- Vidéo H264 en 128kbit (VBR) en 240x176 (attention ! en H264 les
dimensions doivent être divisibles par 16)
- Son MP4A (AAC) en 32kbit, mono, 48000kHz
- Conteneur ASF (mais on pourrait aussi utiliser un conteneur TS par
exemple*)
- Diffusion HTTP (unicast donc) sur port 8080
* Mais d'après mes expérimentations, le conteneur TS nécessitera qu'un
keyframe soit transmis au client avant l'apparition de l'image)
Intégration avec Apache
Un des avantages à utiliser une diffusion de type HTTP est qu'il est
possible d'héberger un ou plusieurs serveurs de diffusion derrière un
serveur Apache. En effet, en diffusion HTTP le client va faire banalement
une requête "GET" et va recevoir en réponse le flux ; il est donc possible
d'utiliser un proxy, comme mod_proxy.
Pour cela, il suffit d'activer et configurer mod_proxy dans sa
configuration Apache :
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
...
<VirtualHost *:80>
ServerName www.server.com
ServerAlias alias.com
...
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /streamvlc http://127.0.0.1:8080
ProxyPassReverse /streamvlc http://127.0.0.1:8080
</VirtualHost>
LoadModule proxy_http_module modules/mod_proxy_http.so
...
<VirtualHost *:80>
ServerName www.server.com
ServerAlias alias.com
...
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /streamvlc http://127.0.0.1:8080
ProxyPassReverse /streamvlc http://127.0.0.1:8080
</VirtualHost>
Conclusion
Grâce à des solutions logicielles flexibles comme VLC et des algos de
compression efficaces, il est possible aujourd'hui de diffuser du contenu
vidéo à relativement faible débit (200kbit/s), ouvrant ainsi les portes de
la diffusion personnelle.
J'espère que ce tuto vous a plu, et n'hésitez pas à faire part de vos
remarques !
Posté le 27/03/08 à 11:47