Esto parece ser posible con multifilesrc
complemento,
gst-launch-1.0 multifilesrc location=alien-age.mpg loop=true ! decodebin ! autovideosink
Parece que se agregó en junio de 2011.
multifilesrc
es la forma más fácil, pero no funcionará en archivos de medios que tengan conocida la "longitud de los medios". puede reproducir en bucle cualquier archivo de video solo si el archivo no tiene información sobre el tiempo o la duración.
Abra su archivo con cualquier reproductor de medios, si muestra la longitud de los medios o si puede buscar el archivo hacia adelante o hacia atrás, eso significa que conoce la longitud de los medios y multifilesrc
no lo repetirá.
Cómo convertir un archivo de video en un archivo sin registro de tiempo (archivo de transmisión) con GStreamer:
necesita ejecutar dos canalizaciones en la línea de comando, primero ejecute la grabadora:
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
se inicia y espera la transmisión entrante.
en otra terminal, ejecute la canalización de reproducción:
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
play pipeline comienza y eventualmente termina cuando se transmite todo el archivo, ahora regrese a la primera línea de comando y finalice la grabación de pipeline con Ctrl+C.
(en lugar de udpsrc/udpsink, puede usar cualquier otro mecanismo para hacer la transmisión, como appsrc/appsink)
Ahora tiene un nuevo archivo que se puede usar en multifilesrc
con bucle:
gst-launch-1.0 multifilesrc location=my_timeless_file.mp4 loop=true ! queue ! decodebin ! videoconvert ! ximagesink
Por qué multifilesrc
no hace un bucle de archivos con una longitud conocida?
Debido a que cuando se conoce la longitud de los medios, envía un mensaje EOS en sentido descendente y hace que toda la canalización pase al estado NULL, al eliminar esa información cuando llega al final del archivo (flujo de bytes), intenta encontrar el siguiente archivo para reproducir (recuerde que es "multi" fuente del archivo y, de forma predeterminada, puede aceptar una ubicación comodín como "image_%d.png"). Cuando no hay un comodín para apuntar al siguiente archivo, regresa solo al archivo conocido.
Según la gente del #gstreamer
Canal IRC, no puede hacer esto con gstreamer en sí, necesitaría algo fuera de la canalización de gstreamer para hacer un bucle.
Si usa gst-launch, es posible que deba usar while true; do [your command]; done
como ha dicho Fredrik. Sin embargo, si está interesado en el código C, he escrito un código que puede ayudarlo. Bucle de video cada 2 segundos desde el comienzo del archivo hasta el final de la transmisión de la primera ejecución.
//(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;
}
Actualización: Consulte el siguiente enlace http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-dataaccess.html
[Sección 19.1.2. Reproducir una región de un archivo multimedia]. Esto podría usarse en conjugación con mi código.