GNU/Linux >> Tutoriels Linux >  >> Linux

Boucler une vidéo avec gstreamer et gst-launch ?

Cela semble être possible avec multifilesrc plug-in,

gst-launch-1.0 multifilesrc location=alien-age.mpg loop=true ! decodebin ! autovideosink

Semble avoir été rajouté en juin 2011.


multifilesrc est le moyen le plus simple, mais cela ne fonctionnera pas sur les fichiers multimédias dont la "longueur du support" est connue. vous pouvez boucler sur n'importe quel fichier vidéo uniquement si le fichier ne contient aucune information sur l'heure ou la durée.

Ouvrez votre fichier avec n'importe quel lecteur multimédia, s'il affiche la longueur du média ou si vous pouvez rechercher le fichier en avant ou en arrière, cela signifie qu'il connaît la longueur du média et multifilesrc ne le bouclera pas.

Comment convertir un fichier vidéo en fichier sans piste temporelle (fichier flux) avec GStreamer :

vous devez exécuter deux pipelines en ligne de commande, lancez d'abord l'enregistreur :

gst-launch-1.0 udpsrc port=10600 ! application/x-rtp-stream ! rtpstreamdepay name=pay1 ! rtph264depay ! h264parse ! video/x-h264,alignment=nal ! filesink location=my_timeless_file.mp4

il démarre et attend le flux entrant.

sur un autre terminal, lancez le pipeline de lecture :

gst-launch-1.0 filesrc location=my_file_with_time_track ! queue ! decodebin ! videoconvert ! x264enc ! h264parse config-interval=-1 ! rtph264pay pt=96 ! rtpstreampay name=pay0 ! udpsink host=127.0.0.1 port=10600

lire le pipeline démarre et finit par se terminer lorsqu'il a diffusé tout le fichier, revenez maintenant à la première ligne de commande et terminez l'enregistrement du pipeline avec Ctrl+C.

(au lieu de udpsrc/udpsink, vous pouvez utiliser n'importe quel autre mécanisme pour créer le flux, comme appsrc/appsink)

Vous avez maintenant un nouveau fichier qui peut être utilisé dans multifilesrc avec boucle :

gst-launch-1.0 multifilesrc location=my_timeless_file.mp4 loop=true ! queue ! decodebin ! videoconvert ! ximagesink

Pourquoi multifilesrc ne boucle pas les fichiers de longueur connue ?

Parce que lorsque la longueur du support est connue, il envoie un message EOS en aval et fait passer tout le pipeline à l'état NULL, en supprimant ces informations lorsqu'il atteint la fin du fichier (flux d'octets), il essaie de trouver le prochain fichier à lire (rappelez-vous que c'est "multi" source du fichier et, par défaut, peut accepter un emplacement générique tel que "image_%d.png"). Lorsqu'il n'y a pas de caractère générique pour pointer vers le fichier suivant, il revient uniquement au fichier connu.


D'après les gens du #gstreamer canal IRC, vous ne pouvez pas faire cela avec gstreamer lui-même, vous auriez besoin de quelque chose en dehors du pipeline gstreamer pour le boucler.


Si vous utilisez gst-launch, vous devrez peut-être utiliser while true; do [your command]; done comme l'a dit Fredrik. Cependant, si vous êtes intéressé par le code C, j'ai écrit un code qui peut vous aider. Bouclage de la vidéo toutes les 2 secondes du début du fichier à la fin du flux de première exécution.

  //(c) 2011 enthusiasticgeek
  // This code is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#include <gst/gst.h>

gboolean bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
{
    GstElement *play = GST_ELEMENT(data);
    switch (GST_MESSAGE_TYPE(msg))
    {
    case GST_MESSAGE_EOS:
        /* restart playback if at end */
        if (!gst_element_seek(play, 
                    1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
                    GST_SEEK_TYPE_SET,  2000000000, //2 seconds (in nanoseconds)
                    GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
            g_print("Seek failed!\n");
        }
        break;
    default:
        break;
    }
    return TRUE;
}

gint
main (gint   argc,
      gchar *argv[])
{
  GMainLoop *loop;
  GstElement *play;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* make sure we have a URI */
  if (argc != 2) {
    g_print ("Usage: %s <URI>\n", argv[0]);
    return -1;
  }

  /* set up */
  play = gst_element_factory_make ("playbin", "play");
  g_object_set (G_OBJECT (play), "uri", argv[1], NULL);

  bus = gst_pipeline_get_bus (GST_PIPELINE (play));
  gst_bus_add_watch (bus, bus_callback, play);
  gst_object_unref (bus);

  gst_element_set_state (play, GST_STATE_PLAYING);

  /* now run */
  g_main_loop_run (loop);

  /* also clean up */
  gst_element_set_state (play, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (play));

  return 0;
}

Mise à jour : Voir le lien suivanthttp://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-dataaccess.html

[Chapitre 19.1.2. Lire une région d'un fichier multimédia]. Cela pourrait être utilisé en conjugaison avec mon code.


Linux
  1. Rechercher des fichiers et des répertoires sous Linux avec la commande find

  2. Téléchargez une partie de la vidéo Youtube avec Youtube-dl et FFmpeg

  3. Chiffrement et déchiffrement de fichiers simplifiés avec GPG

  4. Chiffrement et déchiffrement de fichiers avec ccrypt

  5. Ajouter un fichier audio à une vidéo Mkv ?

Expliquer Soft Link et Hard Link sous Linux avec des exemples

Manipuler du texte avec sed et grep

Comment travailler avec des liens durs et des liens souples sous Linux

Comment travailler avec File and Shell Provisioner dans Vagrant

Autorisations et propriété des fichiers Linux expliquées avec des exemples

Gérer les autorisations de répertoire et de fichier avec chmod Recursive