我试图通过网络将用户的网络摄像头流到一个基于C的服务器上。我用过Janus网关。
我创建了一个小插件,它很大程度上是基于回声测试演示示例的:我的浏览器通过WebRTC技术连接到我的janus服务器,我让它流给用户的网络摄像头。
在服务器端,我有janus_incomming_rtp函数,它给我一个char *缓冲区和int长度。在检查时,阻止的数据缓冲区大约是MTU的长度:我的视频的每一帧都被发送到几个RTP数据包上。
我已经通过跟踪这个维基百科页面来检查头部,但是我不知道如何从UDP RTP数据包流中重建映像。理想情况下,我希望将流传递给openCV进行实时图像处理。
我听说过gstreamer,但我不明白它是什么,也不知道它如何帮助我;此外,我不知道openCV是否有内置的函数来“重建”图像?我不知道视频帧是以哪种格式编码的:PT (Payload Type)似乎是116,它被定义为“动态”,但我不知道它意味着什么。
有什么帮助吗?
发布于 2014-05-26 14:52:33
以下是处理SRTP数据包以解码它们的一些指导步骤。
SDP:
a=rtcp-mux,您将看到a=rtcp:50111 IN IP4 <address>中的端口和候选媒体端口是相同的。a=group:BUNDLE audio videoSRTP:
GStreamer:
发布于 2016-07-29 14:24:13
最后,我使用Janus和GStreamer (1.9)完成了这项工作,它遵循了这个帖子中其他人的建议,包括@nschoe ( OP)和@Benjamin Trent。我想,我应该包括我的代码,以使下一个人的生活更轻松,因为我经历了这么多的尝试和错误:
首先,构建/安装GStreamer及其所有需要的插件(在我的设置中,我需要确保GST_PLUGIN_SYSTEM_PATH环境变量中有两个插件目录)。现在,当您的Janus插件初始化( GStreamer回调)时初始化init():
gst_init(NULL, NULL);对于每个WebRTC会话,您需要保留一些GStreamer句柄,因此将以下内容添加到您的Janus会话结构中:
GstElement *pipeline, *appsrc, *multifilesink;当创建一个Janus会话(create_session()回调)时,为该会话设置GStreamer管道(在我的例子中,我需要降低帧速率,因此需要视频/capsrate;您可能不需要这些):
GstElement *conv, *vp8depay, *vp8dec, *videorate, *capsrate, *pngenc;
session->pipeline = gst_pipeline_new("pipeline");
session->appsrc = gst_element_factory_make("appsrc", "source");
vp8depay = gst_element_factory_make("rtpvp8depay", NULL);
vp8dec = gst_element_factory_make("vp8dec", NULL);
videorate = gst_element_factory_make("videorate", NULL);
capsrate = gst_element_factory_make("capsfilter", NULL);
conv = gst_element_factory_make("videoconvert", "conv");
pngenc = gst_element_factory_make("pngenc", NULL);
session->multifilesink = gst_element_factory_make("multifilesink", NULL);
GstCaps* capsRate = gst_caps_new_simple("video/x-raw", "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
g_object_set(capsrate, "caps", capsRate, NULL);
gst_caps_unref(capsRate);
GstCaps* caps = gst_caps_new_simple ("application/x-rtp",
"media", G_TYPE_STRING, "video",
"encoding-name", G_TYPE_STRING, "VP8-DRAFT-IETF-01",
"payload", G_TYPE_INT, 96,
"clock-rate", G_TYPE_INT, 90000,
NULL);
g_object_set(G_OBJECT (session->appsrc), "caps", caps, NULL);
gst_caps_unref(caps);
gst_bin_add_many(GST_BIN(session->pipeline), session->appsrc, vp8depay, vp8dec, conv, videorate, capsrate, pngenc, session->multifilesink, NULL);
gst_element_link_many(session->appsrc, vp8depay, vp8dec, conv, videorate, capsrate, pngenc, session->multifilesink, NULL);
// Setup appsrc
g_object_set(G_OBJECT (session->appsrc), "stream-type", 0, NULL);
g_object_set(G_OBJECT (session->appsrc), "format", GST_FORMAT_TIME, NULL);
g_object_set(G_OBJECT (session->appsrc), "is-live", TRUE, NULL);
g_object_set(G_OBJECT (session->appsrc), "do-timestamp", TRUE, NULL);
g_object_set(session->multifilesink, "location", "/blah/some/dir/output-%d.png", NULL);
gst_element_set_state(session->pipeline, GST_STATE_PLAYING);当传入的RTP数据包被Janus分解并准备读取(incoming_rtp()回调)时,将其输入到GStreamer管道中:
if(video && session->video_active) {
// Send to GStreamer
guchar* temp = NULL;
temp = (guchar*)malloc(len);
memcpy(temp, buf, len);
GstBuffer* buffer = gst_buffer_new_wrapped_full(0, temp, len, 0, len, temp, g_free);
gst_app_src_push_buffer(GST_APP_SRC(session->appsrc), buffer);
}最后,当Janus会话结束(destroy_session()回调)时,请确保释放GStreamer资源:
if(session->pipeline) {
gst_element_set_state(session->pipeline, GST_STATE_NULL);
gst_object_unref(session->pipeline);
session->pipeline = NULL;
}发布于 2014-05-29 09:27:48
对于WebRTC的流,我们也有同样的担忧。我所做的是将视频帧发送到WebSocket服务器,然后使用imdecode()对图像缓冲区进行解码。
我在这里有一个twistedcv的现场演示,也有github这里的twistedcv的源代码。但流媒体并不是实时播放的。
https://stackoverflow.com/questions/23864128
复制相似问题