While calling to another user getting this error "Uncaught (in promise) DOMException: Failed to execute 'setLocalDescription' on 'RTCPeerConnection': Failed to set local offer sdp: Called in wrong state: have-remote-offer".
Receiver is able to see both local and remote stream but caller not able to see remote stream.
switch(type){
case 'client-candidate':
if(pc.localDescription){
await pc.addIceCandidate(new RTCIceCandidate(data));
}
break;
case 'is-client-ready':
if(!pc){
await getConn();
}
if(!localStream){
await getCam();
}
if(pc.iceConnectionState === 'connected'){
send('clent-already-oncall', null, presentUserId, null);
}else{
displayCall(incomingData);
$(document).on('click', '#declineBtn', function(){
send('client-rejected', sendTo, currentUserName, presentUserId, null);
$('#incomingCallModel').modal('toggle');
});
$(document).on('click', '#answerBtn', function(){
send('client-is-ready', sendTo, currentUserName, presentUserId, null);
$('#incomingCallModel').modal('toggle');
createOffer(sendTo, presentUserId);
});
}
break;
case 'client-answer':
if(pc.localDescription){
await pc.setRemoteDescription(data);
}
break;
case 'client-offer':
createAnswer(sendTo, presentUserId, data);
break;
case 'client-is-ready':
createOffer(sendTo, presentUserId);
break;
case 'client-rejected':
alert('Client has rejected your call');
break;
case 'clent-already-oncall':
setTimeout(() => {
alert('client is on other call');
window.location.reload(true);
}, 2000);
break;
}
let pc;
function getConn(){
if(!pc){
pc = new RTCPeerConnection();
}
}
async function getCam(){
try{
if(!pc){
await getConn();
}
mediaStream = await window.navigator.mediaDevices.getUserMedia(mediaConst);
localVideo.srcObject = mediaStream;
localStream = mediaStream;
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
}catch(error){
// alert('Camera not found')
console.log(error);
}
}
function displayCall(incomingData){
$('.incoming-call-user-name').text(incomingData.callingUserName);
let calligUserProfile = $("#allUserList").find("[data-id='" + incomingData.callingUserId + "']").data("profile");
$('.calling-user-pic').attr('src', calligUserProfile);
$('#incomingCallModel').modal('show');
}
function send(type, sendTo, callingUserName, callingUserId, data){
socket.emit('sendChatRequest', JSON.stringify({
type: type,
receiverId: sendTo,
callingUserName: callingUserName,
callingUserId: callingUserId,
data: data,
}));
}
async function createOffer(sendTo, calledById){
if(!pc){
await getConn();
}
if(!localStream){
await getCam();
}
await pc.createOffer(options);
await sendIceCandidate(sendTo,calledById);
await pc.setLocalDescription(pc.localDescription);
send('client-offer', sendTo, currentUserName, calledById, pc.localDescription);
}
async function sendIceCandidate(sendTo, calledById){
pc.onicecandidate = event => {
if(event.candidate !== null){
send('client-candidate', sendTo, currentUserName, calledById, event.candidate);
}
}
pc.ontrack = event => {
console.log(event)
$('#video').removeClass('hide');
$('#video').addClass('show');
$('#videoCall').addClass('hide');
if (remoteVideo.srcObject) return;
remoteVideo.srcObject = event.streams[0];
}
}
async function createAnswer(sendTo, presentUserId, data){
if(!pc){
await getConn();
}
if(!localStream){
await getCam();
}
await sendIceCandidate(sendTo, presentUserId);
await pc.setRemoteDescription(data);
await pc.createAnswer();
await pc.setLocalDescription(pc.localDescription);
send('client-answer', sendTo, currentUserName, presentUserId, pc.localDescription);
}
Possible reasons.
onTrack
event is firing in the caller side.Possible reasons of onTrack
not firing
addTrack
is in the memory before the exchange of offer
, answer
, candidate
happens.