微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

连接到正在播放的发球台

如何解决连接到正在播放的发球台

我正在使用 gstreamer 将视频从摄像机流式传输到 HLS 接收器,并将该视频作为 MP4 录制到文件系统。我使用 T 恤将视频分成两条路径。我写了一些代码,如果我把它全部连接起来并将状态切换到“播放”,它就会工作。但是当我开始流式传输并尝试将 splitmuxsink 动态连接到 tee 时,我录制的视频文件无效(至少 VLC 不会播放它们)。 (网络流继续正常工作)

我将我的代码简化为一个简单的版本(如下),我从一个 splimuxsink 开始,睡一会儿,然后添加第二个。尽管第一个 splitmuxsink 效果很好,但新的永远不会生成可用的视频。为了进行转换,我将播放管道切换为暂停,添加新元素(全部处于暂停状态)并将所有内容切换为播放。

按照gstream手册,我尝试了更复杂的切换程序;添加探针来阻止tee的新分支等,但结果相同。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <gst/gst.h>
#include <assert.h>

using namespace std;

int main()
{
    // Create a pipeline to write a file
    printf("starting\n");

    gst_init(NULL,NULL);

    // Create the pipeline to host the elements
    GstElement* pipeline = gst_pipeline_new("pipeline");
    assert(pipeline != nullptr);
    
    GstElement* camera = gst_element_factory_make("v4l2src","v4l2src");
    assert(camera != nullptr);
    g_object_set(G_OBJECT(camera),"device","/dev/video2",NULL);
    
    GstElement* caps = gst_element_factory_make("capsfilter","capsfilter");
    assert(caps != nullptr);
    g_object_set(G_OBJECT(caps),"caps",gst_caps_from_string("video/x-h264,width=640,height=480,framerate=30/1"),NULL);

    GstElement* tee = gst_element_factory_make("tee","tee");
    GstElement* queue1 = gst_element_factory_make("queue","queue1");
    GstElement* h264parse1 = gst_element_factory_make("h264parse","h264parse1");
    GstElement* splitmux1 = gst_element_factory_make("splitmuxsink","splitmux1");
    g_object_set(G_OBJECT(splitmux1),"location","file%03d.mp4","max-size-time",10000000000,NULL);
    assert(tee != nullptr && queue1 != nullptr && h264parse1 != nullptr && splitmux1 != nullptr);

    // Attach them all to the pipeline
    gst_bin_add_many(GST_BIN (pipeline),camera,caps,tee,queue1,h264parse1,splitmux1,NULL);

    // Link the pieces
    assert(true == gst_element_link_many(camera,NULL));
    GstPad* srcpad = gst_element_get_request_pad(tee,"src_%u");
    assert(srcpad != nullptr);
    GstPad* dstpad = gst_element_get_static_pad (queue1,"sink");
    assert(dstpad != nullptr);
    assert(GST_PAD_LINK_OK == gst_pad_link(srcpad,dstpad));
    assert(true == gst_element_link_many (queue1,NULL));

    assert(GST_STATE_CHANGE_ASYNC == gst_element_set_state (pipeline,GST_STATE_PLAYING));

    sleep(35);

    printf("Attach the splitmuxsink\n");
    // Now attach another sink
    GstElement* queue2 = gst_element_factory_make("queue","queue2");
    assert(nullptr != queue2);
    GstElement* h264parse2 = gst_element_factory_make("h264parse","h264parse2");
    assert(nullptr != h264parse2);
    GstElement* splitmux2 = gst_element_factory_make("splitmuxsink","splitmux2");
    assert(nullptr != splitmux2);
    g_object_set(G_OBJECT(splitmux2),"alt%03d.mp4",NULL);

    // Set all the states to paused before attaching
    assert(GST_STATE_CHANGE_ASYNC == gst_element_set_state (splitmux2,GST_STATE_PAUSED));
    assert(GST_STATE_CHANGE_SUCCESS == gst_element_set_state (h264parse2,GST_STATE_PAUSED));
    assert(GST_STATE_CHANGE_SUCCESS == gst_element_set_state (queue2,GST_STATE_PAUSED));
    assert(GST_STATE_CHANGE_NO_preroll == gst_element_set_state (pipeline,GST_STATE_PAUSED));

    gst_bin_add_many (GST_BIN (pipeline),queue2,h264parse2,splitmux2,NULL);
    assert(true == gst_element_link_many (queue2,NULL));
    GstPad* srcpad2 = gst_element_get_request_pad(tee,"src_%u");
    assert(nullptr != srcpad2);
    GstPad* dstpad2 = gst_element_get_static_pad (queue2,"sink");
    assert(nullptr != dstpad2);
    assert(GST_PAD_LINK_OK == gst_pad_link(srcpad2,dstpad2));

    assert(GST_STATE_CHANGE_ASYNC == gst_element_set_state (pipeline,GST_STATE_PLAYING));
    sleep(65);
    printf("all done\n");
 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。