通过Kurento媒体服务器通过WebRTC从IP摄像机传输RTSP流

通过Kurento媒体服务器通过WebRTC从IP摄像机传输RTSP流,webrtc,rtsp,kurento,Webrtc,Rtsp,Kurento,我必须创建一个WebRTC解决方案,在这个解决方案中,我在一个专用网络中有多个IP摄像头,并且必须将提要流式传输到网络外的移动应用程序。我正在使用Kurento Media Server帮助我从相机的RTSP流生成WebRTC流。我也在专用网络中安装了KMS(Kurento Media Server) 我遵循了与的类似设置,只是创建了一个管道,其中包含一个带有摄影机流URI的PlayerEndpoint和一个连接到它的WebRTC端点,如下所示 function playCam(message)

我必须创建一个WebRTC解决方案,在这个解决方案中,我在一个专用网络中有多个IP摄像头,并且必须将提要流式传输到网络外的移动应用程序。我正在使用Kurento Media Server帮助我从相机的RTSP流生成WebRTC流。我也在专用网络中安装了KMS(Kurento Media Server)

我遵循了与的类似设置,只是创建了一个管道,其中包含一个带有摄影机流URI的PlayerEndpoint和一个连接到它的WebRTC端点,如下所示

function playCam(message){
  console.log("Message:" + JSON.stringify(message));
  var cam_url = message.cam_url;
  var sdpOffer = message.sdpOffer;
  getKurentoClient(function(error, kurentoClient) {

  console.log("Kurento client created.");
  kurentoClient.create('MediaPipeline', function(error, pipeline) {
  if (error) {
    console.log("Error: Creating Media Pipeline failed.");
    stop(pipeline);
    return;
  }

  console.log("Pipeline created.");
  pipeline.create("PlayerEndpoint", {uri: cam_url}, function(error, player){
      if(error) {
          console.log("Error: Creating PlayerEndpoint failed.");
          stop(pipeline);
          return;
        }

        console.log("PlayerEndpoint created.");
        pipeline.create("WebRtcEndpoint", function(error, webRtcEndpoint){

        remoteWebRtcEndpoint = webRtcEndpoint;
            console.log("WebRtcEndpoint created.");
            webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer){

                      sendSdpAnswer(sdpAnswer);

          for(var i = 0; i < remoteCandidates.length; i++){
            addIceRemoteCandidate(remoteCandidates[i]);
          }

                      webRtcEndpoint.gatherCandidates(function(error) {
                          console.log("Gathering Ice candidates created.");
                    });
                });

                player.connect(webRtcEndpoint, function(error){
                    console.log("PlayerEndpoint-->WebRtcEndpoint connection established");

                    player.play(function(error){
                        console.log("Player playing ...");
                    });
                });

        webRtcEndpoint.on('OnIceCandidate', function(event) {
            console.log(JSON.stringify(event));
            var candidate = kurento.getComplexType('IceCandidate')(event.candidate);
            sendIceCandidate(candidate);
          });
        });
      });
    });
  });
}
页面中的提要仍然不起作用。然而,git回购协议中的示例非常有效。有什么我不知道的吗

提前谢谢

编辑:

这是我的SDP报价

v=0
o=- 62767501284085133 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:AoAe
a=ice-pwd:tp+DQSO/OTvBaDZYQOmb5Yxe
a=fingerprint:sha-256     14:03:6A:CB:9D:86:B5:57:09:30:97:D8:0A:0E:59:A2:0F:8D:5F:24:46:3E:14:C7:D3:23:B2:11:39:4C:61:33
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=recvonly
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
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
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:AoAe
a=ice-pwd:tp+DQSO/OTvBaDZYQOmb5Yxe
a=fingerprint:sha-256 14:03:6A:CB:9D:86:B5:57:09:30:97:D8:0A:0E:59:A2:0F:8D:5F:24:46:3E:14:C7:D3:23:B2:11:39:4C:61:33
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=recvonly
a=rtcp-mux
a=rtcp-rsize
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=rtcp-fb:100 transport-cc
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:116 red/90000
a=rtpmap:117 ulpfec/90000
a=rtpmap:96 rtx/90000
a=fmtp:96 apt=100
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=101
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=107
a=rtpmap:98 rtx/90000
a=fmtp:98 apt=116
SDP答案如下所示:

v=0
o=- 3687061549 3687061549 IN IP4 0.0.0.0
s=Kurento Media Server
c=IN IP4 0.0.0.0
t=0 0
a=msid-semantic: WMS
a=group:BUNDLE audio video
m=audio 1 UDP/TLS/RTP/SAVPF 111 0
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:audio
a=rtcp:9 IN IP4 0.0.0.0
a=rtpmap:111 opus/48000/2
a=rtpmap:0 PCMU/8000
a=setup:active
a=sendonly
a=rtcp-mux
a=fmtp:111 minptime=10;useinbandfec=1
a=ssrc:174718429 cname:user1410268339@host-e518075a
a=ice-ufrag:Y1e8
a=ice-pwd:rLobIsorf9OWA8VkEvGbJN
a=fingerprint:sha-256 EF:8B:94:E4:CF:2A:82:BD:2D:07:F6:35:B8:2A:4C:4A:7F:A5:8D:FE:06:5F:38:6C:E7:F8:10:07:3C:11:E1:28
m=video 1 UDP/TLS/RTP/SAVPF 100
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:video
a=rtcp:9 IN IP4 0.0.0.0
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=setup:active
a=sendonly
a=rtcp-mux
a=ssrc:3344771 cname:user1410268339@host-e518075a
a=ice-ufrag:Y1e8
a=ice-pwd:rLobIsorf9OWA8VkEvGbJN
a=fingerprint:sha-256 EF:8B:94:E4:CF:2A:82:BD:2D:07:F6:35:B8:2A:4C:4A:7F:A5:8D:FE:06:5F:38:6C:E7:F8:10:07:3C:11:E1:28

您在日志中看到的任何可能有助于他人帮助您的错误?您需要检查服务器和客户端中的日志。可能播放机无法访问RTSP提要。您所能做的最好的事情就是搜索您的代码与原始代码之间的差异。谢谢,@igracia。不过我有一个疑问。我正在WebRTCPeer上生成sdp报价。但是,我没有在连接到PlayerEndPoint的WebRTC端点上生成sdp提供。我只是在WebRTC端点处处理来自WebRTCPeer的sdp提供,并将sdp应答发送回WebRTCPeer。我是否也应该在WebRTCEndpoint上创建sdp提供并通过?@igracia发送,我可以在WebRTCPeer位于本地网络时获取要渲染的流。然而,当我切换到NAT后面的另一个网络时,它确实起作用。声明的iceConnectionState变为失败状态。SDP报价/答案和ICE候选人可以互换。我在SDP报价/答案中找不到候选人信息。需要吗?我做错了吗?您很可能需要在KMS配置中添加一个STUN服务器。查看更多关于如何做到这一点的信息。@LukeKroon在我的github回购协议中有三个项目,它很简陋,但很管用。
v=0
o=- 3687061549 3687061549 IN IP4 0.0.0.0
s=Kurento Media Server
c=IN IP4 0.0.0.0
t=0 0
a=msid-semantic: WMS
a=group:BUNDLE audio video
m=audio 1 UDP/TLS/RTP/SAVPF 111 0
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:audio
a=rtcp:9 IN IP4 0.0.0.0
a=rtpmap:111 opus/48000/2
a=rtpmap:0 PCMU/8000
a=setup:active
a=sendonly
a=rtcp-mux
a=fmtp:111 minptime=10;useinbandfec=1
a=ssrc:174718429 cname:user1410268339@host-e518075a
a=ice-ufrag:Y1e8
a=ice-pwd:rLobIsorf9OWA8VkEvGbJN
a=fingerprint:sha-256 EF:8B:94:E4:CF:2A:82:BD:2D:07:F6:35:B8:2A:4C:4A:7F:A5:8D:FE:06:5F:38:6C:E7:F8:10:07:3C:11:E1:28
m=video 1 UDP/TLS/RTP/SAVPF 100
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:video
a=rtcp:9 IN IP4 0.0.0.0
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=setup:active
a=sendonly
a=rtcp-mux
a=ssrc:3344771 cname:user1410268339@host-e518075a
a=ice-ufrag:Y1e8
a=ice-pwd:rLobIsorf9OWA8VkEvGbJN
a=fingerprint:sha-256 EF:8B:94:E4:CF:2A:82:BD:2D:07:F6:35:B8:2A:4C:4A:7F:A5:8D:FE:06:5F:38:6C:E7:F8:10:07:3C:11:E1:28