GNU/Linux >> Linux Esercitazione >  >> Linux

Mettere in loop un video con gstreamer e gst-launch?

Questo sembra essere possibile con multifilesrc plugin,

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

Sembra essere stato aggiunto nel giugno 2011.


multifilesrc è il modo più semplice, ma non funzionerà su file multimediali di cui è nota la "lunghezza del supporto". puoi eseguire il loop su qualsiasi file video solo se il file non ha alcuna informazione sul tempo o sulla durata.

Apri il tuo file con qualsiasi lettore multimediale, se mostra la lunghezza del supporto o se puoi cercare il file avanti o indietro, significa che conosce la lunghezza del supporto e multifilesrc non lo ripeterà.

Come convertire file video in file senza traccia temporale (file stream) con GStreamer:

devi eseguire due pipeline sulla riga di comando, prima esegui il registratore:

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

si avvia e attende il flusso in arrivo.

su un altro terminale eseguire la play pipeline:

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

la pipeline di riproduzione inizia e alla fine termina quando ha trasmesso in streaming l'intero file, ora torna alla prima riga di comando e termina la pipeline di registrazione con Ctrl+C.

(invece di udpsrc/udpsink puoi usare qualsiasi altro meccanismo per creare lo stream, come appsrc/appsink)

Ora hai un nuovo file che può essere usato in multifilesrc con ciclo:

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

Perché multifilesrc non ripete i file di lunghezza nota?

Poiché quando la lunghezza del supporto è nota, invia il messaggio EOS a valle e fa sì che l'intera pipeline passi allo stato NULL, rimuovendo tali informazioni quando raggiunge la fine del file (flusso di byte) tenta di trovare il file successivo da riprodurre (ricorda che è "multiplo" sorgente del file e per impostazione predefinita può accettare la posizione con caratteri jolly come "image_%d.png"). Quando non ci sono caratteri jolly che puntano al file successivo, torna indietro solo al file conosciuto.


Secondo la gente del #gstreamer Canale IRC, non puoi farlo con gstreamer stesso, avresti bisogno di qualcosa al di fuori della pipeline di gstreamer per eseguirne il loop.


Se usi gst-launch allora potresti dover usare while true; do [your command]; done come ha affermato Fredrik. Tuttavia, se sei interessato al codice C, ho scritto un codice che potrebbe aiutarti. Looping del video ogni 2 secondi dall'inizio del file alla fine del flusso della prima esecuzione.

  //(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;
}

Aggiornamento: Vedere il seguente collegamento http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-dataaccess.html

[Sezione 19.1.2. Riproduci una regione di un file multimediale]. Questo potrebbe essere usato in coniugazione con il mio codice.


Linux
  1. Scarica una porzione di video di Youtube con Youtube-dl e FFmpeg

  2. Aggiungere un file audio e video Mkv?

  3. AWK e nomi di file con spazio al suo interno.

  4. Preservare i permessi di file e cartelle con rsync

  5. Monta con sshfs e scrivi i permessi dei file

Spiegazione di Soft Link e Hard Link in Linux con esempi

Manipolazione del testo con sed e grep

Come lavorare con hardlink e softlink in Linux

Come lavorare con File e Shell Provisioner in Vagrant

Permessi e proprietà dei file Linux spiegati con esempi

Gestisci le autorizzazioni di directory e file con chmod Recursive