【问题标题】:WEBRTC video chat app not working in different networksWEBRTC 视频聊天应用程序无法在不同的网络中运行
【发布时间】:2021-01-25 09:49:57
【问题描述】:

我的视频聊天应用在同一网络中正常工作。它也使用 stun 生成和连接 IceCandidate。但由于某种原因,对等视频无法在不同的网络中播放。我在调试问题时遇到问题。

我没有使用任何转向服务器,但我怀疑这是问题所在,因为来自不同网络的对等方已经使用 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()
    }
}

【问题讨论】:

    标签: node.js webrtc stun videochat


    【解决方案1】:

    WebRTC 可以通过几种方式进行连接,并在第一次选择失败时逐渐下降到较低的偏好选择。

    1. 天真直接 p2p 与自己的 ip
    2. 如果失败,请使用 STUN 服务器来确定我们落后的 ip(例如路由器)
    3. 如果失败,则无法实现真正​​的 p2p,请改用 TURN 服务器来中继流量。

    WebRTC 尽其所能建立 p2p 连接,但有时它会失败。轮机服务器作为最后的手段,以便对等方都可以通过轮机服务器进行连接。显然这不是 p2p 连接,因此会有额外的延迟,并且您必须确保您的轮流服务器有足够的带宽来覆盖您期望的所有连接。

    通常大约 20% 的连接需要 TURN 服务器。它在您的网络上可能工作正常,但尝试从具有防火墙和不同网络配置(通常需要 TURN)的不同网络访问您的 webRTC 服务,您会发现并非所有连接都是平等的点对点。所以基本上这就是发生在你身上的事情,不同的对等点在不同的网络中,所以你没有得到对等点的视频。

    基本上发生的情况是,由于对等方具有不同的网络,因此很难进行正确的 Ice 候选交换,因此不会发生在 sdp 协商期间决定的媒体传输,因此我们需要一个公共公共服务器(TURN 服务器)作为与其他对等点进行平滑的候选者交换,以便可以进行媒体传输(此 TURN 服务器充当对等点之间媒体传输的中继)我确信在您的情况下,视频和音频也因此无法正常工作.

    【讨论】:

    • 谢谢@mss,但我知道这些。也许我没有把问题说清楚。对等连接建立正常。但是,对等视频不会在不同的网络中播放。在同一个/LAN网络中不是这样
    • @Kimg69,如果您阅读了我的回答的最后几行,我已经提到由于网络配置和防火墙不同,我们需要转服务器,添加更多信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多