X分钟过后重新启动GStreamer管道

时间:2015-10-08 10:40:20

标签: multithreading gstreamer video-recording

我有一个正在运行的GStreamer应用程序,用于将RTSP流记录到.avi文件中。一般管道如下:

gst-launch-1.0 rtspsrc location=... ! decodebin ! x264enc ! avimux ! filesink location=video.avi

我现在要做的是每隔X分钟录制一个新的视频文件。例如,运行GStreamer应用程序一小时将为我提供12个视频文件,每个视频文件为5分钟,而不是1个60分钟长的视频文件。我想到了几个方法:

  
      
  1. 创建一个计时器线程,使其休眠5分钟,然后发送EOS信号,然后进行相关的重新初始化。
  2.   

我不确定这是否真的可行,因为我不认为计时器线程能够与总线通信。

  
      
  1. 创建一个外部线程来运行GStreamer部分,并每隔5分钟重启一次。
  2.   

我不确定这种方法的副作用。突然终止记录管道似乎破坏了视频时钟的定时,例如10秒钟的视频最初显示为13秒。

  
      
  1. 利用GStreamer在GST_STATE_PLAYING跟踪时间的任何内容,并在5分钟后将EOS发送到公交车。
  2.   

我不知道如何做到这一点,但我认为这与方法2相结合是最好的方法。

  
      
  1. 使用num-buffers=(X*60)*fps
  2.   

这在数学上是有意义的,但在将帧率用作乘数之前必须知道帧速率。

如何实施方法3?有没有更好的方法呢?

2 个答案:

答案 0 :(得分:0)

你有gstreamer的multifilesink插件吗?
如果是,那么您可以使用属性max-duration定期分割文件
经过一点搜索后,可以看到此属性是以纳秒为单位。 因此,您的命令可能类似于1秒分割

gst-launch-1.0 rtspsrc multifilesink location = video%04.avi max-duration = 1000000000! decodebin! x264enc! avimux! filesink

答案 1 :(得分:0)

添加超时并使用新的filesink位置重新启动整个流将是最简单的解决方案。只需添加一个计时器(如果你愿意,可以使用glib):

https://developer.gnome.org/pygobject/stable/glib-functions.html#function-glib--timeout-add-seconds

抓住公共汽车并发布EOS:

GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(my_pipeline));

gst_bus_post(bus, gst_message_new_eos(GST_OBJECT(some_object)));

gst_object_unref(bus);

如果你要存储重要的东西,你可能想确保文件有重叠。在这种情况下,我可能会建议让一个外部进程(比如一个shell脚本)生成文件名并调用你的程序有一些重叠。

您还可以使用output-selector元素做一些比较漂亮的事情,在这里你有这样的起始管道:

rtspsrc0 -> decodebin0 -> output-selector0 pad-negotiation-mode=active -> (x264enc0 -> avimux0 -> filesink0)

...然后你去看看:

rtspsrc0 -> decodebin0 -> output-selector0 -> (x264enc0 -> avimux0 -> filesink0)

output-selector0-> (x264enc1 -> avimux1 -> filesink1)

...并从src_0' to src_1`更改活动垫,将EOS发送到第一组AVI元素,然后留下:

rtspsrc0 -> decodebin0 -> output-selector0 pad-negotiation-mode=active -> (x264enc1 -> avimux1 -> filesink1)

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-output-selector.html