linux - 连接到正在比赛的发球台
问题描述
我正在使用 gstreamer 将视频从相机流式传输到 HLS 接收器,并将该视频作为 MP4 记录到文件系统中。我使用 tee 将视频分成两条路径。如果我将它们全部连接起来并将状态切换为“播放”,我编写了一些代码并让它工作。但是当我开始流式传输并尝试将 splitmuxsink 动态连接到 tee 时,我录制的视频文件无效(至少 VLC 不会播放它们)。(网络流继续正常工作)
我已经将我的代码简化为一个简单的版本(如下),我从一个 splimuxsink 开始,睡一会儿,然后添加第二个。虽然第一个 splitmuxsink 效果很好,但新的从未生成可用的视频。为了进行过渡,我将播放管道切换为暂停,添加新元素(全部处于暂停状态)并将所有内容切换为播放。
按照gstream手册,我尝试了更复杂的切换程序;添加一个探针来阻止三通的新分支等,但结果是一样的。
#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, caps, tee, 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, h264parse1, splitmux1, 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),
"location", "alt%03d.mp4",
"max-size-time", 10000000000,
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, h264parse2, splitmux2, 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");
}
解决方案
推荐阅读
- java - 仅使用 Jackson 序列化私有属性
- java - 使用 Glide 控制 GIF 动画
- javascript - 在 Javascript 问题中使用 XMLHttpRequest()
- javascript - Vue cli3 块特定文件
- java - 从字符串中删除包含特定单词或部分单词的单词
- string - 根据字符串验证arraylist的内容
- rust - 有没有办法在 Rust 中定义多参数特征?
- windows - Windows 批处理:使用 PuTTY 和 sed 在特定位置的远程 Linux 文件中插入多行
- python - 使用 numpy 矢量化对大量对象状态进行操作的良好模式是什么?
- visual-studio-code - 有没有办法在视图面板中禁用命令发射按钮并在不满足条件时将其变灰?