通过WebRTC

时间:2016-10-27 19:10:08

标签: webrtc rtsp kurento

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

我遵循类似的设置https://github.com/lulop-k/kurento-rtsp2webrtc,除了我创建了一个带有PlayerEndpoint的管道,其中相机流URI和WebRTCEndpoint连接到它,如下所示。

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);
          });
        });
      });
    });
  });
}

我在云中使用了一个Web套接字来发出sdpOffer,sdpAnswer,iceCandidate消息的信号。

在客户端,我有使用WebRTC Peer的javascript实现,如下所示。

var ws = new WebSocket(ws.url);
var webRtcPeer;
ws.onmessage = function(message) {
  var parsedMessage = JSON.parse(message.data);

  switch (parsedMessage.id) {
    case 'iceCandidate':
      webRtcPeer.addIceCandidate(parsedMessage.candidate)
      break;
    case 'sdpAnswer':
      webRtcPeer.processAnswer(parsedMessage.sdpAnswer);
      break;
    default:
      onError('Unrecognized message', parsedMessage);
  }
}

window.addEventListener('load', function(){
  var videoOutput = document.getElementById('videoOutput');
  var address = camera_rtsp_stream_url;
  var pipeline;

  function start() {
    var options = {
      remoteVideo : videoOutput,
      configuration: {
        iceServers:[
         { "url": turn_url,
           "username": uname,
           "credential": pass
         }
       ]
      }
    };

    webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options,
      function(error){
      webRtcPeer.generateOffer(onOffer);
      setIceCandidateCallbacks();
    });
  }

  function onOffer(error, sdpOffer){
    var message = {
      id : 'sdpOffer',
      name: 'peer',
      cam_url: address,
      sdpOffer : sdpOffer
    };
    sendMessage(message);
  }

});

function sendMessage(message) {
  var jsonMessage = JSON.stringify(message);
  ws.send(jsonMessage);
}

function setIceCandidateCallbacks(){
  webRtcPeer.on('icecandidate', function(candidate){
    candidate = kurentoClient.register.complexTypes.IceCandidate(candidate);

    var message = {
      id : 'iceCandidate',
      name: 'peer',
      iceCandidate : candidate
    };
    sendMessage(message);

  });

}

页面中的Feed仍无效。但是,git repo中的示例非常完美。有什么我想念的东西。

提前致谢。

编辑:

这是我的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

0 个答案:

没有答案