Flumotion est un projet de serveur de streaming vidéo open-source distribué sous licence GPL. Développé en Python et basé sur les frameworks Twisted et GStreamer, il permet de diffuser sur un réseau des vidéos venant de sources lives (caméra, tv…) ou stockées dans des fichiers (on parle alors de VoD pour Video à la demande) en proposant un interface utilisateur de type Web (vous pouvez voir une démo ici).
Catégorie : Gstreamer
GStreamer, le framework multimedia
Nous allons dans ce billet essayer d’optimiser le streaming d’un flux SD sur un réseau local (LAN de 100 Mbps) en utilisant le framework GStreamer.
Environnement des tests
Deux PC Ubuntu connectés sur un même switch (100 Mbps full-duplex).
- PC serveur: Intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz / 2 Go RAM
- PC client: Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz / 1 Go RAM
GStreamer version 0.10.25.
Vidéo source: Big Buck Bunny 480p
Tests avec le codec X.264
Ligne de commande sur la machine générant le streaming (serveur):
serveur> gst-launch -v \ filesrc location= »../Vidéos/big_buck_bunny_480p_stereo.ogg » \ ! queue ! decodebin \ ! queue ! videoscale method=1 ! video/x-raw-yuv,width=854,height=480 \ ! queue ! videorate ! video/x-raw-yuv,framerate=\(fraction\)24/1 \ ! queue ! x264enc byte-stream=true bitrate=2000 bframes=4 ref=4 me=hex subme=4 weightb=true threads=0 \ ! queue ! rtph264pay \ ! queue ! udpsink port=5000 host=192.168.29.150 sync=false async=false
Ligne de commande sur la machine recevant le streaming (client):
client> gst-launch -v udpsrc caps= »application/x-rtp, media=\(string\)video, clock-rate=\(int\)90000, encoding-name=\(string\)H264, payload=\(int\)96″ port=5000 \
! queue ! rtph264depay \
! queue ! ffdec_h264 ! xvimagesink
Résultat:
Visuel: vidéo saccadé (environ 2 img/sec)
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=135 / %MEM=5
Resource client: %CPU=10 / %MEM=2
On ajoute un buffer juste avant le depay et le décodage (au niveau du client):
client> gst-launch -v udpsrc caps= »application/x-rtp, media=\(string\)video, clock-rate=\(int\)90000, encoding-name=\(string\)H264, payload=\(int\)96″ port=5000 \
! queue ! gstrtpjitterbuffer latency=3000 \
! queue ! rtph264depay \
! queue ! ffdec_h264 ! xvimagesink
Résultat:
Visuel: vidéo beaucoup plus fluide mais variation de la gigue (accéleration de la video par moment). On a par contre un décalage de 3 secondes, donc inutilisable pour des flux lives.
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=140 / %MEM=6
Resource client: %CPU=14 / %MEM=2
On modifie ensuite les paramètres d’encodage X.264 (au niveau du serveur):
serveur> gst-launch -v –gst-debug-level=2 \
filesrc location= »../Vidéos/big_buck_bunny_480p_stereo.ogg » \
! queue ! decodebin \
! queue ! videoscale method=1 ! video/x-raw-yuv,width=720,height=480 \
! queue ! videorate ! video/x-raw-yuv,framerate=\(fraction\)24/1 \
! queue ! x264enc vbv-buf-capacity=3000 byte-stream=true bitrate=900 subme=4 ref=2 bframes=1 b-pyramid=true weightb=true \
! queue ! rtph264pay \
! queue ! udpsink port=5000 host=192.168.29.150 sync=false async=false
Résultat:
Visuel: Presque plus de sacade ni de variation de gigue. On a par contre un décalage de 3 secondes, donc inutilisable pour des flux lives.
Bande passante mesurée: entre 2 et 3 Mbps
Resource serveur: %CPU=120 / %MEM=4
Resource client: %CPU=10 / %MEM=2
Si vous suivez régulièrement ce blog, vous savez que je m’intéresse au Framework multimédia GStreamer présent de base dans les systèmes d’exploitations GNU/Linux. Nous allons dans ce billet voir comment encoder en ligne de commande une source vidéo vers des fichiers aux formats OGG (Theora/Vorbis) et/ou MP4 (H264/AAC).
Un rapide billet pour installer Handbrake (le logice libre pour ripper vos DVDs) sur une distribution Fedora 11. En effet, Handbrake n’est pas disponible dans les dépôts, il faut donc passer par une installation à la mimine (il faut juste avoir quelques connaissances pour suivre ce tuto, comme le fait de savoir saisir des commandes dans un terminal…) . J’en profiterai également pour vos donner ma configuration qui me permet d’encoder les DVDs pour les relire sur ma PlayStation 3.
Avant de commencer
On ouvre un terminal et on lance les commandes suivantes afin d’installer les librairies nécessaires à la compilation de Handbrake:
[shell]sudo yum groupinstall "Development Tools" "Development Libraries" "X Software Development" "GNOME Software Development"
sudo yum install yasm zlib-devel bzip2-devel dbus-glib-devel hal-devel webkitgtk-devel libnotify-devel gstreamer-devel gstreamer-plugins-base-devel
[/shell]
Installation de Handbrake
On récupère la dernière version de Handbrake à parit du dépôt SVN:
[shell]cd ~
mkdir src
cd src
svn checkout svn://svn.handbrake.fr/HandBrake/trunk handbrake
[/shell]
On lance la préparation de la compilation:
[shell]cd handbrake
./configure –launch
[/shell]
On compile et on installe:
[shell]cd build
sudo make install
[/shell]
Pour lancer le logiciel Handbrake, il faut aller dans le menu Applications / Son et vidéo / Handbrake (si vous êtes sous Gnome…). Et voilà le travail:
Configuration d’un profil PlayStation 3
On commence par cliquer sur le profil « High Profile » puis sur le bouton « Save current settings to new preset ». On entre un nom et une description pour le profil:
J’utilise les paramètres suivants:
Il ne reste plus qu’a insérer un DVD dans votre lecteur, choisir le profil « PlayStation 3 » et lancer l’encodage !
Je viens de tomber sur un billet de How-To-Forge qui parle d’une application permettant d’enregistrer sur son disque des vidéos disponibles sur Youtube. Le logiciel est question s’appelle Youtube-dl et nous allons voir dans ce billet ce qu’il a dans le ventre.
Installation
On commence par installer la bête sur notre OS pingouin préféré:
[shell]sudo aptitude install youtube-dl[/shell]
Téléchargement d’une vidéo YouTube
Il faut d’abord se rendre avec votre navigateur Web sur la page Youtube pour y récupérer l’adresse (URL):
URL = http://www.youtube.com/watch?v=zlfKdbWwruY
Ensuite, on entre dans un terminal la commande suivante:
[shell]youtube-dl -b -o whereismatt.flv http://www.youtube.com/watch?v=zlfKdbWwruY[/shell]
L’option -b permet d’obtenir une vidéo en qualité optimale. L’option -o whereismatt.flv configure le nom du fichier de sortie (le fichier qui sera présent sur votre disque dur). Je vous conseille de laisse l’exetension .flv qui correspond au format du fichier vidéo Youtube (Flash Video). Enfin on entre l’URL http://www.youtube.com/watch?v=zlfKdbWwruY.
A la fin du téléchargement (la durée dépend de la rapidité de votre ligne Internet). le fichier whereismatt.flv devrait contenir la vidéo que vous pouvez lire un lecteur multimédia (comme VLC).
En option, convertir le fichier dans un format libre
Le format FLV (qui vit je pense ses dernières heures avec l’arrivée d’HTML 5) n’est pas libre et moi , j’aime pas ce qui n’est pas libre… donc pour convertir le fichier whereismatt.flv en whereismatt.ogv (c’est mieux non ?), j’utilise la commande:
[shell]ffmpeg2theora <span style="font-family: Consolas, Monaco, ‘Courier New’, Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre; background-color: #ffffff;">whereismatt.flv<span style="font-family: Georgia, ‘Times New Roman’, ‘Bitstream Charter’, Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">[/shell]
Vous devriez donc avoir à la fin un beau fichier au format conteneur OGV encodé en Theora pour la vidéo et en Vorbis pour l’audio (bref que du beau libre) !
Et hop danses Matt !
Si vous suivez ce blog de prêt (si ce n’est pas le cas, cliquez ici !), vous savez tout le bien que je pense du Framework multimédia GStreamer présent sur l’ensemble des distributions GNU/Linux. En standard, l’installation de GStreamer ne dispose pas de l’ensemble des plugins disponibles. (dont notamment les encodeurs H.264, et les plugins pour la communication avec FFMpeg).
Comme nous l’avions fait avec la distribution GNU/Linux Ubuntu 9.04, voici donc une petite procédure pour installer une version récente et compléte de GStreamer sous Fedora 11.
On commence par ajouter les dépôts, puis on met à jour notre système:
[shell]
rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm
yum update
[/shell]
Ensuite on installe GStreamer and co:
[shell]
yum install gstreamer gstreamer-tools gstreamer-plugins-base gstreamer-plugins-flumpegdemux gstreamer-plugins-good gstreamer-rtsp gstreamer-ffmpeg gstreamer-plugins-bad gstreamer-plugins-ugly
[/shell]
On vérifie l’installation (et le nombre de plugins):
[shell]
gst-inspect
…
Nombre total :201 greffons, 914 fonctionnalités
[/shell]
Et vous, celà donne quoi sur votre configuration ?
Pas trop le temps de blogger en ce moment (sniff), donc juste une rapide note pour vous indiquer que GStreamer, le framework multimédia sous GNU/Linux vient d’évoluer en version 0.10.25 (pour le core et les plugins de bases).
Deux solutions pour profiter dès à présent des nouveautés, la première est de configurer votre système GNU/Linux Ubuntu avec le dépôt de développement du projet GStreamer.
On commence par ajouter les lignes suivantes au fichier /etc/pat/sources.list:
## Gstreamer for dev
deb http://ppa.launchpad.net/gstreamer-developers/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/gstreamer-developers/ppa/ubuntu jaunty main
Puis on met à jour notre système:
sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys 051D8B58
sudo aptitude update
sudo aptitude safe-upgrade
La deuxième solution consiste à installer cette nouvelle version en complément de la version standard. Je vous conseille de compiler GStreamer en suivant cette procédure (il y a même un script shell qui fait tout pour vous…).
Le codec vidéo libre est sorti la semaine dernière en version 1.1. Beaucoup de nouveautés sur le pont:
- rate-Distortion Optimization ( RDO ) pour une meilleure quantification des décisions
- quantification adaptative implique une meilleure utilisation du bitrate
- un mode d’encodage deux passes pour des fichiers à la taille souhaitée
- une utilisation plus fine du CPU pendant l’encodage
- un meilleur contrôle du débit pour la diffusion en streaming (à valider bientôt avec GStreamer :))
- une amélioration des performances du décodeur (de l’ordre de 1,5 à 2 fois plus rapide par rapport à Theora 1.0)
- une retro compatibilité des fichiers Theora 1.0
Pour profiter sans attendre des ces nouveautés sur votre distribution Ubuntu, il faut suivre la procédure suivante:
cd ~/src
wget http://downloads.xiph.org/releases/theora/libtheora-1.1.0.tar.bz2
bzip2 -d libtheora-1.1.0.tar.bz2
tar xvf libtheora-1.1.0.tar
./configure
make
sudo make install
make check
Et voili !
GStreamer et le codec X.264
Souhaitant effectuer un streaming RTP à partir d’une Webcam, voici un billet sur l’optimisation des paramètres du codec libre X.264 (implémentation libre du codec H.264 ou MPEG-4 AVC – WIKI) dont l’équipe de VideoLAN est à l’origine. Pour tester ce codec et ensuite mettre en place le streaming, j’utiliserai le framework GStreamer.
Edit: j’ai ajouté un script SHELL « qui fait tout pour vous » en fin de billet…
Voici une petite procédure pour compiler la dernière version du framework multimédia GStreamer tout en préservant la version installée depuis les dépôts officiels. La procédure a été validé sur une GNU/Linux Ubuntu 9.04 mais doit facilement être adaptable à d’autres distribution (pour une procèdure équivalente sous Mac OS X, vous pouvez lire ce billet).
GStreamer étant un framework, il se base sur de nombreuses librairies externes. Pour nous simplifier la tache, nous allons utiliser les dépôts pour l’installation de ces librairies:
sudo aptitude build-dep gstreamer0.10-ffmpeg gstreamer0.10-plugins-bad gstreamer0.10-plugins-bad-multiverse gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-plugins-ugly-multiverse bison flex git
Ensuite on récupère les dernières versions disponibles de GStreamer et de ses plugins:
mkdir ~/src
cd ~/src
wget http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.25.tar.gz
wget http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-0.10.25.tar.gz
wget http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-0.10.17.tar.gz
wget http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-0.10.17.tar.gz
wget http://gstreamer.freedesktop.org/src/gst-plugins-ugly/gst-plugins-ugly-0.10.13.tar.gz
wget http://gstreamer.freedesktop.org/src/gst-ffmpeg/gst-ffmpeg-0.10.8.tar.gz
On commence par la compilation de GStreamer (core). L’installation se fera dans le répertoire /opt/gstreamer/gstreamer-0.10.24:
tar zxvf gstreamer-0.10.25.tar.gz
cd gstreamer-0.10.25
./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
… puis les plugins « base »:
tar zxvf gst-plugins-base-0.10.25.tar.gz
cd gst-plugins-base-0.10.25
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-0.10.25/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
… puis les plugins « good »:
tar zxvf gst-plugins-good-0.10.17.tar.gz
cd gst-plugins-good-0.10.17
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-0.10.25/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
… puis les plugins « bad »:
tar zxvf gst-plugins-bad-0.10.17.tar.gz
cd gst-plugins-bad-0.10.17
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-0.10.25/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
… les plugins « ugly »:
tar zxvf gst-plugins-ugly-0.10.13.tar.gz
cd gst-plugins-ugly-0.10.13
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-0.10.25/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
… et enfin les plugins FFMPEG (streaming):
tar zxvf gst-ffmpeg-0.10.8.tar.gz
cd gst-ffmpeg-0.10.8
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-0.10.25/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-0.10.25
make
sudo make install
cd ..
Puis on créé un lien symbolique entre le répertoire /opt/gstreamer/current et /opt/gstreamer/gstreamer-0.10.25. Ce lien nous permet d’avoir plusieur version de GStreamer sur notre système.
sudo cp /opt/gstreamer/gstreamer-0.10.25/lib/gstreamer-0.10.25/* /opt/gstreamer/gstreamer-0.10.25/lib/
sudo ln -s /opt/gstreamer/gstreamer-0.10.25/lib /opt/gstreamer/current
On teste enfin l’installation:
/opt/gstreamer/gstreamer-0.10.25/bin/gst-inspect –gst-plugin-path=/opt/gstreamer/current
Pour les plus faineant, voici un script sheel automatisant ces quelques taches
[shell]
#!/bin/sh
# A simple script to get/compile/install GStreamer
# Nicolas Hennion – GPL
#
# Remarks: the version will be installed in the /opt/gstreamer folder
# Change this to the latest version
GST_CORE=0.10.25
GST_BASE=0.10.25
GST_GOOD=0.10.17
GST_BAD=0.10.17
GST_UGLY=0.10.13
GST_FFMPEG=0.10.8
# Do not edit under this line
sudo aptitude build-dep gstreamer0.10-ffmpeg gstreamer0.10-plugins-bad gstreamer0.10-plugins-bad-multiverse gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-plugins-ugly-multiverse
sudo aptitude install bison flex git
if [ ! -e gstreamer-$GST_CORE.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-$GST_CORE.tar.gz
fi
if [ ! -e gst-plugins-base-$GST_BASE.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-$GST_BASE.tar.gz
fi
if [ ! -e gst-plugins-good-$GST_GOOD.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-$GST_GOOD.tar.gz
fi
if [ ! -e gst-plugins-bad-$GST_BAD.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-$GST_BAD.tar.gz
fi
if [ ! -e gst-plugins-ugly-$GST_UGLY.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gst-plugins-ugly/gst-plugins-ugly-$GST_UGLY.tar.gz
fi
if [ ! -e gst-ffmpeg-$GST_FFMPEG.tar.gz ]
then
wget http://gstreamer.freedesktop.org/src/gst-ffmpeg/gst-ffmpeg-$GST_FFMPEG.tar.gz
fi
sudo mkdir /opt/gstreamer
if [ ! -e gstreamer-$GST_CORE ]
then
tar zxvf gstreamer-$GST_CORE.tar.gz
cd gstreamer-$GST_CORE
./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
if [ ! -e gst-plugins-base-$GST_BASE ]
then
tar zxvf gst-plugins-base-$GST_BASE.tar.gz
cd gst-plugins-base-$GST_BASE
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-$GST_CORE/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
if [ ! -e gst-plugins-good-$GST_GOOD ]
then
tar zxvf gst-plugins-good-$GST_GOOD.tar.gz
cd gst-plugins-good-$GST_GOOD
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-$GST_CORE/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
if [ ! -e gst-plugins-bad-$GST_BAD ]
then
tar zxvf gst-plugins-bad-$GST_BAD.tar.gz
cd gst-plugins-bad-$GST_BAD
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-$GST_CORE/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
if [ ! -e gst-plugins-ugly-$GST_UGLY ]
then
tar zxvf gst-plugins-ugly-$GST_UGLY.tar.gz
cd gst-plugins-ugly-$GST_UGLY
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-$GST_CORE/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
if [ ! -e gst-ffmpeg-$GST_FFMPEG ]
then
tar zxvf gst-ffmpeg-$GST_FFMPEG.tar.gz
cd gst-ffmpeg-$GST_FFMPEG
PKG_CONFIG_PATH=/opt/gstreamer/gstreamer-$GST_CORE/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig ./configure –prefix=/opt/gstreamer/gstreamer-$GST_CORE
make
sudo make install
cd ..
fi
sudo cp /opt/gstreamer/gstreamer-$GST_CORE/lib/gstreamer-$GST_CORE/* /opt/gstreamer/gstreamer-$GST_CORE/lib/
sudo ln -s /opt/gstreamer/gstreamer-$GST_CORE/lib /opt/gstreamer/current
/opt/gstreamer/gstreamer-$GST_CORE/bin/gst-inspect –gst-plugin-path=/opt/gstreamer/current
[/shell]