WEBRTC 视频聊天应用程序无法在不同网络中运行
WEBRTC video chat app not working in different networks
我的视频聊天应用程序在同一网络中运行正常。它还使用 stun 生成并连接 IceCandidate。但出于某种原因,对等视频不会在不同的网络中播放。我在调试问题时遇到问题。
我没有使用过任何 turn 服务器,但我怀疑这是问题所在,因为来自不同网络的对等方已经使用 stun 加入,只有视频无法播放
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 可以通过几种方式连接,并逐渐下降到较低的偏好选择,因为它在第一个选择上失败了。
- 天真的直接 p2p 用自己的 ip
- 如果失败,使用 STUN 服务器来确定我们落后的 ip(例如,路由器)
- 如果失败,则无法实现真正的 p2p,请使用 TURN 服务器来中继流量。
WebRTC 尽其所能建立 p2p 连接,但有时会失败。转弯服务器充当最后的手段,以便对等点都可以通过转弯服务器进行连接。显然这不是 p2p 连接,因此会有额外的延迟,您必须确保您的 turn 服务器有足够的带宽来覆盖您期望的所有连接。
通常大约 20% 的连接需要 TURN 服务器。它可能在您的网络上工作正常,但尝试从具有防火墙和不同网络配置(通常需要 TURN)的不同网络访问您的 webRTC 服务,您会发现并非所有连接都是平等的p2p。所以基本上这就是你正在发生的事情,不同的对等点在不同的网络中,所以你没有得到对等点的视频。
基本上发生的事情是,由于对等点具有不同的网络,因此更难进行正确的 Ice 候选交换,因此没有发生在 sdp 协商期间决定的媒体传输,因此我们需要一个 public 公共服务器(TURN服务器)充当其他对等点的对等点,以便顺利进行 ice-candidate 交换,以便可以进行媒体传输(此 TURN 服务器充当对等点之间媒体传输的中继)我相信在您的情况下还有视频、音频由于这个原因不工作。
我的视频聊天应用程序在同一网络中运行正常。它还使用 stun 生成并连接 IceCandidate。但出于某种原因,对等视频不会在不同的网络中播放。我在调试问题时遇到问题。
我没有使用过任何 turn 服务器,但我怀疑这是问题所在,因为来自不同网络的对等方已经使用 stun 加入,只有视频无法播放
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 可以通过几种方式连接,并逐渐下降到较低的偏好选择,因为它在第一个选择上失败了。
- 天真的直接 p2p 用自己的 ip
- 如果失败,使用 STUN 服务器来确定我们落后的 ip(例如,路由器)
- 如果失败,则无法实现真正的 p2p,请使用 TURN 服务器来中继流量。
WebRTC 尽其所能建立 p2p 连接,但有时会失败。转弯服务器充当最后的手段,以便对等点都可以通过转弯服务器进行连接。显然这不是 p2p 连接,因此会有额外的延迟,您必须确保您的 turn 服务器有足够的带宽来覆盖您期望的所有连接。
通常大约 20% 的连接需要 TURN 服务器。它可能在您的网络上工作正常,但尝试从具有防火墙和不同网络配置(通常需要 TURN)的不同网络访问您的 webRTC 服务,您会发现并非所有连接都是平等的p2p。所以基本上这就是你正在发生的事情,不同的对等点在不同的网络中,所以你没有得到对等点的视频。
基本上发生的事情是,由于对等点具有不同的网络,因此更难进行正确的 Ice 候选交换,因此没有发生在 sdp 协商期间决定的媒体传输,因此我们需要一个 public 公共服务器(TURN服务器)充当其他对等点的对等点,以便顺利进行 ice-candidate 交换,以便可以进行媒体传输(此 TURN 服务器充当对等点之间媒体传输的中继)我相信在您的情况下还有视频、音频由于这个原因不工作。