“Cannot create answer in state stable” in chrome [duplicate]
This question already has an answer here:
How to set remote description for a WebRTC caller in Chrome without errors?
1 answer
I'm implementing WebRTC peer-to-peer call, it is working well in all browser except if chrome is the call initializer (who invoke invite function).
if chrome is the call initializer, the ICE connection state change to connected and the video appear in the other peer,then an error "DOMException: "Cannot create answer in state stable"' happen and the video stop transfer to the other peer.
if the receiver is also chrome, the error says "Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer."
these are the handleVideoOfferMsg function and handleGetUserMediaError function (which trigger the error) code:
function handleVideoOfferMsg(msg) {
// debugger;
// $("#ring")[0].play();
var localStream = null;
targetUsername = msg.from;
// Call createPeerConnection() to create the RTCPeerConnection.
log("Starting to accept invitation from " + targetUsername);
createPeerConnection();
// We need to set the remote description to the received SDP offer
// so that our local WebRTC layer knows how to talk to the caller.
var desc = new RTCSessionDescription(msg.sdp);
myPeerConnection.setRemoteDescription(desc).then(function () {
log("Setting up the local media stream...");
return navigator.mediaDevices.getUserMedia(responserConstraints);
})
.then(function(stream) {
$("#video-container").removeClass("hidden");
log("-- Local video stream obtained");
localStream = stream;
if(responserConstraints.hasOwnProperty('video'))
{
$("#localVideo").removeClass('hidden')[0].srcObject = localStream;
}
log("-- Adding outgoing tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.then(function() {
log("------> Creating answer");
// Now that we've successfully set the remote description, we need to
// start our stream up locally then create an SDP answer. This SDP
// data describes the local end of our call, including the codec
// information, options agreed upon, and so forth.
return myPeerConnection.createAnswer();
})
.then(function(answer) {
log("------> Setting local description after creating answer");
// We now have our answer, so establish that as the local description.
// This actually configures our end of the call to match the settings
// specified in the SDP.
return myPeerConnection.setLocalDescription(answer);
})
.then(function() {
var msg = {
name: myUsername,
target: targetUsername,
type: "video-answer",
sdp: myPeerConnection.localDescription
};
// We've configured our end of the call now. Time to send our
// answer back to the caller so they know that we want to talk
// and how to talk to us.
log("Sending answer packet back to other peer");
sendToServer(msg);
})
.catch(
handleGetUserMediaError);
}
function handleGetUserMediaError(e) {
log(e);
switch(e.name) {
case "NotFoundError":
alert("Unable to open your call because no camera and/or microphone" +
"were found.");
break;
case "SecurityError":
case "PermissionDeniedError":
// Do nothing; this is the same as the user canceling the call.
break;
default:
//the error occur here
alert("Error opening your camera and/or microphone: " + e.message);
console.log("----------");
console.log(e);
break;
}
// Make sure we shut down our end of the RTCPeerConnection so we're
// ready to try again.
closeVideoCall();
}
the invite function:
function invite() {
log("Starting to prepare an invitation");
if (myPeerConnection) {
alert("You can't start a call because you already have one open!");
} else {
var clickedUsername = $("input[name=teacherId]").val();
console.log('user id is '+ clickedUsername);
// Don't allow users to call themselves, because weird.
if (clickedUsername === myUsername) {
alert("I'm afraid I can't let you talk to yourself. That would be weird.");
return;
}
// Record the username being called for future reference
targetUsername = clickedUsername;
log("Inviting user " + targetUsername);
// Call createPeerConnection() to create the RTCPeerConnection.
log("Setting up connection to invite user: " + targetUsername);
createPeerConnection();
// Now configure and create the local stream, attach it to the
// "preview" box (id "video"), and add it to the
// RTCPeerConnection.
log("Requesting webcam access...");
isInviter = true;
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(function(localStream) {
$("#video-container").removeClass("hidden");
console.log(localStream);
log("-- Local video stream obtained");
if(responserConstraints.hasOwnProperty('video'))
{
var localVideo = $('#localVideo');
localVideo.removeClass('hidden')[0].srcObject = localStream;
localVideo[0].mute;
}
else
{
var videoEl = document.getElementById("video");
videoEl.muted = true;
videoEl.srcObject = localStream;
}
log("-- Adding incoming tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.catch(handleGetUserMediaError);
}
}
the console response is the following:
[3:28:31 PM] *** ICE gathering state changed to: gathering
opensocket.js:66 [3:28:31 PM] Outgoing ICE candidate: candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10
opensocket.js:66 [3:28:31 PM] Sending 'new-ice-candidate' message: {"type":"new-ice-candidate","candidate":{"candidate":"candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10","sdpMid":"audio","sdpMLineIndex":0,"usernameFragment":"76SW"},"hash":"m0wk8Kaz8JFejuJGte7kAmNtYDiWPZNBGl7fKA5b"}
opensocket.js:66 [3:28:31 PM] -- Local video stream obtained
opensocket.js:66 [3:28:31 PM] -- Adding outgoing tracks to the RTCPeerConnection
opensocket.js:66 [3:28:31 PM] ------> Creating answer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:66 [3:28:31 PM] InvalidStateError: Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.
I can't find a way to solve it !, the error only occur in chrome !
Any help, please ?
Edit: This is my handleNegotiationNeededEvent function:
function handleNegotiationNeededEvent() {
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
javascript stream video-streaming webrtc
marked as duplicate by jib
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Jan 3 at 14:41
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
How to set remote description for a WebRTC caller in Chrome without errors?
1 answer
I'm implementing WebRTC peer-to-peer call, it is working well in all browser except if chrome is the call initializer (who invoke invite function).
if chrome is the call initializer, the ICE connection state change to connected and the video appear in the other peer,then an error "DOMException: "Cannot create answer in state stable"' happen and the video stop transfer to the other peer.
if the receiver is also chrome, the error says "Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer."
these are the handleVideoOfferMsg function and handleGetUserMediaError function (which trigger the error) code:
function handleVideoOfferMsg(msg) {
// debugger;
// $("#ring")[0].play();
var localStream = null;
targetUsername = msg.from;
// Call createPeerConnection() to create the RTCPeerConnection.
log("Starting to accept invitation from " + targetUsername);
createPeerConnection();
// We need to set the remote description to the received SDP offer
// so that our local WebRTC layer knows how to talk to the caller.
var desc = new RTCSessionDescription(msg.sdp);
myPeerConnection.setRemoteDescription(desc).then(function () {
log("Setting up the local media stream...");
return navigator.mediaDevices.getUserMedia(responserConstraints);
})
.then(function(stream) {
$("#video-container").removeClass("hidden");
log("-- Local video stream obtained");
localStream = stream;
if(responserConstraints.hasOwnProperty('video'))
{
$("#localVideo").removeClass('hidden')[0].srcObject = localStream;
}
log("-- Adding outgoing tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.then(function() {
log("------> Creating answer");
// Now that we've successfully set the remote description, we need to
// start our stream up locally then create an SDP answer. This SDP
// data describes the local end of our call, including the codec
// information, options agreed upon, and so forth.
return myPeerConnection.createAnswer();
})
.then(function(answer) {
log("------> Setting local description after creating answer");
// We now have our answer, so establish that as the local description.
// This actually configures our end of the call to match the settings
// specified in the SDP.
return myPeerConnection.setLocalDescription(answer);
})
.then(function() {
var msg = {
name: myUsername,
target: targetUsername,
type: "video-answer",
sdp: myPeerConnection.localDescription
};
// We've configured our end of the call now. Time to send our
// answer back to the caller so they know that we want to talk
// and how to talk to us.
log("Sending answer packet back to other peer");
sendToServer(msg);
})
.catch(
handleGetUserMediaError);
}
function handleGetUserMediaError(e) {
log(e);
switch(e.name) {
case "NotFoundError":
alert("Unable to open your call because no camera and/or microphone" +
"were found.");
break;
case "SecurityError":
case "PermissionDeniedError":
// Do nothing; this is the same as the user canceling the call.
break;
default:
//the error occur here
alert("Error opening your camera and/or microphone: " + e.message);
console.log("----------");
console.log(e);
break;
}
// Make sure we shut down our end of the RTCPeerConnection so we're
// ready to try again.
closeVideoCall();
}
the invite function:
function invite() {
log("Starting to prepare an invitation");
if (myPeerConnection) {
alert("You can't start a call because you already have one open!");
} else {
var clickedUsername = $("input[name=teacherId]").val();
console.log('user id is '+ clickedUsername);
// Don't allow users to call themselves, because weird.
if (clickedUsername === myUsername) {
alert("I'm afraid I can't let you talk to yourself. That would be weird.");
return;
}
// Record the username being called for future reference
targetUsername = clickedUsername;
log("Inviting user " + targetUsername);
// Call createPeerConnection() to create the RTCPeerConnection.
log("Setting up connection to invite user: " + targetUsername);
createPeerConnection();
// Now configure and create the local stream, attach it to the
// "preview" box (id "video"), and add it to the
// RTCPeerConnection.
log("Requesting webcam access...");
isInviter = true;
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(function(localStream) {
$("#video-container").removeClass("hidden");
console.log(localStream);
log("-- Local video stream obtained");
if(responserConstraints.hasOwnProperty('video'))
{
var localVideo = $('#localVideo');
localVideo.removeClass('hidden')[0].srcObject = localStream;
localVideo[0].mute;
}
else
{
var videoEl = document.getElementById("video");
videoEl.muted = true;
videoEl.srcObject = localStream;
}
log("-- Adding incoming tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.catch(handleGetUserMediaError);
}
}
the console response is the following:
[3:28:31 PM] *** ICE gathering state changed to: gathering
opensocket.js:66 [3:28:31 PM] Outgoing ICE candidate: candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10
opensocket.js:66 [3:28:31 PM] Sending 'new-ice-candidate' message: {"type":"new-ice-candidate","candidate":{"candidate":"candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10","sdpMid":"audio","sdpMLineIndex":0,"usernameFragment":"76SW"},"hash":"m0wk8Kaz8JFejuJGte7kAmNtYDiWPZNBGl7fKA5b"}
opensocket.js:66 [3:28:31 PM] -- Local video stream obtained
opensocket.js:66 [3:28:31 PM] -- Adding outgoing tracks to the RTCPeerConnection
opensocket.js:66 [3:28:31 PM] ------> Creating answer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:66 [3:28:31 PM] InvalidStateError: Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.
I can't find a way to solve it !, the error only occur in chrome !
Any help, please ?
Edit: This is my handleNegotiationNeededEvent function:
function handleNegotiationNeededEvent() {
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
javascript stream video-streaming webrtc
marked as duplicate by jib
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Jan 3 at 14:41
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Where's yourcreateOffer
? Also, are you relying onnegotiationneeded
by any chance?
– jib
Jan 3 at 1:37
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41
add a comment |
This question already has an answer here:
How to set remote description for a WebRTC caller in Chrome without errors?
1 answer
I'm implementing WebRTC peer-to-peer call, it is working well in all browser except if chrome is the call initializer (who invoke invite function).
if chrome is the call initializer, the ICE connection state change to connected and the video appear in the other peer,then an error "DOMException: "Cannot create answer in state stable"' happen and the video stop transfer to the other peer.
if the receiver is also chrome, the error says "Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer."
these are the handleVideoOfferMsg function and handleGetUserMediaError function (which trigger the error) code:
function handleVideoOfferMsg(msg) {
// debugger;
// $("#ring")[0].play();
var localStream = null;
targetUsername = msg.from;
// Call createPeerConnection() to create the RTCPeerConnection.
log("Starting to accept invitation from " + targetUsername);
createPeerConnection();
// We need to set the remote description to the received SDP offer
// so that our local WebRTC layer knows how to talk to the caller.
var desc = new RTCSessionDescription(msg.sdp);
myPeerConnection.setRemoteDescription(desc).then(function () {
log("Setting up the local media stream...");
return navigator.mediaDevices.getUserMedia(responserConstraints);
})
.then(function(stream) {
$("#video-container").removeClass("hidden");
log("-- Local video stream obtained");
localStream = stream;
if(responserConstraints.hasOwnProperty('video'))
{
$("#localVideo").removeClass('hidden')[0].srcObject = localStream;
}
log("-- Adding outgoing tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.then(function() {
log("------> Creating answer");
// Now that we've successfully set the remote description, we need to
// start our stream up locally then create an SDP answer. This SDP
// data describes the local end of our call, including the codec
// information, options agreed upon, and so forth.
return myPeerConnection.createAnswer();
})
.then(function(answer) {
log("------> Setting local description after creating answer");
// We now have our answer, so establish that as the local description.
// This actually configures our end of the call to match the settings
// specified in the SDP.
return myPeerConnection.setLocalDescription(answer);
})
.then(function() {
var msg = {
name: myUsername,
target: targetUsername,
type: "video-answer",
sdp: myPeerConnection.localDescription
};
// We've configured our end of the call now. Time to send our
// answer back to the caller so they know that we want to talk
// and how to talk to us.
log("Sending answer packet back to other peer");
sendToServer(msg);
})
.catch(
handleGetUserMediaError);
}
function handleGetUserMediaError(e) {
log(e);
switch(e.name) {
case "NotFoundError":
alert("Unable to open your call because no camera and/or microphone" +
"were found.");
break;
case "SecurityError":
case "PermissionDeniedError":
// Do nothing; this is the same as the user canceling the call.
break;
default:
//the error occur here
alert("Error opening your camera and/or microphone: " + e.message);
console.log("----------");
console.log(e);
break;
}
// Make sure we shut down our end of the RTCPeerConnection so we're
// ready to try again.
closeVideoCall();
}
the invite function:
function invite() {
log("Starting to prepare an invitation");
if (myPeerConnection) {
alert("You can't start a call because you already have one open!");
} else {
var clickedUsername = $("input[name=teacherId]").val();
console.log('user id is '+ clickedUsername);
// Don't allow users to call themselves, because weird.
if (clickedUsername === myUsername) {
alert("I'm afraid I can't let you talk to yourself. That would be weird.");
return;
}
// Record the username being called for future reference
targetUsername = clickedUsername;
log("Inviting user " + targetUsername);
// Call createPeerConnection() to create the RTCPeerConnection.
log("Setting up connection to invite user: " + targetUsername);
createPeerConnection();
// Now configure and create the local stream, attach it to the
// "preview" box (id "video"), and add it to the
// RTCPeerConnection.
log("Requesting webcam access...");
isInviter = true;
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(function(localStream) {
$("#video-container").removeClass("hidden");
console.log(localStream);
log("-- Local video stream obtained");
if(responserConstraints.hasOwnProperty('video'))
{
var localVideo = $('#localVideo');
localVideo.removeClass('hidden')[0].srcObject = localStream;
localVideo[0].mute;
}
else
{
var videoEl = document.getElementById("video");
videoEl.muted = true;
videoEl.srcObject = localStream;
}
log("-- Adding incoming tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.catch(handleGetUserMediaError);
}
}
the console response is the following:
[3:28:31 PM] *** ICE gathering state changed to: gathering
opensocket.js:66 [3:28:31 PM] Outgoing ICE candidate: candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10
opensocket.js:66 [3:28:31 PM] Sending 'new-ice-candidate' message: {"type":"new-ice-candidate","candidate":{"candidate":"candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10","sdpMid":"audio","sdpMLineIndex":0,"usernameFragment":"76SW"},"hash":"m0wk8Kaz8JFejuJGte7kAmNtYDiWPZNBGl7fKA5b"}
opensocket.js:66 [3:28:31 PM] -- Local video stream obtained
opensocket.js:66 [3:28:31 PM] -- Adding outgoing tracks to the RTCPeerConnection
opensocket.js:66 [3:28:31 PM] ------> Creating answer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:66 [3:28:31 PM] InvalidStateError: Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.
I can't find a way to solve it !, the error only occur in chrome !
Any help, please ?
Edit: This is my handleNegotiationNeededEvent function:
function handleNegotiationNeededEvent() {
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
javascript stream video-streaming webrtc
This question already has an answer here:
How to set remote description for a WebRTC caller in Chrome without errors?
1 answer
I'm implementing WebRTC peer-to-peer call, it is working well in all browser except if chrome is the call initializer (who invoke invite function).
if chrome is the call initializer, the ICE connection state change to connected and the video appear in the other peer,then an error "DOMException: "Cannot create answer in state stable"' happen and the video stop transfer to the other peer.
if the receiver is also chrome, the error says "Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer."
these are the handleVideoOfferMsg function and handleGetUserMediaError function (which trigger the error) code:
function handleVideoOfferMsg(msg) {
// debugger;
// $("#ring")[0].play();
var localStream = null;
targetUsername = msg.from;
// Call createPeerConnection() to create the RTCPeerConnection.
log("Starting to accept invitation from " + targetUsername);
createPeerConnection();
// We need to set the remote description to the received SDP offer
// so that our local WebRTC layer knows how to talk to the caller.
var desc = new RTCSessionDescription(msg.sdp);
myPeerConnection.setRemoteDescription(desc).then(function () {
log("Setting up the local media stream...");
return navigator.mediaDevices.getUserMedia(responserConstraints);
})
.then(function(stream) {
$("#video-container").removeClass("hidden");
log("-- Local video stream obtained");
localStream = stream;
if(responserConstraints.hasOwnProperty('video'))
{
$("#localVideo").removeClass('hidden')[0].srcObject = localStream;
}
log("-- Adding outgoing tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.then(function() {
log("------> Creating answer");
// Now that we've successfully set the remote description, we need to
// start our stream up locally then create an SDP answer. This SDP
// data describes the local end of our call, including the codec
// information, options agreed upon, and so forth.
return myPeerConnection.createAnswer();
})
.then(function(answer) {
log("------> Setting local description after creating answer");
// We now have our answer, so establish that as the local description.
// This actually configures our end of the call to match the settings
// specified in the SDP.
return myPeerConnection.setLocalDescription(answer);
})
.then(function() {
var msg = {
name: myUsername,
target: targetUsername,
type: "video-answer",
sdp: myPeerConnection.localDescription
};
// We've configured our end of the call now. Time to send our
// answer back to the caller so they know that we want to talk
// and how to talk to us.
log("Sending answer packet back to other peer");
sendToServer(msg);
})
.catch(
handleGetUserMediaError);
}
function handleGetUserMediaError(e) {
log(e);
switch(e.name) {
case "NotFoundError":
alert("Unable to open your call because no camera and/or microphone" +
"were found.");
break;
case "SecurityError":
case "PermissionDeniedError":
// Do nothing; this is the same as the user canceling the call.
break;
default:
//the error occur here
alert("Error opening your camera and/or microphone: " + e.message);
console.log("----------");
console.log(e);
break;
}
// Make sure we shut down our end of the RTCPeerConnection so we're
// ready to try again.
closeVideoCall();
}
the invite function:
function invite() {
log("Starting to prepare an invitation");
if (myPeerConnection) {
alert("You can't start a call because you already have one open!");
} else {
var clickedUsername = $("input[name=teacherId]").val();
console.log('user id is '+ clickedUsername);
// Don't allow users to call themselves, because weird.
if (clickedUsername === myUsername) {
alert("I'm afraid I can't let you talk to yourself. That would be weird.");
return;
}
// Record the username being called for future reference
targetUsername = clickedUsername;
log("Inviting user " + targetUsername);
// Call createPeerConnection() to create the RTCPeerConnection.
log("Setting up connection to invite user: " + targetUsername);
createPeerConnection();
// Now configure and create the local stream, attach it to the
// "preview" box (id "video"), and add it to the
// RTCPeerConnection.
log("Requesting webcam access...");
isInviter = true;
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(function(localStream) {
$("#video-container").removeClass("hidden");
console.log(localStream);
log("-- Local video stream obtained");
if(responserConstraints.hasOwnProperty('video'))
{
var localVideo = $('#localVideo');
localVideo.removeClass('hidden')[0].srcObject = localStream;
localVideo[0].mute;
}
else
{
var videoEl = document.getElementById("video");
videoEl.muted = true;
videoEl.srcObject = localStream;
}
log("-- Adding incoming tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.catch(handleGetUserMediaError);
}
}
the console response is the following:
[3:28:31 PM] *** ICE gathering state changed to: gathering
opensocket.js:66 [3:28:31 PM] Outgoing ICE candidate: candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10
opensocket.js:66 [3:28:31 PM] Sending 'new-ice-candidate' message: {"type":"new-ice-candidate","candidate":{"candidate":"candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10","sdpMid":"audio","sdpMLineIndex":0,"usernameFragment":"76SW"},"hash":"m0wk8Kaz8JFejuJGte7kAmNtYDiWPZNBGl7fKA5b"}
opensocket.js:66 [3:28:31 PM] -- Local video stream obtained
opensocket.js:66 [3:28:31 PM] -- Adding outgoing tracks to the RTCPeerConnection
opensocket.js:66 [3:28:31 PM] ------> Creating answer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:66 [3:28:31 PM] InvalidStateError: Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.
I can't find a way to solve it !, the error only occur in chrome !
Any help, please ?
Edit: This is my handleNegotiationNeededEvent function:
function handleNegotiationNeededEvent() {
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
This question already has an answer here:
How to set remote description for a WebRTC caller in Chrome without errors?
1 answer
javascript stream video-streaming webrtc
javascript stream video-streaming webrtc
edited Jan 3 at 6:40
shamaseen
asked Jan 2 at 13:33
shamaseenshamaseen
311315
311315
marked as duplicate by jib
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Jan 3 at 14:41
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by jib
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Jan 3 at 14:41
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Where's yourcreateOffer
? Also, are you relying onnegotiationneeded
by any chance?
– jib
Jan 3 at 1:37
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41
add a comment |
1
Where's yourcreateOffer
? Also, are you relying onnegotiationneeded
by any chance?
– jib
Jan 3 at 1:37
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41
1
1
Where's your
createOffer
? Also, are you relying on negotiationneeded
by any chance?– jib
Jan 3 at 1:37
Where's your
createOffer
? Also, are you relying on negotiationneeded
by any chance?– jib
Jan 3 at 1:37
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41
add a comment |
1 Answer
1
active
oldest
votes
Ok I found a solution and it was really strange !
It look like chrome is firing onnegotiationneeded
twice !
I don't know why chrome is doing such weird behavior !
so createOffer
is fired twice because of that, as the log show:
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
so my solution was to change the handleNegotiationNeededEvent
as the following:
var Negotiation = 0;
function handleNegotiationNeededEvent() {
if(Negotiation === 0 )
{
Negotiation++;
}
else
{
return;
}
// if (myPeerConnection.signalingState === "stable") return;
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
it look like strange to me, but at least it is working now.
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Ok I found a solution and it was really strange !
It look like chrome is firing onnegotiationneeded
twice !
I don't know why chrome is doing such weird behavior !
so createOffer
is fired twice because of that, as the log show:
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
so my solution was to change the handleNegotiationNeededEvent
as the following:
var Negotiation = 0;
function handleNegotiationNeededEvent() {
if(Negotiation === 0 )
{
Negotiation++;
}
else
{
return;
}
// if (myPeerConnection.signalingState === "stable") return;
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
it look like strange to me, but at least it is working now.
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
add a comment |
Ok I found a solution and it was really strange !
It look like chrome is firing onnegotiationneeded
twice !
I don't know why chrome is doing such weird behavior !
so createOffer
is fired twice because of that, as the log show:
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
so my solution was to change the handleNegotiationNeededEvent
as the following:
var Negotiation = 0;
function handleNegotiationNeededEvent() {
if(Negotiation === 0 )
{
Negotiation++;
}
else
{
return;
}
// if (myPeerConnection.signalingState === "stable") return;
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
it look like strange to me, but at least it is working now.
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
add a comment |
Ok I found a solution and it was really strange !
It look like chrome is firing onnegotiationneeded
twice !
I don't know why chrome is doing such weird behavior !
so createOffer
is fired twice because of that, as the log show:
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
so my solution was to change the handleNegotiationNeededEvent
as the following:
var Negotiation = 0;
function handleNegotiationNeededEvent() {
if(Negotiation === 0 )
{
Negotiation++;
}
else
{
return;
}
// if (myPeerConnection.signalingState === "stable") return;
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
it look like strange to me, but at least it is working now.
Ok I found a solution and it was really strange !
It look like chrome is firing onnegotiationneeded
twice !
I don't know why chrome is doing such weird behavior !
so createOffer
is fired twice because of that, as the log show:
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
so my solution was to change the handleNegotiationNeededEvent
as the following:
var Negotiation = 0;
function handleNegotiationNeededEvent() {
if(Negotiation === 0 )
{
Negotiation++;
}
else
{
return;
}
// if (myPeerConnection.signalingState === "stable") return;
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");
log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}
it look like strange to me, but at least it is working now.
answered Jan 3 at 6:47
shamaseenshamaseen
311315
311315
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
add a comment |
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
negotiationneeded is somewhat buggy in Chrome: bugs.chromium.org/p/chromium/issues/detail?id=740501
– Philipp Hancke
Jan 3 at 8:14
add a comment |
1
Where's your
createOffer
? Also, are you relying onnegotiationneeded
by any chance?– jib
Jan 3 at 1:37
@jib sorry, I edit the question and added the handleNegotiationNeededEvent which fired onnegotiationneeded
– shamaseen
Jan 3 at 6:41