I have been having this error for a while
Have been trying to use async to wait for the local description to be updated but as how my code works right now it would not be able to integrate it and also I heard that socket.on already does async itself.
I have also tried using breakpoints in vs code to debug the code which doesn't work well.
Would greatly appreciate if anyone knows a workaround for this. The code is attached below
'use strict';
var localStream;
var remoteStream;
var isInitiator;
var configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
var pc = new RTCPeerConnection(configuration);
// Define action buttons.
const callButton = document.getElementById('callButton');
const hangupButton = document.getElementById('hangupButton');
/////////////////////////////////////////////
window.room = prompt('Enter room name:');
var socket = io.connect();
if (room !== '') {
console.log('Message from client: Asking to join room ' + room);
socket.emit('create or join', room);
}
socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
startVideo();
});
socket.on('joined', function(room) {
console.log('joined: ' + room);
startVideo();
});
socket.on('log', function(array) {
console.log.apply(console, array);
});
////////////////////////////////////////////////
function sendMessage(message) {
socket.emit('message', message);
}
// This client receives a message
socket.on('message', function(message) {
try {
if (message.type === 'offer') {
pc.setRemoteDescription(new RTCSessionDescription(message));
// const stream = navigator.mediaDevices.getUserMedia({
// audio: true,
// video: true
// });
// stream.getTracks().forEach(track => pc.addTrack(track, localStream));
pc.setLocalDescription(
pc.createAnswer(setLocalAndSendMessage, function(err) {
console
.log(err.name + ': ' + err.message)
.then(pc.setLocalDescription);
})
);
} else if (message.type === 'answer') {
console.log('This is to check if answer was returned');
pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate') {
pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
});
////////////////////////////////////////////////////
const localVideo = document.querySelector('#localVideo');
const remoteVideo = document.querySelector('#remoteVideo');
// Set up initial action buttons status: disable call and hangup.
callButton.disabled = true;
hangupButton.disabled = true;
// Add click event handlers for buttons.
callButton.addEventListener('click', callStart);
hangupButton.addEventListener('click', hangupCall);
function startVideo() {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(function(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
})
.catch(function(err) {
console.log('getUserMedia() error: ' + err.name);
});
callButton.disabled = false;
}
function callStart() {
createPeerConnection();
//pc.addTrack(mediaStream);
//stream.getTracks().forEach(track => pc.addTrack(track, localStream));
callButton.disabled = true;
hangupButton.disabled = false;
if (isInitiator) {
console.log('Sending offer to peer');
pc.createOffer(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message).then(pc.setLocalDescription);
});
}
}
/////////////////////////////////////////////////////////
function createPeerConnection() {
try {
pc = new RTCPeerConnection(null);
pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
pc.ontrack = event => {
if (remoteVideo.srcObject) return;
remoteVideo.srcObject = event.streams[0];
};
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}
function setLocalAndSendMessage(sessionDescription) {
console.log('setLocalAndSendMessage sending message', sessionDescription);
pc.setLocalDescription(sessionDescription);
sendMessage(sessionDescription);
}
function hangupCall() {
pc.close();
pc = null;
}