WebRTC on Edge gives "Timeout for addRemoteCandidate. Consider sending an end-of-candidates notification"

468 views Asked by At

NOTE: Check most recent EDIT please

I get this warning on edge:

Timeout for addRemoteCandidate. Consider sending an end-of-candidates notification

I do not understand how to fix this. I use an adapter.js and I found a thread where people talk about the issue. But the fix does not work.

I tried to add pc.addIceCandidate(null), but it does nothing.


On chrome it works, ICE state goes from checking to connected really fast.

On edge the ICE state hangs on checking and after a few seconds goes to new, but it should not be new.

EDIT:

Adding pc.addIceCandidate(null); gives me 0: InvalidStateError. The state before I call pc.addIceCandidate(null); is new.

I also tried using pc.addIceCandidate({candidate:''});, but it does nothing.

Here are the relevant parts of code, where I try to add the fix:

function handleIceCandidate(event) {
  console.log('icecandidate event: ', event);
  if (event.candidate) {
    sendMessage([{
      type: 'candidate',
      label: event.candidate.sdpMLineIndex,
      id: event.candidate.sdpMid,
      candidate: event.candidate.candidate
    }, room]);
  } else {
    console.log("state in End of candidates: " + pc.iceConnectionState);
    if (window.navigator.userAgent.indexOf("Edge") > -1 && pc.iceConnectionState == "new") {
      //pc.addIceCandidate(null);
      pc.addIceCandidate({candidate:''});
    }
  }
}

And in the socket call:

socket.on('message', function(message) {


  if (message.type === 'candidate' && isStarted) {

    var candidate = new RTCIceCandidate({
      sdpMLineIndex: message.label,
      candidate: message.candidate
    });
    pc.addIceCandidate(candidate);
    console.log("state in socket: " + pc.iceConnectionState);
    if (window.navigator.userAgent.indexOf("Edge") > -1 && pc.iceConnectionState == "new") {
      //pc.addIceCandidate(null);
      pc.addIceCandidate({candidate:''});
    }
  } 
});

EDIT:

It looks like there is an issue in adapter.js:

if (!pc._remoteDescription) {
        return reject(makeError('InvalidStateError',
            'Can not add ICE candidate without a remote description'));
      } else if (!candidate || candidate.candidate === '') { 
        for (var j = 0; j < pc.transceivers.length; j++) {
          if (pc.transceivers[j].rejected) {
            continue;
          }
          pc.transceivers[j].iceTransport.addRemoteCandidate({});
          sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);
          sections[j] += 'a=end-of-candidates\r\n';
          console.log("tries to send end of candidates (I added this)");
          pc._remoteDescription.sdp =
              SDPUtils.getDescription(pc._remoteDescription.sdp) +
              sections.join('');
          if (pc.usingBundle) {
            break;
          }
        }
      }

It should go into the else if, but it never does it. I tried to console.log(candidate.candidate) and it shows me undefined. I tried adding || candidate.candidate == undefined to the else if conditions, but still it wont go into the else if.

Actually it feels already wrong to modify the adapter.js file. I also verified that I use an up to date version, I have no clue whats going on here and why it seems I am the only one with this problem on edge.

EDIT:

The best approach I have atm. is using pc.addIceCandidate(null) only here:

function handleIceCandidate(event) {
  console.log('icecandidate event: ', event);
  if (event.candidate) {
    sendMessage([{
      type: 'candidate',
      label: event.candidate.sdpMLineIndex,
      id: event.candidate.sdpMid,
      candidate: event.candidate.candidate
    }, room]);
  } else {
    if (window.navigator.userAgent.indexOf("Edge") > -1) {
      pc.addIceCandidate(null);
    }
  }
}

This will go into the else if in adapter.js where it tries to append a=end-of-candidates\r\n, but it fails before with:

0: InvalidAccessError

Its this line in adapter.js:

pc.transceivers[j].iceTransport.addRemoteCandidate({});

I think I need to add the null candidate here, I tried different syntax variants, but no success:

pc.transceivers[j].iceTransport.addRemoteCandidate(null);
pc.transceivers[j].iceTransport.addRemoteCandidate({candidate:''});
pc.transceivers[j].iceTransport.addRemoteCandidate();
pc.transceivers[j].iceTransport.addRemoteCandidate({""});

From Microsoft Docu on Edge:

When the remote RTCIceGathereremits its final candidate, addRemoteCandidate() should be called with an RTCIceCandidateComplete dictionary as an argument, so that the local RTCIceTransport can know there are no more remote candidates expected, and can enter the "completed" state.

I tried:

pc.transceivers[j].iceTransport.addRemoteCandidate(new RTCIceCandidateComplete({complete:true}));
pc.transceivers[j].iceTransport.addRemoteCandidate({complete:true});

The first one gives me:

RTCIceCandidateComplete is not defined
0

There are 0 answers