用gstreamer和gst-launch循环播放视频?

Ror*_*ory 5 linux video video-processing gstreamer gnonlin

我可以在gstreamer的命令行上播放视频gst-launch:

gst-launch gnlfilesource location=file:///tmp/myfile.mov start=0 duration=2000000000 ! autovideosink
Run Code Online (Sandbox Code Playgroud)

这将在/tmp/myfile.mov中播放文件的前2秒,之后视频播放停止.无论如何要让它重复循环?gnlfilesource即将2秒长转为无限长度的视频,一次又一次播放2秒钟?

ent*_*eek 10

如果使用gst-launch,那么你可能必须while true; do [your command]; done像Fredrik所说的那样使用.但是,如果对C代码感兴趣,我编写了一个可能对您有所帮助的代码.在第一次运行流结束时从文件开始每2秒循环一次视频.

  //(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;
}
Run Code Online (Sandbox Code Playgroud)

更新: 请参阅以下链接 http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-dataaccess.html

[第19.1.2节.播放媒体文件的某个区域].这可以用于与我的代码共轭.

  • 然而,有趣的是,时间戳不会随着此解决方案单调增加. (2认同)

Kei*_*van 8

multifilesrc是最简单的方法,但它不适用于已知“媒体长度”的媒体文件。仅当文件没有任何有关时间或长度的信息时,您才可以循环播放任何视频文件。

使用任何媒体播放器打开文件,如果它显示媒体长度或者您可以向前或向后搜索文件,则意味着它知道媒体长度并且multifilesrc不会循环播放。

如何使用GStreamer将视频文件转换为无时间轨迹文件(流文件):

您需要在命令行上运行两个管道,首先运行记录器:

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
Run Code Online (Sandbox Code Playgroud)

它启动并等待传入​​的流。

在另一个终端上运行播放管道:

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
Run Code Online (Sandbox Code Playgroud)

播放管道在流式传输整个文件时启动并最终终止,现在返回到第一个命令行并使用 Ctrl+C 终止记录管道。

(您可以使用任何其他机制来代替 udpsrc/udpsink 来制作流,例如 appsrc/appsink)

现在您有了一个可以在multifilesrcwith 循环中使用的新文件:

gst-launch-1.0 multifilesrc location=my_timeless_file.mp4 loop=true ! queue ! decodebin ! videoconvert ! ximagesink
Run Code Online (Sandbox Code Playgroud)

为什么multifilesrc不循环已知长度的文件?

因为当知道媒体长度时,它会向下游发送 EOS 消息并导致整个管道进入 NULL 状态,通过在到达文件末尾(字节流)时删除该信息,它会尝试找到下一个要播放的文件(记住它是“多”文件)文件源,默认情况下可以接受通配符位置,如“image_%d.png”)。当没有通配符指向下一个文件时,它将循环回仅已知的文件。


Ror*_*ory 6

根据#gstreamerIRC 频道上的人员的说法,您无法使用 gstreamer 本身来做到这一点,您需要 gstreamer 管道之外的东西来循环它。


Bar*_*ray 6

这似乎可以用multifilesrc插件,

gst-launch-1.0 multifilesrc location=alien-age.mpg loop=true ! decodebin ! autovideosink
Run Code Online (Sandbox Code Playgroud)

似乎将在2011年6月加入.

  • 在使用 v4l2loopback 的浏览器中将视频作为网络摄像头进行流式传输时,在 Ubuntu 18.04 上不会循环。 (3认同)

Fre*_*ihl 1

假设巴什...

将其包裹在一个while循环中?

while true; do [your command]; done
Run Code Online (Sandbox Code Playgroud)

哪里true没有成功,即

true: true
    Return a successful result.

    Exit Status:
    Always succeeds.
Run Code Online (Sandbox Code Playgroud)

它允许您创建无限循环,例如

$ while true; do echo "run..."; sleep 1; done
run...
run...
run...
run...
run...
...
Run Code Online (Sandbox Code Playgroud)

  • 确切地说,这是可行的,但我想在 gstreamer 中完成它,这样我就可以稍后处理这个无限循环...... (3认同)