Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to add remote ice candidate in webrtc

I am trying to establish a p2p audio/video connection b/w 2 peers. Peer P1 sends an offer to peer P2. On getting offer, P2 does-

{
    pc = new RTCPeerConnection(ice);
    pc.setRemoteDescription(new RTCSessionDescription(msg.offer),
            onSetRemoteDescriptionSuccess, onSetSessionDescriptionError);                    

    function onSetRemoteDescriptionSuccess() {
        console.log('onSetRemoteDescriptionSuccess called');                                 
    }                                                                                        

    function onSetSessionDescriptionError() {
        console.log('onSetSessionDescriptionError called');                                  
    }                                                                                        

    pc.onicecandidate = function(evt) {                                                      
        if (evt.candidate) {
            console.log('got local icecandidate', evt.candidate);                            
            send_ice_candicate(evt.candidate.sdpMLineIndex,                                  
                      evt.candidate.sdpMid,
                      evt.candidate.candidate                                                
                      );                                                                     
        }                                                                                    
    }                                                                                        

    pc.onaddstream = function (evt) {
        var remote_video = document.getElementById('remote_video');                          
        remote_video.src = window.URL.createObjectURL(evt.stream);                           
    }                                                                                        

    navigator.getUserMedia({ "audio": true, "video": true },                                 
            gotStream, logError);
} 

function gotStream(stream) {                                                                     
    pc.addStream(stream);                                                                        

    var local_video = document.getElementById('local_video');                                    
    local_video.src = window.URL.createObjectURL(stream);                                        

    pc.createAnswer(function(answer) {
        pc.setLocalDescription(answer);
        console.log('creating answer', answer.sdp)                                           
        signalingChannel.send(answer.sdp);                                                 
        });
    got_ice_candidate(remote_ice_candidate);                                                     
}                                     

remote_ice_candidate is something which was received before offer and hence is buffered and I am trying to add after the answer is ready and other pre-requisites are done.

But still I am getting error while trying to add remote ice candidate.

Peer connection object on P2 looks like-

RTCPeerConnection {ondatachannel: null, oniceconnectionstatechange: null, onremovestream: null, onaddstream: function, onsignalingstatechange: null…}
iceConnectionState: "new"
iceGatheringState: "gathering"
localDescription: RTCSessionDescription
sdp: "v=0
↵o=- 5043546633484176483 2 IN IP4 127.0.0.1
↵s=-
↵t=0 0
↵a=group:BUNDLE audio video
↵a=msid-semantic: WMS irIWtGZ87WFi8P6XH94I85sUsKYcu775glZk
↵m=audio 10990 RTP/SAVPF 111 103 104 0 8 106 105 13 126
↵c=IN IP4 122.171.69.180
↵a=rtcp:1 IN IP4 0.0.0.0
↵a=candidate:3022624816 1 udp 2122260223 192.168.1.4 50063 typ host generation 0
↵a=candidate:4205470912 1 tcp 1518280447 192.168.1.4 0 typ host generation 0
↵a=candidate:494278629 1 udp 1686052607 122.171.69.180 10990 typ srflx raddr 192.168.1.4 rport 50063 generation 0
↵a=ice-ufrag:1ZCyumc5I0T8mbFJ
↵a=ice-pwd:+JUisFsiKa8ezPXDIuzu99tv
↵a=fingerprint:sha-256 BE:16:E6:7B:C8:18:E6:B9:50:D9:31:F3:24:85:3B:63:26:BA:EA:6B:5D:F4:4E:0E:29:47:16:C0:1D:9D:B7:F3
↵a=setup:active
↵a=mid:audio
↵a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
↵a=sendrecv
↵a=rtcp-mux
↵a=rtpmap:111 opus/48000/2
↵a=fmtp:111 minptime=10
↵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:2173896727 cname:PZV2reyyZuw6KufJ
↵a=ssrc:2173896727 msid:irIWtGZ87WFi8P6XH94I85sUsKYcu775glZk fb1b496d-ffa9-43cd-940a-7c68df86d3b3
↵a=ssrc:2173896727 mslabel:irIWtGZ87WFi8P6XH94I85sUsKYcu775glZk
↵a=ssrc:2173896727 label:fb1b496d-ffa9-43cd-940a-7c68df86d3b3
↵m=video 10990 RTP/SAVPF 100 116 117
↵c=IN IP4 122.171.69.180
↵a=rtcp:1 IN IP4 0.0.0.0
↵a=candidate:3022624816 1 udp 2122260223 192.168.1.4 50063 typ host generation 0
↵a=candidate:4205470912 1 tcp 1518280447 192.168.1.4 0 typ host generation 0
↵a=candidate:494278629 1 udp 1686052607 122.171.69.180 10990 typ srflx raddr 192.168.1.4 rport 50063 generation 0
↵a=ice-ufrag:1ZCyumc5I0T8mbFJ
↵a=ice-pwd:+JUisFsiKa8ezPXDIuzu99tv
↵a=fingerprint:sha-256 BE:16:E6:7B:C8:18:E6:B9:50:D9:31:F3:24:85:3B:63:26:BA:EA:6B:5D:F4:4E:0E:29:47:16:C0:1D:9D:B7:F3
↵a=setup:active
↵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=sendrecv
↵a=rtcp-mux
↵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=rtpmap:116 red/90000
↵a=rtpmap:117 ulpfec/90000
↵a=ssrc:2118221653 cname:PZV2reyyZuw6KufJ
↵a=ssrc:2118221653 msid:irIWtGZ87WFi8P6XH94I85sUsKYcu775glZk a735b317-1752-40fa-96df-511c0febb55e
↵a=ssrc:2118221653 mslabel:irIWtGZ87WFi8P6XH94I85sUsKYcu775glZk
↵a=ssrc:2118221653 label:a735b317-1752-40fa-96df-511c0febb55e
↵"
type: "answer"
__proto__: RTCSessionDescription
onaddstream: function (evt) {
arguments: null
caller: null
length: 1
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
ondatachannel: null
onicecandidate: function (evt) {
oniceconnectionstatechange: null
onnegotiationneeded: null
onremovestream: null
onsignalingstatechange: null
remoteDescription: RTCSessionDescription
sdp: "v=0
↵o=- 8847796014807563532 2 IN IP4 127.0.0.1
↵s=-
↵t=0 0
↵a=group:BUNDLE audio video
↵a=msid-semantic: WMS na7tuNpnYZpmg56IJULDdF8oMUG8V5ndTjkK
↵m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126
↵c=IN IP4 0.0.0.0
↵a=rtcp:1 IN IP4 0.0.0.0
↵a=ice-ufrag:mfL29tarMKRBN9F/
↵a=ice-pwd:/my1DZo1Yjne4BrcQGKN1o3I
↵a=ice-options:google-ice
↵a=fingerprint:sha-256 BE:16:E6:7B:C8:18:E6:B9:50:D9:31:F3:24:85:3B:63:26:BA:EA:6B:5D:F4:4E:0E:29:47:16:C0:1D:9D:B7:F3
↵a=setup:actpass
↵a=mid:audio
↵a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
↵a=sendrecv
↵a=rtcp-mux
↵a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:ggGTdSmkygu0aVidv2M6kO25w5DX/OknOXFnRBYK
↵a=rtpmap:111 opus/48000/2
↵a=fmtp:111 minptime=10
↵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:702054304 cname:++QJWJ3eyXhSOSgH
↵a=ssrc:702054304 msid:na7tuNpnYZpmg56IJULDdF8oMUG8V5ndTjkK 054d6450-034f-48ca-85dc-3a843c7f7554
↵a=ssrc:702054304 mslabel:na7tuNpnYZpmg56IJULDdF8oMUG8V5ndTjkK
↵a=ssrc:702054304 label:054d6450-034f-48ca-85dc-3a843c7f7554
↵m=video 1 RTP/SAVPF 100 116 117
↵c=IN IP4 0.0.0.0
↵a=rtcp:1 IN IP4 0.0.0.0
↵a=ice-ufrag:mfL29tarMKRBN9F/
↵a=ice-pwd:/my1DZo1Yjne4BrcQGKN1o3I
↵a=ice-options:google-ice
↵a=fingerprint:sha-256 BE:16:E6:7B:C8:18:E6:B9:50:D9:31:F3:24:85:3B:63:26:BA:EA:6B:5D:F4:4E:0E:29:47:16:C0:1D:9D:B7:F3
↵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=sendrecv
↵a=rtcp-mux
↵a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:ggGTdSmkygu0aVidv2M6kO25w5DX/OknOXFnRBYK
↵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=rtpmap:116 red/90000
↵a=rtpmap:117 ulpfec/90000
↵a=ssrc:846853801 cname:++QJWJ3eyXhSOSgH
↵a=ssrc:846853801 msid:na7tuNpnYZpmg56IJULDdF8oMUG8V5ndTjkK c0dde33c-f422-4774-9f7b-65cec136e107
↵a=ssrc:846853801 mslabel:na7tuNpnYZpmg56IJULDdF8oMUG8V5ndTjkK
↵a=ssrc:846853801 label:c0dde33c-f422-4774-9f7b-65cec136e107
↵"
type: "offer"
__proto__: RTCSessionDescription
signalingState: "stable"
__proto__: RTCPeerConnection    

The error that I get is

Failed to add Ice Candidate: Error processing ICE candidate      
like image 280
CodeQ Avatar asked Apr 27 '14 15:04

CodeQ


People also ask

What is WebRTC ICE candidate?

The RTCIceCandidate interface—part of the WebRTC API—represents a candidate Interactive Connectivity Establishment (ICE) configuration which may be used to establish an RTCPeerConnection . An ICE candidate describes the protocols and routing needed for WebRTC to be able to communicate with a remote device.

What is trickle ICE in WebRTC?

Trickle ICE is an optimization of the ICE specification for NAT traversal. The main bottleneck in ICE is the time it takes to start initiating connectivity checks – it requires collecting all ICE candidates in advance, which in turn means interacting with external servers (STUN and TURN servers).


1 Answers

This is a reply to comments asking how to ensure ice candidates are only added after the remote description is set:

let candidates = [];
let remoteDescriptionSet = false;

function wsMessage(ev) {
  if (!ev || !ev.data) return;
  const json = JSON.parse(ev.data);
  if (!json) return;
  if (json.type === 'answer') {
    pc.setRemoteDescription(json)
    .then(() => {
      remoteDescriptionSet = true;
      console.log('remote description set');
      return Promise.all(candidates.map(c => pc.addIceCandidate(c)));
    })
    .then(() => {
      console.log('all stored candidates added');
      candidates.length = 0;
    })
    .catch(err => console.error(err));
  }
  else if (json.type === 'ice') {
    if (remoteDescriptionSet) {
      pc.addIceCandidate(json.ice)
      .then(() => console.log(`adding remote ice candidate: ${json.ice.candidate}`))
      .catch(err => console.error(err));
    }
    else {
      candidates.push(json.ice);
      console.log(`storing remote ice candidate: ${json.ice.candidate}`);
    }
  }
}
like image 153
SCG82 Avatar answered Oct 21 '22 05:10

SCG82