My video chat app works properly in the same network. It generates and connects IceCandidate using stun as well. But for some reason the peer videos don't play in different networks. I am having trouble debugging the issue.
I haven't used any turn server but I doubt that is the problem as the peers from different networks already joins using stun, only videos don't play
var socket= io('/')
var divVideoChatLobby = document.getElementById("video-chat-lobby")
var divVideoChat = document.getElementById("video-chat-room")
var joinButton = document.getElementById("join")
var userVideo = document.getElementById("user-video")
var peerVideo = document.getElementById("peer-video")
var roomInput = document.getElementById("roomName")
var roomname= roomInput.value
var rtcPeerConnection
var userStream
const iceServers = {
iceServers:[
{urls: "stun:stun.services.mozilla.com"},
{urls: "stun:stun.l.google.com:19302"},
{urls: "stun:stun1.l.google.com:19302"},
{urls: "stun:stun3.l.google.com:19302"},
{urls: "stun:stun4.l.google.com:19302"},
{urls: "stun:stun.ekiga.net"},
]
}
userVideo.muted= "muted"
// var roomDiv = document.getElementById("room-div")
// roomDiv.style="display:none"
var creator=false
joinButton.addEventListener('click', function () {
console.log('Room Name:', roomInput.value)
if (roomInput.value == "") {
alert("Please enter a room name")
}
else {
socket.emit("join",roomInput.value)
}
})
socket.on("created",function(){
creator=true
navigator.getUserMedia(
{
audio: true,
video:true
// { width: 1280, height: 720 }
},
function(stream) {
divVideoChatLobby.style="display:none"
// roomInput.value
// roomDiv.style="visibility: visible"
// console.log('room name',roomInput)
console.log("got user media stream")
userStream= stream
userVideo.srcObject = stream
userVideo.onloadedmetadata = function(e){
userVideo.play()}
},
function() {
alert("Couldn't acces User Media")
}
)
})
socket.on("joined",function(){
creator=false
navigator.getUserMedia(
{
audio: true,
video:true
// { width: 1280, height: 720 }
},
function(stream) {
divVideoChatLobby.style="display:none"
// roomInput.value
// roomDiv.style="visibility: visible"
// console.log('room name',roomInput)
userStream=stream
userVideo.srcObject = stream
userVideo.onloadedmetadata = function(e){
userVideo.play()}
socket.emit("ready",roomInput.value)
console.log("haha to you")
},
function() {
alert("Couldn't acces User Media")
}
)
})
socket.on("full",function(){
alert("The room is full. You cannot join now")
})
socket.on("ready",function(){
console.log("haha to you 3")
if(creator){
rtcPeerConnection= new RTCPeerConnection(iceServers)
rtcPeerConnection.onicecandidate= OnIceCandidateFunction
rtcPeerConnection.ontrack = OnTrackFunction
rtcPeerConnection.addTrack(userStream.getTracks()[0],userStream)
rtcPeerConnection.addTrack(userStream.getTracks()[1],userStream)
rtcPeerConnection.createOffer(function(offer){
rtcPeerConnection.setLocalDescription(offer)
socket.emit("offer", offer, roomInput.value)
},function(error){
console.log(error)
})
}
})
socket.on("candidate", function (candidate) {
var icecandidate = new RTCIceCandidate(
{candidate: candidate.candidate,
sdpMID:candidate.sdpMID,
sdpMLineIndex:candidate.sdpMLineIndex,})
console.log("INSIDE CANDIDATEEEEEEEEEEEEEEE")
rtcPeerConnection.addIceCandidate(icecandidate)
});
// socket.on("candidate",function(candidate){
// rtcPeerConnection.addIceCandidate(candidate)
// })
socket.on("offer",function(offer){
if(!creator){
rtcPeerConnection= new RTCPeerConnection(iceServers)
rtcPeerConnection.onicecandidate= OnIceCandidateFunction
rtcPeerConnection.ontrack = OnTrackFunction
rtcPeerConnection.addTrack(userStream.getTracks()[0],userStream)
rtcPeerConnection.addTrack(userStream.getTracks()[1],userStream)
rtcPeerConnection.setRemoteDescription(offer)
rtcPeerConnection.createAnswer(function(answer){
rtcPeerConnection.setLocalDescription(answer)
socket.emit("answer", answer, roomInput.value)
},function(error){
console.log(error)
})
}
})
socket.on("answer",function(answer){
rtcPeerConnection.setRemoteDescription(answer)
})
function OnIceCandidateFunction(event){
console.log('EVENT CANDIDATE',event.candidate)
if(event.candidate){
// console.log('EVENT CANDIDATE',event.candidate)
socket.emit("candidate",event.candidate,roomInput.value)
}
}
function OnTrackFunction(event){
peerVideo.srcObject = event.streams[0]
console.log("EVENT STREAM 0", event.streams[0])
peerVideo.onloadedmetadata = function(e){
console.log("IN THE ONTRACKFUNC")
peerVideo.play()
}
}
WebRTC can connect in a few ways, and falls down progressively to lower preference choices as it fails at its first choices.
WebRTC tries everything it can do to make a p2p connection, but there are times that it will fail. The turn server acts as a last resort so that the peers can both connect through the turn server. Obviously this is not a p2p connection, so there will be extra latency, and you will have to make sure that your turn server has enough bandwidth to cover all of the connections you expect.
Usually about 20% of connections require a TURN server. It may work fine for you on your network, but try accessing your webRTC service from a different network which has firewall and different network configurations (which will usually require TURN), and you'll see that not all connections are equal when it comes to p2p. so basically this is what is happening to you that different peer are in different network so you are not getting video of peers.
Basically what happens is that since peers have different networks so It become harder to do correct Ice candidate exchange so no media transmission happens that was decided during sdp negotiation, so we need a a public common server(TURN server) which acts as a peer to other peers for smooth ice-candidate exchange so that media transmission can happens (where this TURN server act as a relay for the media transmission between peers) I am sure in your case along with video, audio too is not working for this reasons.