2014-09-26 101 views
4

我从浏览器中使用的WebRTC到以下安装工作的服务器流式网络摄像头:使用Firefox和改进的回声测试HTML from janus gateway需要哪个gstreamer管道设置来处理chrome的rtp流?

  1. 我的网络摄像头流发送到服务器剑锋
  2. 所述的Janus服务器正在使用的改性EchoTest中插件,它简单地UDP流在janus_videorecv_incoming_rtp给定char *的buf()到端口5060上运行,只是用于测试目的(pretty much like this
  3. 以下gstreamer的命令行实际打开示出的流的窗口视频

GST_DEBUG=p*:5 gst-launch-1.0 -vvv udpsrc caps="application/x-rtp,media=video,clock-rate=90000,payload=96" port=5060 ! rtpvp8depay ! vp8dec ! autovideosink

在改性回波测试JavaScript我删除从SDP几行回答浏览器将接收如下所示:

//jsep.sdp = jsep.sdp.replace(/a=rtcp-mux[^\s]*\s*/g, ''); 
jsep.sdp = jsep.sdp.replace(/a=rtpmap[^\s]*\s*red[^\s]*\s*/g, ''); 
jsep.sdp = jsep.sdp.replace(/a=rtpmap[^\s]*\s*ulpfec[^\s]*\s*/g, ''); 
jsep.sdp = jsep.sdp.replace(/a=fmtp[^\r\n]*\r*\n*/g, ''); 
jsep.sdp = jsep.sdp.replace(/a=rtcp-fb[^\s]*\s*goog-remb[^\s]*\s*/g, ''); 
下面

,可以发现改性的Firefox SDP应答,其适用于上面gstreamer的命令 但在铬 的情况下,以相同的方式,修改的SDP应答不工作我想了解在gstreamer的帽调整有效载荷,但32,33,96,100,120没有工作

所以问题是:铬的情况下需要什么才能使其工作?

我也尝试在铬的情况下,加入在从詹纳斯videoroom.c冷杉/ PLI请求等作为suggested here

的gstreamer的输出是,这里的命令只是不断在最后一行等待:

0:00:00.025791492 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:219:gst_pipeline_init:<[email protected]> set bus <bus2> on pipeline 
Setting pipeline to PAUSED ... 
0:00:00.029798090 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:282:reset_start_time:<pipeline0> reset start_time to 0 
Pipeline is live and does not need PREROLL ... 
/GstPipeline:pipeline0/GstUDPSrc:udpsrc0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, payload=(int)96, encoding-name=(string)VP8-DRAFT-IETF-01 
Setting pipeline to PLAYING ... 
0:00:00.030045034 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:377:gst_pipeline_change_state:<pipeline0> selecting clock and base_time 
0:00:00.030053523 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:398:gst_pipeline_change_state:<pipeline0> Need to update start_time 
0:00:00.030058181 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:403:gst_pipeline_change_state:<pipeline0> Need to update clock. 
/GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0.GstPad:src: caps = video/x-vp8, framerate=(fraction)0/1 
/GstPipeline:pipeline0/GstVP8Dec:vp8dec0.GstPad:sink: caps = video/x-vp8, framerate=(fraction)0/1 
0:00:00.030111345 22279  0x1954b90 DEBUG    pipeline gstpipeline.c:443:gst_pipeline_change_state:<pipeline0> start_time=0:00:00.000000000, now=33:52:04.529345754, base_time 33:52:04.529345754 
/GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, payload=(int)96, encoding-name=(string)VP8-DRAFT-IETF-01 
New clock: GstSystemClock 

铬答案:

v=0 
o=- 8913399741269897639 2 IN IP4 127.0.0.1 
s=- 
t=0 0 
a=group:BUNDLE audio video 
a=msid-semantic: WMS janus 
m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126 
a=mid:audio 
c=IN IP4 192.168.0.1 
a=sendrecv 
a=rtcp-mux 
a=ice-ufrag:l0n9 
a=ice-pwd:r1elT1Ew8lP3TNlzwAHUsC 
a=ice-options:trickle 
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 
a=setup:active 
a=connection:new 
a=rtpmap:111 opus/48000/2 
a=rtpmap:103 ISAC/16000 
a=rtpmap:104 ISAC/32000 
a=rtpmap:0 PCMU/8000 
a=rtpmap:8 PCMA/8000 
a=rtpmap:106 CN/32000 
a=rtpmap:105 CN/16000 
a=rtpmap:13 CN/8000 
a=rtpmap:126 telephone-event/8000 
a=maxptime:60 
a=ssrc:600390024 cname:janusaudio 
a=ssrc:600390024 msid:janus janusa0 
a=ssrc:600390024 mslabel:janus 
a=ssrc:600390024 label:janusa0 
a=candidate:1 1 udp 2013266431 192.168.0.1 45728 typ host 
m=video 1 RTP/SAVPF 100 116 117 96 
a=mid:video 
c=IN IP4 192.168.0.1 
a=sendrecv 
a=rtcp-mux 
a=ice-ufrag:l0n9 
a=ice-pwd:r1elT1Ew8lP3TNlzwAHUsC 
a=ice-options:trickle 
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 
a=setup:active 
a=connection:new 
a=rtpmap:100 VP8/90000 
a=rtcp-fb:100 ccm fir 
a=rtcp-fb:100 nack 
a=rtcp-fb:100 nack pli 
a=rtpmap:96 rtx/90000 
a=ssrc-group:FID 3188003624 3419969288 
a=ssrc:677441062 cname:janusvideo 
a=ssrc:677441062 msid:janus janusv0 
a=ssrc:677441062 mslabel:janus 
a=ssrc:677441062 label:janusv0 
a=candidate:1 1 udp 2013266431 192.168.0.1 45728 typ host 
m=application 0 DTLS/SCTP 0 
c=IN IP4 192.168.0.1 

firefox的答案:

v=0 
o=Mozilla-SIPUA-32.0.3 11426 0 IN IP4 127.0.0.1 
s=SIP Call 
t=0 0 
a=group:BUNDLE audio video 
a=msid-semantic: WMS janus 
m=audio 1 RTP/SAVPF 109 0 8 101 
a=mid:audio 
c=IN IP4 192.168.0.1 
a=sendrecv 
a=rtcp-mux 
a=ice-ufrag:BRBU 
a=ice-pwd:2W4fGNr//HejhiC4UIabW6 
a=ice-options:trickle 
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 
a=setup:active 
a=connection:new 
a=rtpmap:109 opus/48000/2 
a=ptime:20 
a=rtpmap:0 PCMU/8000 
a=rtpmap:8 PCMA/8000 
a=rtpmap:101 telephone-event/8000 
a=fmtp:101 0-15 
a=ssrc:3725983979 cname:janusaudio 
a=ssrc:3725983979 msid:janus janusa0 
a=ssrc:3725983979 mslabel:janus 
a=ssrc:3725983979 label:janusa0 
a=candidate:1 1 udp 2013266431 192.168.0.1 56574 typ host 
m=video 1 RTP/SAVPF 120 
a=mid:video 
c=IN IP4 192.168.0.1 
a=sendrecv 
a=rtcp-mux 
a=ice-ufrag:jZ5b 
a=ice-pwd:dQQej9UIpPl5zuXBQNg3Nz 
a=ice-options:trickle 
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 
a=setup:active 
a=connection:new 
a=rtpmap:120 VP8/90000 
a=rtcp-fb:120 nack 
a=rtcp-fb:120 nack pli 
a=rtcp-fb:120 ccm fir 
a=ssrc:1425382999 cname:janusvideo 
a=ssrc:1425382999 msid:janus janusv0 
a=ssrc:1425382999 mslabel:janus 
a=ssrc:1425382999 label:janusv0 
a=candidate:2 1 udp 2013266431 192.168.0.1 39063 typ host 
m=application 0 DTLS/SCTP 0 
c=IN IP4 192.168.0.1 

UPDATE: 我修改了SDP-回答这样既Firefox和Chrome获得近,除了我刚刚从SDP要约复制“O =”和“s =”行相同 v=0 o=- 7589782217972865757 2 IN IP4 127.0.0.1 s=- t=0 0 a=group:BUNDLE audio video a=msid-semantic: WMS janus m=audio 1 RTP/SAVPF 111 a=mid:audio c=IN IP4 192.168.0.1 a=sendrecv a=rtcp-mux a=ice-ufrag:g0kZ a=ice-pwd:d5oEody1jqIzDYUdf1fg6t a=ice-options:trickle a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 a=setup:active a=connection:new a=rtpmap:111 opus/48000/2 a=ssrc:1038736511 cname:janusaudio a=ssrc:1038736511 msid:janus janusa0 a=ssrc:1038736511 mslabel:janus a=ssrc:1038736511 label:janusa0 a=candidate:1 1 udp 2013266431 192.168.0.1 51232 typ host m=video 1 RTP/SAVPF 100 a=mid:video c=IN IP4 192.168.0.1 a=sendrecv a=rtcp-mux a=ice-ufrag:g0kZ a=ice-pwd:d5oEody1jqIzDYUdf1fg6t a=ice-options:trickle a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44 a=setup:active a=connection:new a=rtpmap:100 VP8/90000 a=rtcp-fb:100 ccm fir a=rtcp-fb:100 nack a=rtcp-fb:100 nack pli a=rtcp-fb:100 goog-remb a=ssrc:2455978689 cname:janusvideo a=ssrc:2455978689 msid:janus janusv0 a=ssrc:2455978689 mslabel:janus a=ssrc:2455978689 label:janusv0 a=candidate:1 1 udp 2013266431 192.168.0.1 51232 typ host m=application 0 DTLS/SCTP 0 c=IN IP4 192.168.0.1

+0

在chrome中,并非所有的映射都被删除。你为什么要删除'a = rtcp-fb:100 goog-remb'?纠正视频媒体行上显示的rtp有效载荷,并删除未被占用的'rtx' rtp映射。这应该会让你更进一步。你确定chrome甚至会向你发送任何媒体吗?我猜测它在答案上很怪,并且不发送任何东西。如果它发送媒体,你可以打破rtp头,并查看有效载荷,以确保它是VP8 – 2014-09-26 18:15:03

+0

我实际上删除了goog-remb,因为我试图逐行删除行,也许有一些工作。实际上chrome正在发送数据,我的janus插件也正确转发,正如我通过wireshark所看到的。关于“视频媒体行中正确的rtp有效载荷”,你的意思是我应该设置m = video 1 RTP/SAVPF 120,就像在Firefox中一样?通过分解rtp头文件究竟是什么意思?你会怎么做?感谢您的时间 – 2014-09-26 18:44:38

+0

该行应该是'm = video 1 RTP/SAVPF 100'来表示只有一个映射(对于VP8)。那么只有VP8映射应该存在。 [一些webrtc sdp指针](http://webrtchacks.com/sdp-anatomy/)。您可以将缓冲区转换为rtp数据包,然后访问该类型。 'rtp_header * packetheader =(rtp_header *)buf; \t \t packetheader-> type; //有效载荷' – 2014-09-26 19:00:18

回答

0

我已经更新了包含the bidirectional streaming plugin的fork,向您展示了一个可用的示例(我已在debian jessie上进行了测试)。

这里是我的三分球给你的插件改变

  1. 确保您的GStreamer管道被设置为接收之前,您从镀铬请求关键帧
  2. 请求你的关键帧时WebRTC媒体已准备就绪(见janus_bidirectional_streaming_setup_media功能了解详情)
  3. 请勿使用rtpbin gstreamer元素处理传入流。由于某些原因,它设置上限的方式并不真正起作用,管道将崩溃。如果你得到的RTP包,并能够把它们发送到端口,那么下面的管道的工作没有问题:gst-launch-1.0 udpsrc port=<your listener> caps="application/x-rtp, clock-rate=90000, payload=100" ! rtpvp8depay ! vp8dec ! autovideosink sync=false async=false

从理论上讲,直接推缓冲区到appsrc内的插件应该正常工作。

1

WebRTC使用DTLS-SRTP进行强制加密(Chrome仍支持非标准和明确的MUST-NOT-IMPLMENT SDES键控)。

你不能只将一个RTP流提供给webrtc;它必须是一个以初始DTLS连接为关键字的DTLS-SRTP流。

人们已经将node.js挂钩到webrtc浏览器,所以我想象你需要的所有机器都在那里。

+0

我不确定我是否理解你的权利。你的意思是“不能只喂一个rtp流到webrtc”的情况下,我发送rtp从服务器到浏览器?如果是的话,那不是我想要做的。我从webrtc(浏览器)发送rtp到服务器,并尝试使用gstreamer向服务器显示流,主要是为了调试/测试目的。关于dtls,尽管我不知道所有的细节,但我读到janus(服务器)处理这个 – 2014-09-27 07:11:04

+0

数据包在到达gstreamer管道时被解密。 Janus负责处理每个数据包的解密和解复用。 – 2014-09-27 16:23:21

0

Kurento媒体服务器(KMS)是完全写在GStreamer之上的WebRTC媒体服务器。 KMS提供了一个WebRtcEndpoint,用于实现向Web浏览器发送/接收WebRTC流所需的所有协议和算法。 KMS根据媒体元素和媒体管道进行公开和API,这可以转化为GStreamer媒体管道。一般来说,您在GStreamer上的所有功能都可以在KMS中使用。您可以在http://www.kurento.org中查看KMS。

声明:我是Kurento开发团队的成员。

+0

什么流水线专门与来自Chrome的WebRTC流的解密,解复用RTP流配合使用?用户已经在使用janus,所以只是连接另一种技术并不能真正回答问题。 – 2014-09-27 16:24:44