Un serveur RTSP basé sur GStreamer

Date: 7/03/2011 | Catégories: Gstreamer,Open-source,Planet-libre,Video,Web | Tags: ,,,,,

Dans le petit monde du streaming vidéo, RTSP est un protocole permettant à un client (lecteur multimédia) de contrôler un serveur (serveur de streaming) en lui envoyant des ordres simples: lire, pause, stop, déplacement temporel (pour avoir une liste des fonctions théoriquement disponibles, vous pouvez lire la RFC 2326). Il est important, pour comprendre la suite de ce billet que le protocole RTSP ne fait pas lui même le streaming vidéo (il utilise pour cela le protocole RTP). RTSP est juste une couche complémentaire permettant de contrôler ce streaming.

Nous allons dans ce billet étudier un serveur basé sur le framework GStreamer. Maintenu par Wim Taymans, un des développeurs de GStreamer, gst-rtsp se compose d'un ensemble de librairies permettant de concevoir simplement son propre serveur RTSP. Pour effectuer des tests, les développeurs fournissent quelques exemples de serveurs.

Installation de gst-rtsp

On commence par récupérer les sources puis à compiler:

mkdir ~/src

cd ~/src

wget http://gstreamer.freedesktop.org/src/gst-rtsp/gst-rtsp-0.10.8.tar.bz2

bzip2 -d gst-rtsp-0.10.8.tar.bz2

tar xvf gst-rtsp-0.10.8.tar

cd gst-rtsp-0.10.8/

./configure

make

Premier streaming RTSP: la mire

On commence par lancer le serveur de test qui va streamer une mire:

cd examples/

./test-readme

Le serveur est maintenant lancé, en écoute sur le port TCP/8554 et l'URL: rtsp://127.0.0.1:8554/test

Note: si vous lancer le client sur une autre machine il faut bien sur remplacer 127.0.0.1 par l'adresse IP (ou le nom d'hôte) de votre serveur.

Si on regarde le code C de ce premier serveur (./test-readme.c), on peut retrouver la pipeline GStreamer qui va s'occuper de diffuser le flux sur le réseau:

videotestsrc is-live=1 ! x264enc ! rtph264pay name=pay0 pt=96

On a donc la génération de la mire avec videotestsrc, puis un encodage H.264 avec x264enc puis enfant un streaming RTP avec rtph264pay.

Pour lire se genre de flux, on peut utiliser plusieurs logiciels. Le plus "populaire" est le très frenchie VLC. On lance donc le logiciel puis on va dans le menu Média / Ouvrir un flux réseau, puis on entre l'URL: rtsp://127.0.0.1:8554/test

Après quelques secondes, la vidéo devrait s'afficher:

On peut aussi utiliser FFplay (le player basée sur FFmpeg):

ffmplay rtsp://127.0.0.1:8554/test

Ou bien directement une pipeline GStreamer, ce qui ouvre la porte à des post traitements:

gst-launch -v rtspsrc location=rtsp://127.0.0.1:8554/test ! queue ! decodebin ! ffmpegcolorspace ! autovideosink

Il est bien sur possible de lancer plusieurs clients vers la même source RTSP (j'ai testé 3 clients en parallèle).

Une mire c'est bien, un fichier MPEG-4 c'est mieux

Les esprits chagrins vont me dire que pour tester les fonctions de seekink (déplacement temporel) avec une mire ce n'est pas terrible... Nous allons donc streamer une vidéo MPEG-4 (j'ai utilisé le logiciel Avidemux pour produire une vidéo de 640x360 en MPEG-4 ISO à partir d'une source Big Buck Bunny 720p AVI).

On va lancer le serveur avec les commandes suivantes (toujours dans le sous répertoires examples):

./test-mp4 ~/big_buck_bunny_360p_surround.mp4

Lecture à partir de VLC:

On a alors, pour cette vidéo, un flux réseau entre le serveur et le client variant entre 350 et 550 Kbps. Ceci est normal car la pipeline suivante que l'on peut trouver dans le fichier test-mp4.c ne fait en fait aucun transcodage. Comme la vidéo n'a pas été encodé en CBR (constant bit rate) on se retrouve avec des variations de débits:

filesrc location=%s ! qtdemux name=d d. ! queue ! rtph264pay pt=96 name=pay0 d. ! queue ! rtpmp4apay pt=97 name=pay1

Coté occupation CPU du coté client je suis à environ 25% sur un Core 2 à 1.8 Ghz.

Capture réseau

Pour les plus curieux d'entre vous, voici le résultat d'une capture réseau entre mon serveur RTSP (192.168.29.79) et un client (192.168.29.148).

On peut notamment y voir la négociation RTSP avec la liste des fonctions disponibles sur le serveur (OPTIONS, DESCRIBE, GET_PARAMETER, PAUSE, PLAY, SETUP, SET-PARAMETER, TEARDOWN) puis le début du streaming RTP.

Conclusion

Bien qu'en développement, ce projet de serveur RTSP basé sur GStreamer est très stable (je n'ai pas rencontré de plantage lors de mes tests) et facile à intégrer dans un développement en C. Si vous voulez faire mumuse et développer votre propre serveur, je vous conseille la lecture du fichier README qui se trouve dans le sous répertoire docs.

A vos serveurs !

  • Tuxfanou

    Petite erreur dans la procédure, il ne s’agit pas de :

    wget http://gstreamer.freedesktop.org/src/gst-rtsp/gst-rtsp-0.10.2.tar.bz2

    mais de :

    wget http://gstreamer.freedesktop.org/src/gst-rtsp/gst-rtsp-0.10.8.tar.bz2

    (numéro de version qui n’est pas bon)

    Mais j’ai également un souci au niveau du « make » je vais voir ce qui peux manquer, si je trouve je reposterais

  • ebuprofen

    Merci pour la présentation, cela me parait sympa pour réaliser un système audio multizone home made

    ebu

    • Attention quand même à la CPU pour décoder des flux HD…

  • Tuxfanou

    Bon, la compilation, c’est fait, il faut juste installer une version de gstreamer qui, pour les version actuelles d’ubuntu ne sont que les ppa : https://launchpad.net/~gstreamer-developers/+archive/ppa

    la bonne version sera disponible dans natty

  • Smile

    bonjour à tous, comment je peux résoudre ce problème : no gstreamer-0.10 >= 0.10.29 (GStreamer) found ?? comment je peux installer les versions récentes de Gstreamer ??
    Merci d’avance 🙂

  • ghost

    can u explain to me this problem pleaaaaaaaaaaaase :
    the configuration is good but when i execute « make this message is appeared all the time

    make all-recursive
    make[1]: entrant dans le répertoire « /home/bassouma/src/gst-rtsp-0.10.8 »
    Making all in gst
    make[2]: entrant dans le répertoire « /home/bassouma/src/gst-rtsp-0.10.8/gst »
    Making all in rtsp-server
    make[3]: entrant dans le répertoire « /home/bassouma/src/gst-rtsp-0.10.8/gst/rtsp-server »
    CC libgstrtspserver_0.10_la-rtsp-media-factory-uri.lo
    rtsp-media-factory-uri.c: In function ‘gst_rtsp_media_factory_uri_init’:
    rtsp-media-factory-uri.c:173: error: ‘gst_plugin_feature_rank_compare_func’ undeclared (first use in this function)
    rtsp-media-factory-uri.c:173: error: (Each undeclared identifier is reported only once
    rtsp-media-factory-uri.c:173: error: for each function it appears in.)
    rtsp-media-factory-uri.c: In function ‘find_payloader’:
    rtsp-media-factory-uri.c:301: warning: assignment makes pointer from integer without a cast
    rtsp-media-factory-uri.c:311: warning: assignment makes pointer from integer without a cast
    rtsp-media-factory-uri.c:321: warning: assignment makes pointer from integer without a cast
    make[3]: *** [libgstrtspserver_0.10_la-rtsp-media-factory-uri.lo] Erreur 1
    make[3]: quittant le répertoire « /home/bassouma/src/gst-rtsp-0.10.8/gst/rtsp-server »
    make[2]: *** [all-recursive] Erreur 1
    make[2]: quittant le répertoire « /home/bassouma/src/gst-rtsp-0.10.8/gst »
    make[1]: *** [all-recursive] Erreur 1
    make[1]: quittant le répertoire « /home/bassouma/src/gst-rtsp-0.10.8 »
    make: *** [all] Erreur 2

  • ghost

    so u think that i should make an update, ok

  • fred

    Comme « ghost » sur debian 6 j’ai les memes messages d’erreur en faisant make. (#11657)
    Dommage !

  • fred

    Installé ubuntu server 10 : idem. j’ai pourtant installé tous les packages essentiels. le Configure passe bien. pas le make.

    Voici ce que ca donne :

    Gst-rtsp-server configured. Type ‘make’ to build.

    root@GSTREAM:~/src/gst-rtsp-0.10.8# make
    make all-recursive
    make[1]: Entering directory `/root/src/gst-rtsp-0.10.8′
    Making all in gst
    make[2]: Entering directory `/root/src/gst-rtsp-0.10.8/gst’
    Making all in rtsp-server
    make[3]: Entering directory `/root/src/gst-rtsp-0.10.8/gst/rtsp-server’
    CC libgstrtspserver_0.10_la-rtsp-funnel.lo
    CC libgstrtspserver_0.10_la-rtsp-auth.lo
    CC libgstrtspserver_0.10_la-rtsp-params.lo
    CC libgstrtspserver_0.10_la-rtsp-sdp.lo
    CC libgstrtspserver_0.10_la-rtsp-media.lo
    CC libgstrtspserver_0.10_la-rtsp-media-factory.lo
    CC libgstrtspserver_0.10_la-rtsp-media-factory-uri.lo
    rtsp-media-factory-uri.c: In function ‘gst_rtsp_media_factory_uri_init’:
    rtsp-media-factory-uri.c:173: error: ‘gst_plugin_feature_rank_compare_func’ unde clared (first use in this function)
    rtsp-media-factory-uri.c:173: error: (Each undeclared identifier is reported onl y once
    rtsp-media-factory-uri.c:173: error: for each function it appears in.)
    rtsp-media-factory-uri.c: In function ‘find_payloader’:
    rtsp-media-factory-uri.c:301: warning: assignment makes pointer from integer wit hout a cast
    rtsp-media-factory-uri.c:311: warning: assignment makes pointer from integer wit hout a cast
    rtsp-media-factory-uri.c:321: warning: assignment makes pointer from integer wit hout a cast
    make[3]: *** [libgstrtspserver_0.10_la-rtsp-media-factory-uri.lo] Error 1
    make[3]: Leaving directory `/root/src/gst-rtsp-0.10.8/gst/rtsp-server’
    make[2]: *** [all-recursive] Error 1
    make[2]: Leaving directory `/root/src/gst-rtsp-0.10.8/gst’
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/root/src/gst-rtsp-0.10.8′
    make: *** [all] Error 2

    • @fred et @ghost: il doit vous manquer une librairie. Pouvez vous me faire un http://pastebin.com/ des commandes suivantes:

      cd ~/src/gst-rtsp-0.10.8/
      make clean
      make distclean
      ./configure

      • ghost

        Good Morning Nicolargo, Sorry for this late answer
        I execute the command line, u can take a look on

        http://pastebin.com/QfRy4UyH

        and thanks a lot .

        • I just found another person with the same issue (http://gstreamer-devel.966125.n4.nabble.com/Compile-problem-with-gstreamer-rtsp-server-td3326149.html).

          « You need GStreamer core >= 0.10.31 for this, which is available in the GStreamer PPA. »

          To check your GST core version, use this command:

          # gst-inspect fakesink | grep Version

          On my PC:

          Version: 0.10.32

          Hope it will help you.

        • ghost

          On my PC Version:0.10.29

          I download the gstreamer-0.10.31, but i didn’t knew how to install it, is it the same like gstreamer-0.10.29 ??

          • The best way is to use the dev PPA:

            add-apt-repository ppa:gstreamer-developers
            apt-get update
            apt-get safe-upgrade

  • ghost

    Or how to update my gstreamer Version, i think it’s more professionnel as solution.

  • ghost

    even after the update the Version didn’t changed, it’s 0.10.29, gonna insane really

    • Can you double check the GST core lib:

      # aptitude show libgstreamer0.10-dev
      Paquet : libgstreamer0.10-dev
      État: installé
      Automatiquement installé: non
      Version : 0.10.32-1~maverick1

      • ghost

        this is the message,

        Paquet : libgstreamer0.10-dev
        État: installé
        Automatiquement installé: non
        Version : 0.10.25-2
        Priorité : optionnel
        Section : libdevel
        Responsable : Ubuntu Developers
        Taille décompressée : 4 047k
        Dépend: libgstreamer0.10-0 (= 0.10.25-2), libc6-dev | libc-dev, pkg-config,
        libglib2.0-dev, libxml2-dev, libc6 (>= 2.3.6-6~), libglib2.0-0 (>=
        2.16)
        Recommande: debhelper
        Suggère: gstreamer0.10-doc
        Remplace: gobject-introspection-repository (< 0.6.5-2), gstreamer-tools (<
        0.10.20-2)
        Description : GStreamer core development files
        GStreamer est une infrastructure pour les flux multimédia, basée sur des
        graphes et filtres qui opèrent sur des données multimédia. Les applications qui
        utilisent cette bibliothèque peuvent tout faire, depuis le traitement du son en
        temps réel jusqu'à la lecture de vidéos, et traiter pratiquement tout ce qui
        est lié au multimédia. Son architecture, basée sur des greffons, permet
        d'ajouter facilement de nouveaux types de données ou de nouvelles possibilités
        de traitement.

        This package contains development files for the core library and elements.
        Site : http://gstreamer.freedesktop.org

        bassouma@bassouma-laptop:~$

        How can i install the version 0.10.31 ?? pleaaaaaaaaaaaaaaaaase :'(

        • I understand why my script did not work with our configuration….

          The PPA Gstreamer Dev is only available for Ubuntu 10.04 and 10.10.

          If you want to install the latest version of GStreamer on you system, you need to compil it from sources (here is my procedure to do this *hard* task: http://blog.nicolargo.com/2009/06/compiler-gstreamer-depuis-les-sources-sous-gnulinux.html).

          I think that the simple solution is to upgrade from 9.04 to 10.04 (a Long Time Support version of Ubuntu)…

          • ghost

            Ok, I will do it today, i will inform you about the results , thank you sooooooo much 😀

          • fred

            I did succeed on ubuntu 10.10 to setup this.
            I did that :
            apt-get install python-software-properties
            add-apt-repository ppa:gstreamer-developers
            aptitude safe-upgrade

            thks Nico !

  • Hasto

    Merci pour ce tutoriel. Il fait surement suite au mail que je vous avais envoyé tout début Mars. Nous avions aussi réussi à débloquer la situation par nous même pour diffuser un flux webcam en local( il suffit d’éditer le fichier test-readme.c en changeant la création du pipeline et en y incorporant v4l2src )Nous avons ensuite réussi à renvoyer ce flux sur une webTV. Nous travaillons actuellement sur sa compression en passant par un serveur DNS, la qualité étant pour le moment très médiocre.

    • Exactement 🙂

      Je viens également de changer la pipeline du code du fichier test-readme.c pour qu’il diffuse un flux live venant d’une webcam dans un stream H.264+RTP. Pour info j’utilise la pipeline suivante:


      v4l2src device=/dev/video0 ! queue ! videoscale method=1 ! videorate ! video/x-raw-yuv,width=(int)640,height=(int)400,framerate=(fraction)24/1 ! x264enc vbv-buf-capacity=3000 byte-stream=true bitrate=600 subme=4 ref=2 bframes=1 b-pyramid=true weightb=true ! rtph264pay name=pay0 pt=96

      Je serais intéressé d’avoir vos retours sur le sujet (options de x264enc, optimisation éventuelle). Mon mail se trouve dans la page contact du blog.

      • Hasto

        Je vous ai envoyé un email 🙂

        • Hasto

          Bonjour,
          je vous ai renvoyé un mail ce week end. L’avez vous bien recu?
          Merci 🙂

  • ghost

    Hi Nicolargo,
    The server is working now, actually the problem was as you said, a problem of system updating, my system now is ubuntu 10.04 LTS, the Gstreamer Version is 0.10.32 u were right , think you sooooo much, so interesting blog really, go ahead.

  • ghost

    Hi Nicolargo , Hi eveybody,
    I’ searching documents about rtsp_Gstremer_Server, I wanna know really the interaction and the dialogue between client and the server

  • ghost

    Hi Nicolargo , Hi eveybody,
    I’m searching documents about rtsp_Gstremer_Server, I want to know exactly how it is the interaction and exchange between the client and server , have documents or links which vcan help me , and thank you .

    • Hi Ghost,

      the documentation is located on the docs repository. But if you want a description of the RTSP protocole, the best is to have a look on the RFC: http://tools.ietf.org/html/rfc2326

      • ghost

        Thank you so much Nicolargo !!

  • ghost

    Hi everybody,

    I’m really surprised, i wanna use this streaming server in my application which represent a portal for VOD and TVs in direct, so i thought that this server can be managed by a Web service which i will developp in J2EE, but i discover in README.txt that this server can’t be able to be used in a big application in an IP network, this ‘s which is mentionned in README.txt:

    …The server currently integrates with the glib mainloop nicely. It is also a
    heavy user of multiple threads. It’s currently not meant to be used in
    high-load scenarios and you should probably not put it on a public IP address…

    Any explication ???!!!!!

  • Florentah

    Hi everybody, salut tout le monde

    j ai suivi le tuto et lance le ./test-readme

    Je vois bien que le serveur est cree et est en mode ecoute avc l outil netstat . Cependant loraue je lance la commande :
    gst-launch -v rtspsrc location=rtsp://127.0.0.1:8554/test ! queue ! decodebin ! ffmpegcolorspace ! autovideosink

    jai ce message d erreur:
    Setting pipeline to PAUSED …
    ERROR: Pipeline doesn’t want to pause.
    ERROR: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0: Could not read from resource.
    Additional debug info:
    gstrtspsrc.c(4573): gst_rtspsrc_send (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0:
    Got error response: 503 (Service Unavailable).
    Setting pipeline to NULL …
    Freeing pipeline …

    de meme jai un message d erreur ds vlc :
    live555 demux error: Failed to connect with rtsp://localhost:8554/test
    [0xb7308cd8] main input error: open of `rtsp://localhost:8554/test’ failed: (null)

    Quelqu un peut m eclaircir sur ce point?? merci d avance.

  • Florentah

    Hi everybody, salut tout le monde

    I followed the tutorial so i executed ./test-readme

    I can see activities of the server with the tool netstat. The server is listening however when i execute
    gst-launch -v rtspsrc location=rtsp://127.0.0.1:8554/test ! queue ! decodebin ! ffmpegcolorspace ! autovideosink

    i have this message error
    Setting pipeline to PAUSED …
    ERROR: Pipeline doesn’t want to pause.
    ERROR: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0: Could not read from resource.
    Additional debug info:
    gstrtspsrc.c(4573): gst_rtspsrc_send (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0:
    Got error response: 503 (Service Unavailable).
    Setting pipeline to NULL …
    Freeing pipeline …

    another message error when i use VLC
    live555 demux error: Failed to connect with rtsp://localhost:8554/test
    [0xb7308cd8] main input error: open of `rtsp://localhost:8554/test’ failed: (null)

    Who know this problem and/or can try to help me?
    thanks a lot

  • caligula

    Salut à tous,

    Avec avidemux, je n’arrive pas à produire un fichier mp4 compatible de test-mp4. Quelqu’un a-t-il une procédure ?

  • Pingback: Vidéo embarquée depuis un véhicule grâce à GStreamer | Webmaster Tunisie Blog()

  • Fadi

    Bonjour NicoLargo,

    merci beaucoup pour l’effort et les astuces précieuse dans le blog.

    en fait, est ce qu’il ya un moyen de faire le straming d’une source en temp réel avec ce serveur Gstreamer, En fait est il possible de faire le streming de mon Webcam par example ?! si oui comment ?

    merci infiniment

  • modelvincent

    Bonjour NicoLargo,

    Déja merci pour ce billet super interessant, j’ai un petit soucis sur la lecture de la mire depuis gstreamer.

    J’ai installé ubuntu en machine virtuelle, je lance le test-readme sur la machine virtuelle et j’y accede avec VLC depuis la machine virtuelle sans soucis, ainsi que depuis ma machine physique, donc le lien est bien créé, en revanche lorsque j’essaye d’utiliser Gstreamer pour lire le flux à la place de VLC avec la commande gst-launch -v rtspsrc location=rtsp://127.0.0.1:8554/test ! queue ! decodebin ! ffmpegcolorspace ! autovideosink, j’obtiens le message suivant:

    Définition du pipeline à PAUSED…
    Le pipeline est actif et n’a pas besoin de phase PREROLL…
    Passage du pipeline à la phase PLAYING…
    New clock: GstSystemClock


    ici j’ai viré pas mal de choses sur la mise en place du pipeline, a priori sans erreur

    ..

    puis j’obtiens ceci:

    libva: VA-API version 0.32.0
    libva: va_getDriverName() returns 0
    libva: Trying to open /usr/lib/i386-linux-gnu/dri/vboxvideo_drv_video.so
    libva: va_openDriver() returns -1

    ERROR: Caught a segmentation fault while loading plugin file:
    /usr/lib/gstreamer-0.10/libgstffmpeg.so

    Please either:
    – remove it and restart.
    – run with –gst-disable-segtrap –gst-disable-registry-fork and debug.

    Je n’arrive pas a comprendre ce qui se passe, j’ai essayé de reinstaller le codec ffmpeg mais sans succés.

    Merci d’avance

  • Inou Togola

    bjr Nicolardo,comment on fait pour créer un client?

  • Andy Kimpe

    lol impossible de compiler sous trusty erreur

    configure: error: no gstreamer-plugins-base-0.10 >= 0.10.29 (GStreamer Base Plugins) found

    gstreamer0.10-plugins-base version installer 0.10.36

  • thibaud leroy

    Bonjour, je déterre un peu ce poste, j’ai suivi ton tuto et quand j’arrive au point de faire le test dû redame via vlc j’ai l’erreur de l’image.
    pour information je suis en Ubuntu 14.04, gstreamer-0.10.36.
    S’il y a besoin d’information faite le moi savoir.suivi

  • thibaud leroy

    ubuntu@ubuntu-VirtualBox:~/src/gst-rtsp-0.10.8/examples$ ./test-readme

    ** (lt-test-readme:6730): CRITICAL **: could not parse launch syntax (( videotestsrc is-live=1 ! x264enc ! rtph264pay name=pay0 pt=96 )): pipeline vide non autorisé

    ** (lt-test-readme:6730): CRITICAL **: could not create element