Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[InvalidStateError: "setRemoteDescription needs to called before addIceCandidate" code: 11

I create a simple video calling app by using web Rtc and websockets. But when i run the code, the following error occured.

DOMException [InvalidStateError: "setRemoteDescription needs to called before addIceCandidate" code: 11

I don't know how to resolve this error. Here is my code below:

enter code here

var localVideo;
var remoteVideo;
var peerConnection;
var uuid;
var localStream;
var peerConnectionConfig = {
'iceServers': [
    {'urls': 'stun:stun.services.mozilla.com'},
    {'urls': 'stun:stun.l.google.com:19302'},
]
};

function pageReady() {
    uuid = uuid();
    console.log('Inside Page Ready');
    localVideo = document.getElementById('localVideo');
    remoteVideo = document.getElementById('remoteVideo');

   serverConnection = new WebSocket('wss://' + window.location.hostname + 
   ':8443');
   serverConnection.onmessage = gotMessageFromServer;

   var constraints = {
       video: true,
       audio: true,
   };

   if(navigator.mediaDevices.getUserMedia) {

   navigator.mediaDevices.getUserMedia(constraints)
   .then(getUserMediaSuccess).catch(errorHandler);
   }else
   {
       alert('Your browser does not support getUserMedia API');
   }
   }

   function getUserMediaSuccess(stream) {
        localStream = stream;
        localVideo.src = window.URL.createObjectURL(stream); 
   }

   function start(isCaller) {
       console.log('Inside isCaller');
       peerConnection = new RTCPeerConnection(peerConnectionConfig);
       peerConnection.onicecandidate = gotIceCandidate;
       peerConnection.onaddstream = gotRemoteStream;
       peerConnection.addStream(localStream);

       if(isCaller) {
            console.log('Inside Caller to create offer');
            peerConnection.createOffer().
            then(createdDescription).catch(errorHandler);
       }
      }

   function gotMessageFromServer(message) {
   console.log('Message from Server');
   if(!peerConnection) 
   {
        console.log('Inside !Peer Conn');
        start(false);
   }

   var signal = JSON.parse(message.data);

   // Ignore messages from ourself
   if(signal.uuid == uuid) return;

   if(signal.sdp) {
        console.log('Inside SDP');
        peerConnection.setRemoteDescription(new 
        RTCSessionDescription(signal.sdp)).then(function() {
        // Only create answers in response to offers
        if(signal.sdp.type == 'offer') {
            console.log('Before Create Answer');
            peerConnection.createAnswer().then(createdDescription)
            .catch(errorHandler);
        }
     }).catch(errorHandler);
     } else if(signal.ice) {
           console.log('Inside Signal Ice');
           peerConnection.addIceCandidate(new 
           RTCIceCandidate(signal.ice)).catch(errorHandler);
     }

    }

    function gotIceCandidate(event) {
         console.log('Inside Got Ice Candi');
         if(event.candidate != null) {
         serverConnection.send(JSON.stringify({'ice': event.candidate, 
         'uuid': uuid}));
    }
  }

  function createdDescription(description) {
  console.log('got description');

    peerConnection.setLocalDescription(description).then(function() {
    console.log('Inside Setting ');
    serverConnection.send(JSON.stringify({'sdp': 
    peerConnection.localDescription, 'uuid': uuid}));
   }).catch(errorHandler);
  }

  function gotRemoteStream(event) {
  console.log('got remote stream');
  remoteVideo.src = window.URL.createObjectURL(event.stream);
  }

  function errorHandler(error) {
     console.log(error);
  }

  // Taken from http://stackoverflow.com/a/105074/515584
  // Strictly speaking, it's not a real UUID, but it gets the job done here
  function uuid() {
      function s4() {
      return Math.floor((1 + Math.random()) * 
      0x10000).toString(16).substring(1);
      }

  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + 
  s4() + s4();
  }

This is my code, I don't know how to arrange the addIceCandidate and addRemoteDescription function.

like image 476
Umer Ali Avatar asked Oct 20 '25 10:10

Umer Ali


1 Answers

You need to make sure that peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)) is called after description is set. You have sitution where you receive ice candidate and try to add it to peerConnection before peerConnection has completed with setting description.

I had similar situation, and I created array for storing candidates that arrived before setting description is completed, and a variable that checks if description is set. If description is set, I would add candidates to peerConnection, otherwise I would add them to array. (when you set your variable to true, you can also go through array and add all stored candidates to peerConnection.

like image 188
Velexior Avatar answered Oct 22 '25 04:10

Velexior



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!