Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PeerConnection cannot create an answer [duplicate]

I am getting this error in my catch block when I do myPeerConnection.createAnswer()

PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.

I am using socket.io as the signalling server. I am following the tutorial from MDN

Here's my code:

myPeerConnection.setRemoteDescription(desc).then(() => {
    return navigator.mediaDevices.getUserMedia(mediaConstraints);
  }).then((stream) => {
    localStream = stream;
    document.getElementById("localVideo").srcObject = localStream;
    return myPeerConnection.addStream(localStream);
  }).then(() => {
    return myPeerConnection.createAnswer(); //No error when removed this then chain
  }).then((answer) => {
    return myPeerConnection.setLocalDescription(answer); // No error when removed this then chain
  }).then(() => {
    socket.emit('video-answer', {
      sdp: myPeerConnection.localDescription
    });
  }).catch(handleGetUserMediaError);

The answer here didn't helped me either.

I have uploaded the whole project on Github. You can look at the script file here.

Any help is appreciated.

like image 453
DragonBorn Avatar asked Jun 29 '18 10:06

DragonBorn


2 Answers

This is long-standing a bug in Chrome I filed a year and a half ago.

You're creating a peer connection in both the onclick handler and handleVideoOfferMsg, complete with an onnegotiationneeded handler that calls createOffer. That's OK and straight out of the spec example.

In handleVideoOfferMsg you go on to call setRemoteDescription(desc), bringing that peer connection to have-remote-offer state, and then you add tracks to it for your answer.

The bug in Chrome is that adding those tracks fire the negotiationneeded event, when the spec says to only set the negotiationneeded flag in "stable" state.

Try it in Firefox. It should work there.

You can work around this in Chrome somewhat, like this:

pc.onnegotiationneeded = e => {
  if (pc.signalingState != "stable") return;
  ..
}
like image 155
jib Avatar answered Nov 15 '22 05:11

jib


Metaphorically speaking, you are trying to answer a question without being asked a question. This does not make sense -- and the peerconnection API tells you exactly that.

like image 42
Philipp Hancke Avatar answered Nov 15 '22 03:11

Philipp Hancke