I'm trying to build a one-page webRTC app in order to learn this topic. I have 2 audio tags :
<audio id="local"></audio>
<audio id="remote"></audio>
One represents the local peer and the other represents the remote peer. I've successfully "sent" the local video to the remote peer - the descriptions were set as the local and the remote descriptions of the 2 peers and the stream was successfully "arrived" to the remote peer - I can inspect the 2 audio elements and see that they both have a blob url of the stream. But, only when I play the local video I can hear the audio - when I'm turning it off and playing the remote audio, I don't hear anything.
Why is it happening? Here is the JS code:
var local = document.querySelector("#local"); //The local audio tag
var remote = document.querySelector("#remote"); //The remote audio tag
var pc1; //The local peer
var pc2; //The remote peer
//Autoplay
//local.play();
remote.play();
navigator.webkitGetUserMedia({audio:true},function(stream){ //Get the audio
local.src = window.URL.createObjectURL(stream);
pc1 = new webkitRTCPeerConnection(null); //Initialize the local peer
pc2 = new webkitRTCPeerConnection(null); //Initialize the remote peer
pc1.addStream(stream); //Add the local stream to the connection => pass it to the remote peer
pc1.createOffer(gotDescription1); //Create an offer and when you get the description call gotDescription1
pc2.createAnswer(gotDescription2); //Create an answer acoording to the description you get from the local peer
pc1.onicecandidate = gotLocalIceCandidate;
pc2.onicecandidate = gotRemoteIceCandidate;
pc2.onaddstream = gotRemoteStream; //When you get stream, call gotRemoteStream
},function(e){ //If there is an error
console.error("ERROR: "+e);
});
function gotDescription1(desc){
console.log("Offer from pc1 \n" + desc.sdp);
pc1.setLocalDescription(desc); //set the description as the local description of the local peer
//(Send the description to the remote peer)
pc2.setRemoteDescription(desc); //set the description as the remote description of the remote peer
}
function gotDescription2(desc){
console.log("Set the description in pc2");
pc2.setLocalDescription(desc); //Set the description as the local description of the remote peer
//(Send the description to the local peer)
pc1.setRemoteDescription(desc); //set the description as the remote description of the local peer
}
function gotRemoteStream(e){
remote.src = window.URL.createObjectURL(e.stream); //Play the stream you get
}
function gotLocalIceCandidate(event) {
if (event.candidate) {
pc2.addIceCandidate(new RTCIceCandidate(event.candidate));
}
}
function gotRemoteIceCandidate(event) {
if (event.candidate) {
pc1.addIceCandidate(new RTCIceCandidate(event.candidate));
}
}
You order of execution in your javascript is slightly off
You have not set the onaddstream
event handler until already getting the remote stream(getting the remote stream can happen as early as setting the remote description).
It is also better for you to handle creating the answer inside the gotDescription1
callback as the callbacks are asynchronous and could be called out of order. I also set both audio html5 elements to autoplay instead of having to set them to play(you may want to do this as well)
Get user media changes:
navigator.webkitGetUserMedia({ audio: true }, function (stream) { //Get the audio
local.src = window.URL.createObjectURL(stream);
pc1 = new webkitRTCPeerConnection(null); //Initialize the local peer
pc2 = new webkitRTCPeerConnection(null); //Initialize the remote peer
pc1.addStream(stream); //Add the local stream to the connection => pass it to the remote peer
pc1.onicecandidate = gotLocalIceCandidate;
pc2.onicecandidate = gotRemoteIceCandidate;
pc2.onaddstream = gotRemoteStream; //When you get stream, call gotRemoteStream
pc1.createOffer(gotDescription1); //Create an offer and when you get the description call gotDescription1
}, function (e) { //If there is an error
console.error("ERROR: " + e);
});
And the gotDescription1
callback:
function gotDescription1(desc) {
console.log("Offer from pc1 \n" + desc.sdp);
pc1.setLocalDescription(desc); //set the description as the local description of the local peer
//(Send the description to the remote peer)
pc2.setRemoteDescription(desc); //set the description as the remote description of the remote peer
pc2.createAnswer(gotDescription2); //Create an answer acoording to the description you get from the local peer
}