Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gstreamer:将录制从一个文件切换到另一个文件_Gstreamer - Fatal编程技术网

gstreamer:将录制从一个文件切换到另一个文件

gstreamer:将录制从一个文件切换到另一个文件,gstreamer,Gstreamer,我正在编写一个应用程序,将传入的视频记录到一个文件中,每隔“t”秒,就会将该文件和记录保存到一个新文件中。splitmuxsink似乎实现了这一点,但不符合我的目的,因为- 它不允许连续文件之间重叠。我希望一个文件的最后几秒钟也出现在下一个文件中 splitmuxsink还存在其他奇怪的问题(与普通FileLink相比,延迟太大,不能像FileLink那样录制音频,文件的时间戳不正确,等等) 因此,我希望应用程序每隔“t”秒触发一次基于时间的回调。在我的管道中,我有一个mux,通过它我可以同

我正在编写一个应用程序,将传入的视频记录到一个文件中,每隔“t”秒,就会将该文件和记录保存到一个新文件中。splitmuxsink似乎实现了这一点,但不符合我的目的,因为-

  • 它不允许连续文件之间重叠。我希望一个文件的最后几秒钟也出现在下一个文件中
  • splitmuxsink还存在其他奇怪的问题(与普通FileLink相比,延迟太大,不能像FileLink那样录制音频,文件的时间戳不正确,等等)
因此,我希望应用程序每隔“t”秒触发一次基于时间的回调。在我的管道中,我有一个mux,通过它我可以同时写入两个文件一段时间(取决于重叠),然后根据另一个计时器回调,断开旧的FileLink

我有以下问题:

  • 上述计划是一个好主意吗?还有更好的主意吗
  • 如何注册计时器回调?只是OS系统调用还是gstreamer提供任何API
  • 断开旧文件链接的安全方法是什么?是否应先断开连接,然后发送EOS信号?我有点困惑
  • 更改新文件在管道中的时间。splitmuxsink中的一个问题是,该文件带有管道运行时间的时间戳,但实际上,每次创建新文件时,该时间戳都会重置。(我不介意现在还没有得到答案;这可能是一个单独的问题。)

  • 为了了解所涉及的时间,每个文件的持续时间可能为5分钟,重叠时间可能为1%,3秒。

    我将实施以下解决方案

  • 使用元素将视频分割为2个动态(在运行时)创建的源(src PAD),其中
    mux
    filesink
    作为每个
    src
  • 根据您的逻辑动态添加/删除
    tee
    src焊盘1和2(以及附加的元素src->mux->filesink)。在您的情况下,您需要为您的环境以标准方式实现2个计时器

  • 正如您所说,有一种安全的断开“旧文件链接”连接的方法。在建议的解决方案中,您需要通过在要删除的
    tee
    src pad上注册阻塞来断开/删除管道的“旧”src->mux->filesink部分。例如,安全删除src1及其下游元素可以这样实现

    GstElement* videoTee = gst_bin_get_by_name(GST_BIN(pipeline), "tee");
    GstPad* srcPad = gst_element_get_static_pad(videoTee, "src_1");
    gst_pad_add_probe(srcPad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, remove_video_tee_block_probe_cb, &user_data, NULL);
    gst_object_unref(srcPad);
    gst_object_unref(videoTee);
    
    然后,在
    remove\u video\u tee\u block\u probe\u cb
    回调中,可以删除src pad和连接的mux和filesink

    GstPadProbeReturn remove_video_tee_block_probe_cb(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) {
        /*user_data should contain reference to pipeline*/
        StreamData* streamData = (StreamData*)user_data;
    
        GstElement* videoTee = gst_bin_get_by_name(GST_BIN(streamData->pipeline), "videoTee");
        /*video tee src pad is blocked now and it can be safely removed*/
        gst_element_release_request_pad(videoTee, pad);
    
        GstElement* mux = gst_bin_get_by_name(GST_BIN(streamData->pipeline),  "mux1");
        GstElement* fileSink =gst_bin_get_by_name(GST_BIN(streamData->pipeline), "sink1");
        /* set state of element from PLAYING to NULL */
        gst_element_set_state(mux, GST_STATE_NULL);
        gst_element_set_state(fileSink, GST_STATE_NULL);
        /* remove elements from pipeline */
        gst_bin_remove(GST_BIN(streamData->pipeline), mux);
        gst_bin_remove(GST_BIN(streamData->pipeline), fileSink);
    
        gst_object_unref(videoTee);
    
       /* remove the probe*/
       gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID(info));
    
       return GST_PAD_PROBE_OK;
    }
    

  • 此解决方案将允许您根据您的逻辑在计时器回调中添加/删除管道的src->mux->filesink部分,从而在运行时控制filesink的存在。

    谢谢。我有几个后续问题-1。看起来我没有提到我也有音频,视频+音频应该同步录制。最简单的方法是在mux元素之后添加tee。例如-视频+音频编码->matroskamux->tee->两个文件链接。问题在于,当接收到关键帧时,应该发生阻塞。有什么建议可以做到这一点吗?2.当T形三通的一个衬垫被堵塞时,它不会以任何方式影响另一个衬垫吗?@RajatRao,1。如果存在音频,则需要在输入文件解复用(到视频和音频中)后添加“音频”T形三通。如果有音频的话,这个解决方案看起来会稍微复杂一些,但想法还是一样的。2.如果T形三通上有两个src焊盘,并且如果您阻止了其中一个,则另一个将继续工作而不会中断。您还希望通过录制队列发送EOS以完成文件链接。