I had earlier posted some questions on this problem. At that time I had two separate programs for caller and receiver. I was also using old-fashioned callback API. Thanks to help from @jib on that post, I was able to understand the need for some fundamental changes. I rewrote the program to make it an integrated one for both caller and receiver and have used the WebRTC promises API. My problem is that I am not getting remote video from either end. One part I understand but do not know the solution: The receiver does not create SDPs for Video in the first place, only for audio. The caller part does create SDPS for Video and audio but on the receiver end there is no event generated for remote stream.
I have checked, through console logs, that the core functions work. Offer SDP is created, sent out, received, answer SDP created, sent out, received, etc. Candidates get exchanged and added too. But the .onaddstream event handler is never triggered. Local video is shown but that is trivial.
I have spent a LOT of time on this. I simply need to get that exciting feeling of seeing remote video on both ends which has kept me going. ANY HELP WILL BE SINCERELY APPRECIATED.
<script>
$(document).ready(function () {
var iceCandidates = [], countIceCandidates=0;
var socket = io.connect();
socket.on('connect',function() { console.log("Socket connected"); });
var pc = new RTCPeerConnection({"iceServers":[{"url":"stun:stun.l.google.com:19302"}]});
//If remote video stream comes in, display it in DIV vid2
pc.onaddStream = function (event) {
stream = event.stream;
var video = $('#vid2');
video.attr('src', URL.createObjectURL(stream));
video.onloadedmetadata = function(e) { video.play(); }
}
//Display media in both Caller and Receiver
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(function(stream) {
var video = $('#vid1');
video.attr('src', URL.createObjectURL(stream));
video.onloadedmetadata = function(e) { video.play(); };
pc.addStream(stream);
})
.catch(function(err) { console.log(err);});
//INITIATE CALL
$('#call').click(function() {
pc.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: true })
.then(function(offer) {
localSessionDescription = new RTCSessionDescription(offer);
pc.setLocalDescription(localSessionDescription)
.then (function() { socket.emit('sdpOffer',localSessionDescription); })
.catch(function(err) { console.log("Error in setLocalDescription"); console.log(err); })
.catch(function(err) { console.log("Error in createOffer"); console.log(err); })
});
})
pc.onicecandidate = function (event) {
socket.emit('candidate',event.candidate);
};
socket.on('candidate',function (data) {
if (data != null) {
pc.addIceCandidate(new RTCIceCandidate(data))
.then(function() { console.log("peer candidate added");})
.catch(function(err) {console.log(err); console.log("Error during peer candidate addition");});
}
});
socket.on('disconnect',function() { alert("Disconnected"); });
function error(err) {
console.log("The following error occurred: " + err.name);
}
socket.on('sdpAnswer',function(data) {
sdpAnswer = new RTCSessionDescription(data.sdpAnswer);
pc.setRemoteDescription(sdpAnswer)
.then(function() { console.log("Answer SDP Set:"); console.log(sdpAnswer); })
.catch(function(err) { console.log("Error enountered when setting remote SDP Answer"); console.log(err)});
});
socket.on('sdpOffer', function(data) {
sdpOffer = new RTCSessionDescription(data.sdpOffer);
pc.setRemoteDescription(sdpOffer)
.then(function() { console.log("Remote SDP set in receiver");
pc.createAnswer()
.then(function(sdpAnswer) {
localSessionDescription = new RTCSessionDescription(sdpAnswer);
socket.emit('sdpAnswer',localSessionDescription);
pc.setLocalDescription(localSessionDescription)
.then(function(){
console.log("Local SDP Description set in receiver:");
})
.catch(function(err) { console.log("Error enountered when setting local SDP in receiver"); console.log(err)});
})
.catch(function(err) { console.log("Error enountered when creating answer SDP in receiver"); console.log(err)});
});
});
}); //End of document.ready function
</script>
ON THE SERVER SIDE (RELEVANT CODE ONLY). I have included here just in case there are any datatype related issues - object types, etc. getting changed when sent thru the server.
io.sockets.on('connection', function(socket) {
socket.on('sdpOffer', function(data) {
sdpOffer = data.sdp;
socket.broadcast.emit('sdpOffer',{"sdpOffer":data});
});
socket.on('sdpAnswer', function(data) {
sdpAnswer = data.sdp;
socket.broadcast.emit('sdpAnswer',{"sdpAnswer":data});
});
socket.on('candidate', function(data) {
socket.broadcast.emit('candidate',data);
});
});