Patrice Ferlet
Patrice Ferlet
Créateur de ce blog.
Publié le août 13, 2012 Temps de lecture: 18 min

Me suivre sur Mastodon

Didacticiel GStreamer

Gstreamer est un framework extrêmement puissant, bien pensé et vraiment utile permettant de travailler avec des flux audio et vidéo. Decodage, encodage, streaming, effets, et j’en passe… Il est impressionnant de simplicité à condition d’avoir des bases de connaissance sur les méthodes. C’est donc avec plaisirs que je vous propose une montée en compétence sur ce système de “pipeline”.

J’ai certainement beaucoup de retard pour créer un tel didacticiel, mais je ne peux pas tout faire à temps. J’ai eut envie de me pencher sur Gstreamer pour gérer une lecture de vidéo dans une application. J’ai tellement aimé gstreamer que j’ai décidé de vous proposer ce didacticiel.

D’abord, qui a besoin de gstreamer ?

Gstreamer est utilisé dans la plupart des applications utilisant des flux vidéo et audio. Totem, le lecteur inclu dans Gnome, KDE, Empathy pour les vidéo conférences, Web le navigateur Gnome pour la gestion des médias HTML5… La liste est longue. De ce fait, l’utilisateur final a besoin des plugins intégrés en général nativement par les distributions GNU/Linux ou BSD.

Mais si en plus vous avez envie de créer un outil que ce soit en script Bash ou via C, Java, Python ou je ne sais quel langage, GStreamer va vous soulager de la plupart des tâches complexes de gestion de flux (stream). En effet, il va vous permettre de lire des médias en tant que source, de l’envoyer dans des encodeurs, des décodeurs, des effets, puis d’aller directement se brancher sur le serveur de son (pulse, jack…) ou X pour la vidéo. Et ce avec un minimum d’effort.

Donc, clairement, les “utilisateurs” des pipeline gstreamer sont surtout les développeurs ou au moins des utilisateurs avertis qui veulent se créer des outils, des script ou les utiliser par curiosité.

Avant de savoir utiliser Gstreamer, il faut appréhender le fonctionnement de flux, de multiplexage et de “pipeline”.

Prenons un exemple relativement général: une vidéo avec du son. Nous allons prendre le cas où vous voulez lire un fichier avi qui contient un film complet.

Le principe est de récupérer deux flux: la vidéo et la bande son. C’est ce que nous appelons le démultiplexage. Le fichier conteneur sort une source binaire que nous devons découper en deux flux distincts.

Ces flux ont un format d’encodage (mp3, mp4, vorbis…) il faut donc les décoder afin de les utiliser. Et enfin il faut envoyer le flux décodé dans les sorties adéquates: la vidéo sur l’écran via le serveur graphique, et le son sur le serveur sonore qui envoit le tout dans les enceintes.

Ça en fait un paquet d’opérations n’est-ce pas ?

vidéo avec du son
       |
       |
+--------------------+
|   démultiplexage   |- flux de son -> décodage -> ... -> pulseaudio (sortie sonore) 
+--------------------+
          |
          +- flux vidéo -> décodage -> callage de taille -> ... -> Affichage

Gstreamer va vous permettre de faire ces opérations via une ligne de connexion appelée “pipeline”. C’est le même principe que les redirections de sortie de commandes en shell.

Petit rappel:

echo "coucou vous" | rev

la commande “echo” fait sortir “coucou vous”, puis le pipe “|” redirrige cette chaine dans la command “rev” (reverse, retourne le texte), ce qui sort “suov uocuoc”

Avec Gstreamer on utilisera non pas “|” mais “!” pour ne pas interférer avec le shell.

Chaque plugin GStreamer peut avoir ces “PADS” qui représentent des entrées/sorties:

  • des sorties: src
  • des entrées : sink

En plus de ces PADS, on peut utiliser des options, nommées “caps”, par exemple pour manipuler la qualité d’un encodage ou donner un nom à un plugin qu’on va réutiliser plusieurs fois.

Par conséquent, un pipeline gstreamer va être une simple série de branchements entre des “src” et des “sink”. Notez que le mot “sink” veut dire “lavabo”, l’idée étant de déverser un flux dans le lavabo qui se rempli, le plugin se débrouillera tout seul pour le vider à son rythme.

+----------+         +-----------+
|   pad    |         |   pad 2   |
|        (src) -> (sink)       (src) -> ... 
|          |         |           |
|        (src) -> (sink)         |
|          |         |           |
+----------+         +-----------+

Les bases sont en place, on entre dans le vif du sujet.

Afin de tester un pipeline, on peut utiliser la commande “gst-launch”.

Utilisons un fichier de son, disons “hello.ogg”. Je vous montrerai après comment on peut trouver quel plugin utiliser. Pour le moment faites moi simplement confiance.

On va :

  • Utiliser une source de type fichier: filesrc
  • demultiplexer de fichier oggvorbis pour avoir une sortie : oggdemux
  • on l’envoit ensuite dans le décodeur vorbis: vorbisdec
  • on l’envoit dans pulseaudio: pulsesink

L’idée est donc de raccorder un pipeline de ce type:

filesrc -> oggdemux -> vorbisdec -> pulsesink

Le plugin filesrc a une option nommée “location” qui permet de donner le chemin du fichier à utiliser. Voici la commande de lecture:

gst-launch filesrc location="hello.ogg" ! oggdemux ! vorbisdec ! pulsesink

Vous comprenez, on lit de gauche à droite, de sortie en entrée. Les “caps” (option de plugin) sont déposés à coté du nom du plugin, et on utilise “=” pour donner une valeur. Ainsi, le plugin filesrc à un caps “location” que j’utilise. C’est assez simple.

Vous allez me dire “ok, pour coder un truc qui fait de la lecture c’est cool, mais c’est pas drôle de devoir chercher constamment quel demultiplexeur et décodeur utiliser”. Et ce à quoi je vous répond que si je vous dis que gstreamer est vraiment bien pensé, c’est qu’il existe des méthodes qui ressemblent à de la magie.

En effet, il existe des plugins qui vous font gagner un temps fou. L’un d’entre eux est “decodebin” qui est un décodeur générique sortant du “raw”. Il fait office de proxy et se débrouille comme un chef pour trouver quel décodeur utiliser. Testons-le:

gst-launch filesrc location="hello.ogg" ! decodebin ! pulsesink

Magique non ?

Et là je vous vois venir: “oui, et si j’utilise pas pulseaudio ? Comment je sais quel sink final utiliser ?”. C’est là qu’intervient “autoaudiosink”. On teste:

gst-launch filesrc location="hello.ogg" ! decodebin ! autoaudiosink

“autoaudiosink” trouve quelle sortie sonore utiliser… Et tout seul en plus !

Dans le cas où on doit être générique, pour créer un petit lecteur par exemple, c’est simplement (je me répète) magique.

Important

Il faudra tout de même prendre quelques habitudes. Il est toujours intéressant de rééchantillonner le son avant de le faire sortir afin de soulager le calcul. En effet un son à un bitrate de 192khz pour une simple écoute de musique n’est pas forcément nécessaire, l’oreille humaine ne pourra pas entendre les hautes fréquences. D’autre part, envoyer un flux trop gros à un décodeur ou un lecteur peut avoir un véritable impact sur les performances, et certain encodeur n’accèpte pas certaines fréquences. Donc pour rester dans un seuil correct, on “resample” le son:

Ce sera aussi le cas avec les vidéo, il est recommandé de passer par les plugins ffmpegcolorspace et videoscale lors des traitements. Si je ne les mets pas dans mes exemples, pensez à le faire…

gst-launch filesrc location="hello.ogg" ! decodebin ! audioresample ! autoaudiosink

On fait compliqué, et on simplifira après

Cette partie va vous faire peur… alors avant de la lire en vous disant “ouais bha c’est le foutoir pour trouver quel decodeur, encodeur etc…” rapellez vous qu’on utilisera “decodebin” par la suite, et que par conséquent vous n’aurez pas à vous arracher les cheveux. Ici je vais simplement vous présenter comment on peut traiter deux flux en même temps. C’est **primordial** car sans cela vous ne saurez jamais lire/encoder une vidéo avec du son.

Ok pour le son. On va passer par la partie “vidéo” puis “audio/vidéo” mais avant tout il faut que je vous montre les outils qui permettent d’avoir des informations sur les plugins. Deux sont vraiment utiles dans tous les cas:

  • gst-inspect
  • gst-typefind

Le premier sert à inspecter les capacités d’un plugins. Sans argument vous allez lister tous les plugins installés. En utilisant “grep” vous pourrez alors trouver votre bonheur. Par exemple, pour trouver un plugin qui traite du mp3:

gst-inspect | grep mp3
typefindfunctions: application/x-id3v2: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: application/x-id3v1: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: application/x-apetag: mp3, ape, mpc, wv
typefindfunctions: audio/mpeg: mp3, mp2, mp1, mpga
mad:  mad: mad mp3 decoder
mpegaudioparse:  mp3parse: MPEG1 Audio Parser
ffmpeg:  ffmux_mp3: FFmpeg MPEG audio layer 3 formatter (not recommended, use id3v2mux instead)
ffmpeg:  ffdec_mp3on4float: FFmpeg MP3onMP4 decoder
ffmpeg:  ffdec_mp3on4: FFmpeg MP3onMP4 decoder
ffmpeg:  ffdec_mp3adufloat: FFmpeg ADU (Application Data Unit) MP3 (MPEG audio layer 3) decoder
ffmpeg:  ffdec_mp3adu: FFmpeg ADU (Application Data Unit) MP3 (MPEG audio layer 3) decoder
ffmpeg:  ffdec_mp3float: FFmpeg MP3 (MPEG audio layer 3) decoder
ffmpeg:  ffdec_mp3: FFmpeg MP3 (MPEG audio layer 3) decoder
lame:  lame: L.A.M.E. mp3 encoder
lame:  lamemp3enc: L.A.M.E. mp3 encoder

Notez qu’on aime beaucoup utiliser “mad” pour décoder le mp3 sous gstreamer. Et pour connaitre les informations d’un plugins, ce qui vous permettra en plus d’avoir la liste de pads et de caps:

gst-inspect mad

Je ne vous colle pas la sortie complète, mais vous y trouverez les sections “Pad Templates” et “Element Properties”. Vous voyez donc quel sont les capacités d’un plugin, les entrées, les sorties et les options.

Pour vous amuser, on va ajouter un echoe au son. On cherche ça:

gst-inspect | grep echo

On trouve “audioecho”… on regarde les options:

gst-inspect audioecho

Je trouve 3 options intéressantes: delay, feedback et intensity. “delay” étant en nanoseconde, feedback entre 0 et 1 et intensity entre 0 et 1. Voici un réglage sympa:

gst filesrc location="hello.ogg" ! decodebin ! audioresample ! audioecho feedback=0.8 delay=1200000000 intensity=0.2 ! autoaudiosink

Quant à “gst-typefind” il vous donnera le type du fichier que vous voulez traiter, par exemple :

gst-typefind hello.ogg
hello.ogg - application/ogg

Je suis donc “sûr” que mon fichier est en oggvorbis je sais donc quel plugin chercher… ou presque…

Allez, on passe à la vidéo. On utilisera encore une fois “decodebin”, mais pour vous montrer comment on se sert des sources et sink, je commence par la partie compliquée.

Prenons une vidéo et regardons quel type est utilisé:

gst-typefind Portishead\ -\ Wandering\ Star.mp4 
Portishead - Wandering Star.mp4 - video/quicktime, variant=(string)iso

Ok… du quicktime… bon et bien cherchons un demuxer…

gst-inspect | grep -i quicktime
...
isomp4:  qtdemux: QuickTime demuxer

Ok, là on va utiliser qtdemux. Quels sont les pads à utiliser:

gst-inspect qtdemux
...
Pad Templates:
  SRC template: 'subtitle_%02d'
    Availability: Sometimes
    Capabilities:
      ANY

  SRC template: 'audio_%02d'
    Availability: Sometimes
    Capabilities:
      ANY

  SRC template: 'video_%02d'
    Availability: Sometimes
    Capabilities:
      ANY

  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/quicktime
      video/mj2
      audio/x-m4a
      application/x-3gp

Aïe… ça se complique… Plusieurs “src” à utiliser, et en plus ce sont des “template”. Car ce type de fichier peut contenir des sous-titres, plusieurs sources vidéos, plusieurs piste de sons. Mais ne prenons pas peur. En informatique “%02d” veut dire “deux chiffres de type double (entier) et si le nombre ne tient pas 2 caractère on lui met un 0 (zéro), par exemple 01”, donc en toutes logique on va utiliser la vidéo: “video_00” pour avoir la première piste vidéo, et “audio_00” pour la première piste audio.

Ne cherchez pas encore comment savoir quel décodeur utiliser, ici je vous le dit: ma vidéo est en “h264” et le son en “aac”. Si je vous dis de ne pas chercher trop longtemps c’est que vous pourrez vous en passer par la suite. Je veux juste vous montrer comment récupérer des sources dans un plugin.

Dans un premier lieu, on peut se passer de cette option. Gstreamer va trouver tout seule quoi raccorder à quoi. De ce fait:

gst-launch filesrc location=Portishead\ -\ Wandering\ Star.mp4 ! qtdemux ! ffdec_h264 ! autovideosink

et pour le son:

gst-launch filesrc location=Portishead\ -\ Wandering\ Star.mp4 ! qtdemux ! ffdec_aac ! autoaudiosink

Alors comment je vais faire pour récupérer les deux en même temps ?

Et voilà comment on en vient à donner un nom à un pipe ! Le “caps” “name” qui est utilisable par tous les plugins va nous permettre cette manipulation. Le but est de pouvoir réutiliser un plugin en cours d’utilisation pour récupérer d’autres “src” (ou d’autres sink).

C’est là qu’il faut y aller par étape:

-on donne un nom au plugin de démultiplexeur pour l’identifier (avec l’option “name”), ici on l’appelera “q” -on récupère la piste qu’on veutavec nom_plugin.nom_propiété, donc d’abord la vidéo “video_00”, puis l’audio “audio_00” (comme indiqué par gst-inspect), via q.video_00 et q.audio_00. -On dira quel “src” ira dans quel “sink”, donc q.video_00 dans ffdec_h264 et q.audio_00 dans ffdec_aac

Allons-y par étape, je commence par la vidéo:

gst-launch filesrc location=Portishead\ -\ Wandering\ Star.mp4 ! qtdemux name=q q.video_00 ! ffdec_h264 ! autovideosink

Etudiez la ligne:

  • filesrc est envoyé à qtdemux -on ne met pas de “!”, on repart avec un src
  • je pars de q.video_00 qui est une source, et je l’envois dans ffdec_h264

Cela fonctionne donc comme les lignes précédentes.

J’insiste sur l’absence de “!” entre “name=q” et “q.video_00”. Pour être plus clair, cette commande se découpe en deux pipes:

  • file -> qtmux nommé “q”
  • q.video_00 -> ffdec -> sortie vidéo

Pour ajouter le pipe de son, on va donc mettre un nouveau pipe qui réutilise “q”:

  • q.audio_00 -> ffdec -> sortie sonore

C’est à dire:

... q.audio_00 ! ffdec_aac ! autoaudiosink

et voici la ligne de commande (qui ne marchera pas encore… vous allez comprendre):

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! qtdemux name=q \
q.video_00 ! ffdec_h264 ! autovideosink \
q.audio_00 ! ffdec_aac ! autoaudiosink

Vous voyez les 3 pipes:

  • filesrc -> qtdemux nommé “q”, “q” est donc le demultiplexeur
  • q.video_00 -> ffdec_h264 -> autovideosink
  • q.audio_00 -> ffdec_aac -> autoaudiosink

Important pour cette section

Avant de craquer, parce que d’une part vous n’avez peut-être pas compris la ligne, et que en plus ça marche toujours pas, lisez tout jusqu’au bout.

Alors pourquoi ça marche pas ? Et bien le problème c’est que là nous utilisons 2 flux. Il faut créer une file d’attente pour que gstreamer parse un peu les données et puisse gérer le tout en parallèle.

Explication: gstreamer a pris tout le pipeline et le passe comme on lui donne… du coup il tente de lire la vidéo mais l’audio est en pause dans un coin.

Ce n’est pas si compliqué, il faut mettre en “queue” les différentes parties du pipeline pour que tout parte en même temps, correctement callé. Et pour cela, on utiliser un plugin de base nommé “queue”. Il est super simple à utiliser, on le calle à des endroits stratégiques pour définir la mise en fil d’attente. On peut en utiliser autant qu’on veut.

Voici la commande que je vous propose:

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! qtdemux name=q \
q.video_00 ! queue ! ffdec_h264 ! autovideosink \
q.audio_00 ! queue ! ffdec_aac ! autoaudiosink

Voilà, gstreamer sait maintenant qu’il faut travailler avec une mise en queue sur chaque src. Et du coup ça fonctionne.

Notez que là je mets en queue juste avant le décodage, on peut aussi lui demander de la faire après:

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! qtdemux name=q \
q.video_00 ! ffdec_h264 ! queue ! autovideosink \
q.audio_00 ! ffdec_aac ! queue  ! autoaudiosink

Ou carrément avant et après:

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! qtdemux name=q \
q.video_00 ! queue ! ffdec_h264 ! queue ! autovideosink \
q.audio_00 ! queue ! ffdec_aac ! queue  !  autoaudiosink

A vous d’optimiser, en testant, on plantant le stream comme une misérable pomme oubliée en fin de récolte…

Ne vous découragez pas… car là, vous allez adorer la suite: on va rendre tout ça très très simple !

On va tout simplifier !

Je vous ai parlé du magique “decodebin”, mais j’ai oublié de vous dire qu’en plus il évite les prises de tête pour des recherche de nom de source etc…

Et ajoutons un point encore plus sympa: pas la peine de donner les nom de sources, car GStreamer sait quel src doit se racorder au plugin.

Comme je vous le disais, “nom_du_plugin.nom_de_propriété” permet d’avoir la propriété nommée “nom_de_propriété” dans un plugin nommé “nom_du_plugin”. Mais ce que je ne vous ai pas dit, c’est qu’en fait “nom_du_plugin.” (n’oubliez pas le point) permet de récupérer le plugin complet. On utilise un point pour ne pas interférer avec les nom de plugin. Un point en fin de nom veut simplement dire “nom que j’ai donné”. Donc là, quand je tape “qtdemux name=q” je pourrais réutiliser ce demuxer en utilisant “q.” dans mon pipline.

Comme gstreamer est cool, qu’il sait quoi raccorder en src dans un sink selon le type de flux, on va simplement donner le nom du demuxer, ça sera bien plus simple.

Ce que je vous dit là, c’est que le pipeline qu’on a créé plus haut pour demultiplexer un fichier quicktime, trouver les “src” qui vont bien, les raccorder à decodeur… peuvent simplement se faire via:

  • decodebin qui va démultiplexer et décoder
  • q. pour raccorder les pads au bon endroit

Laissez-moi vous montrer:

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! decodebin name=q \
q. ! queue !  autoaudiosink \ 
q. ! queue ! autovideosink

Et oui, gstreamer sait quel pad utiliser, le met en queue, et le branche à la sortie. Mais attendez, on peut simplifier:

gst-launch  -v filesrc location=./Portishead\ -\ Wandering\ Star.mp4 ! decodebin name=q \ 
! queue !  autoaudiosink \ 
q. ! queue ! autovideosink

Pas la peine de donner “q.” au premier branchement, puisque le plugin (decodebin ici) a des sorties. Inutile de le donner explicitement, le pipe “!” branche la sortie de decodebin sur la queue.

Par contre pour le second branchement (vers l’audio) je dois le donner car autoaudiosink n’a pas de sortie (c’est un sink).

Et il existe encore plus simple ! Le plugin “playbin” qui prend directement toutes les sorties et les plug dans les sorties audio et vidéo automatiquement.

Autre plugin intéressant: uridecodebin. Il permet de récupérer un stream depuis le disque dur, le net, un périphérique, etc. Exemple:

gst-launch uridecodebin uri="http://mirrorblender.top-ix.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_surround.avi" name=u ! autovideosink u. ! autoaudiosink

Ce plugin a d’autant plus des options pour régler la taille de tampon, le déclenchement de mise en buffer, etc.

On a parlé de décodeur, parlons maintenant d’encodage.

L’idée est la même, mais au lieu de brancher la sortie sur la carte son ou vidéo, on va l’envoyer dans un fichier. Il faut donc encoder les éléments puis les multiplexer pour en faire un seul élément.

On commence encore une fois par un truc simple, on va encoder un wav en oggvorbis, la chaine sera:

filesrc -> decode -> conversion + resample -> encode en vorbis -> écriture dans un fichier (filesink)

On va utiliser les éléments simples, j’entends par là que j’utiliserai “decodebin” pour avoir le flux décodé de mon fichier source afin d’éviter de vous mettre une chaine de décodage complexe. Par contre pour la sortie en oggvorbis, il est logique de devoir spécifier l’encodeur… Puisque c’est le but.

  • filesrc monfichier mp3 -decodebin pour avoir un flux raw
  • audioconvert pour avoir un flux converti
  • audioresample pour rééchantillonner
  • vorbisenc pour encoder au format vorbis
  • oggmux pour en faire un fichier au format .ogg -filesink pour écrire

Pas mal de plugins, mais c’est logique.

gst-launch -v filesrc location="Portishead - Roads.mp3" ! decodebin ! \
audioconvert ! \
audioresample ! \
vorbisenc ! \
oggmux ! \
filesink location=out.ogg

C’est très rapide. Testez le fichier out.ogg et vous verrez que ça fonctionne bien.

Bon et bien encodons une vidéo au format ogv ! On va utiliser la même méthode, c’est-à-dire récupérer les sources, encoder, multiplexer le tout dans un seul fichier, et enfin le déposer dans un fichier.

Ça va ressembler à ça:

   filesrc (fichier d'entrée)
     |
     |     -(vidéo) -> queue -------> theoraenc --------
     |    /                                             \
 decodebin                                               -> oggmux --+ 
     d.   \                                             /    mux.    |
           -(audio) -> queue -> resample -> vorbisenc --             |
                                                                     |
                                                                     |
+--------------------------------------------------------------------+
|
+---> filesink (fichier de sortie)

Avant de lire la commande ci dessous, prenez le temps de comprendre. On va ouvrir un décodeur qu’on nomme “d”, chaque fois que je vais appeler “d.” je récupère un flux que j’envois dans un plugin.

Un multiplexeur (muxer) nommé “mux” va récupérer les deux sorties, la vidéo et l’audio. On redirige enfin les muxer dans un sink fichier pour sauver le résultat.

Je vous le fait pas à pas:

  • je décode la source

gst-lauch filesrc location="video.mp4" decodebin name=d

  • je récupère la sortie son, on la place en queue, on resample, on encode en vorbis et j’envois ça dans un muxer ogg

d. ! queue ! audioconvert ! audioresample ! vorbisenc ! oggmux name=mux

  • on reprend le flux decodé (d), cette fois la vidéo, on la place en queue, dans theoraenc, puis envoyée dans le muxer ogg déclaré plus haut

d. ! queue ! theoraenc ! mux.

  • je reprend le muxer, j’envoi le tout dans un fichier

mux. ! filesink location="out.ogv"

En une ligne:

gst-lauch filesrc location="video.mp4" decodebin name=d \
d. ! queue ! audioconvert ! audioresample ! vorbisenc ! oggmux name=mux \
d. ! queue ! theoraenc ! mux. \
mux. ! filesink location="out.ogv"

Et sans le “d.” implicite en seconde ligne:

gst-lauch filesrc location="video.mp4" ! decodebin name=d \
! queue !audioconvert ! audioresample ! vorbisenc ! oggmux name=mux \
d. ! queue ! theoraenc ! mux. \
mux. ! filesink location="out.ogv"

Petit conseil: utiliser ffmpegcolorspace pour permettre à Gstreamer de récuperer le bon espace de couleur avant d’encoder, ou décoder une vidéo… vous savez, l’hitoire des vidéo en RGB, YUV, etc.

Donc, plus proprement:

gst-lauch filesrc location="video.mp4" ! decodebin name=d \
! queue ! audioconvert ! audioresample ! vorbisenc ! oggmux name=mux \
d. ! queue ! ffmpegcolorspace ! theoraenc ! mux. \
mux. ! filesink location="out.ogv"

Bon, ça va servir à quoi tout ça ?

Ce que je me suis efforcé de vous montrer, ce n’est pas “comment lire/encoder un fichier audio/vidéo” car pour cela vous avez des lecteurs bien plus simples. L’idée et de vous montrer comment fonctionne un pipeline gstreamer pour s’en servir dans du code. Python, C, Java, etc. Car désormais vous savez sortir un flux vidéo ou audio, et par conséquent vous allez pouvoir l’utiliser. L’idée principale étant d’intégrer une vidéo dans un programme.

Il sera effectivement simple d’utiliser un effet vidéo, de le placer après un stream, d’encoder dans différent format, simplement en créant un pipeline gstreamer.

Je pense créer un didacticiel python très prochainement pour vous montrer comment on peut utiliser gstreamer dans un programme Gtk. Mais pour l’heure, essayez de créer des pipeline, regardez du coté du plugin “v4l2src” pour capter la caméra (petit conseil, utilisez ximagesink pour la sortie plutôt que autovideosink), tenter des encodages, revoyez comment on utilise les nom assigné au plugins (le nom avec un point) etc. Ne paniquez pas si ça passe pas du premier coup, je passe parfois un peu de temps à trouver le bon pipeline, je m’y reprend à plusieurs fois, mais à la fin vous serez heureux d’avoir un bon pipeline qui vous permette de faire exactement ce que vous voulez.

Notez bien que que c’est vraiment simple:

  • sink = entrée
  • src = sortie source.

C’est tout !

comments powered by Disqus