我有一个正在运行的GStreamer应用程序,用于将RTSP流记录到.avi文件中。一般管道如下:
gst-launch-1.0 rtspsrc location=... ! decodebin ! x264enc ! avimux ! filesink location=video.avi
我现在要做的是每隔X分钟录制一个新的视频文件。例如,运行GStreamer应用程序一小时将为我提供12个视频文件,每个视频文件为5分钟,而不是1个60分钟长的视频文件。我想到了几个方法:
- 创建一个计时器线程,使其休眠5分钟,然后发送EOS信号,然后进行相关的重新初始化。
醇>
我不确定这是否真的可行,因为我不认为计时器线程能够与总线通信。
- 创建一个外部线程来运行GStreamer部分,并每隔5分钟重启一次。
醇>
我不确定这种方法的副作用。突然终止记录管道似乎破坏了视频时钟的定时,例如10秒钟的视频最初显示为13秒。
- 利用GStreamer在
醇>GST_STATE_PLAYING
跟踪时间的任何内容,并在5分钟后将EOS发送到公交车。
我不知道如何做到这一点,但我认为这与方法2相结合是最好的方法。
- 使用
醇>num-buffers=(X*60)*fps
这在数学上是有意义的,但在将帧率用作乘数之前必须知道帧速率。
如何实施方法3?有没有更好的方法呢?
答案 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)