【问题标题】:Remote users audio and video not displaying in Peerjs WebRTC远程用户音频和视频未在 Peerjs WebRTC 中显示
【发布时间】:2021-10-01 18:15:19
【问题描述】:

我对 PeerJs 和 WebRTC 非常陌生。由于新冠疫情,最近开始为我的学校学习、开发和应用远程课程。

建立连接后,创建的用户可以在视频中看到他,但远程人员的音频/视频不显示。

服务器代码:

io.on('connection', (socket) => {
    socket.on('room-joined', (roomId, userId) => {
        socket.join(roomId)
        socket.broadcast.to(roomId).emit('new-user-connected', userId)

        socket.on('disconnect', () => {
            socket.broadcast.to(roomId).emit('user-disconnected', userId)
        })
        
        socket.on("offer", payload => {
            socket.broadcast.to(roomId).emit("offer-received", payload);
        });

        socket.on("answer", payload => {
            socket.broadcast.to(roomId).emit("answer-received", payload);
        });

        socket.on("ice-candidate", data => {
            socket.broadcast.to(roomId).emit("ice-candidate-message", data);
        });
    })
})

客户代码:

const socket = io('/');
var selectedCamera = 'user'
var totalUsers = []
let localStream;
let localId
let initiater;
let otherUserId;

const peer = new Peer(undefined, {
    host: '/',
    port: '443',
    path: '/myapp',
    secure: true
});

peer.on("open", (id) => {
    localId = id;
    socket.emit("room-joined", roomId, id);
    totalUsers.push(id);
    initSelfStream();
    //console.log('My userId: ' + id)
});

const initSelfStream = () => {
    (async () => {
        try {
            await navigator.mediaDevices.getUserMedia(
                {
                    video: {
                        facingMode: selectedCamera
                    },
                    audio: true
                }).then(stream => {
                    localStream = stream;
                    
                    const video = document.createElement("video");
                    loadAndShowVideoView(video, stream, localId);

                    socket.on('new-user-connected', id => {
                        setTimeout(function() { callUser(id, stream); }, 3000);
                        otherUserId = id;
                    });
                });
        } catch (err) {
            console.log('(async () =>: ' + err);
        }
    })();
}

const callUser = (id, stream) => {
    test1 = createRtcPeerConnection(id);
    localStream.getTracks().forEach(track => test1.addTrack(track, localStream));
}

socket.on("offer-received", (data) => {
    if(data.target == localId){
        test1 = createRtcPeerConnection();
        const desc = new RTCSessionDescription(data.sdp);
        test1.setRemoteDescription(desc).then(() => {
            localStream.getTracks().forEach(track => test1.addTrack(track, localStream));
        }).then(() => {
            return test1.createAnswer();
        }).then(answer => {
            return test1.setLocalDescription(answer);
        }).then(() => {
            const payload = {
                target: data.caller,
                caller: localId,
                sdp: test1.localDescription
            }
            socket.emit("answer", payload);
        });
    }
});
socket.on("answer-received", (data) => {
    if(data.target == localId){
        const desc = new RTCSessionDescription(data.sdp);
        test1.setRemoteDescription(desc).catch(e => console.log(e));
    }
});
socket.on("ice-candidate-message", (data) => {
    if(data.target == localId){
        if (data.candidate.candidate) {
            const payload = {
                target: otherUserId,
                candidate: data.candidate.candidate,
            }
            socket.emit("ice-candidate", payload);
        }
    }
});

const createRtcPeerConnection = (id) => {
    const rtcPeerConnection = new RTCPeerConnection({
        iceServers: [
            {
                urls: "stun:stun.stunprotocol.org"
            },
            {
                urls: 'turn:numb.viagenie.ca',
                credential: 'muazkh',
                username: 'webrtc@live.com'
            },
        ]
    });

    rtcPeerConnection.onicecandidate = handleICECandidateEvent;
    rtcPeerConnection.ontrack = handleTrackEvent;
    rtcPeerConnection.onnegotiationneeded = () => handleNegotiationNeededEvent(id);

    return rtcPeerConnection;
}

const handleICECandidateEvent = (e) => {
    if (e.candidate) {
        const payload = {
            target: otherUserId,
            candidate: e.candidate,
        }
        socket.emit("ice-candidate", payload);
    }
}
const handleTrackEvent = (e) => {
    const video = document.createElement("video");
    loadAndShowVideoView(video, e.streams[0], "Temporary Id")
}
const handleNegotiationNeededEvent = (targetUserID) => {
    test1.createOffer().then(offer => {
        return test1.setLocalDescription(offer);
    }).then(() => {
        const payload = {
            target: targetUserID,
            caller: localId,
            sdp: test1.localDescription
        };
        socket.emit("offer", payload);
    }).catch(e => console.log(e));
}

const loadAndShowVideoView = (video, stream, id) => {
    video.classList.add('video-inset', 'background-black');
    video.setAttribute("id", id);
    video.style.position = "relative"
    video.autoplay = true;
    
    video.srcObject = stream;
    video.style.height = 50+"vh"
    video.style.width = 50+"vw"
    
    video.muted = true;
    video.style.objectFit = "cover"
    
    appendVideo(video, stream, id)
}
const appendVideo = (video, stream, id) => {
    video.addEventListener("loadedmetadata", () => {
            loader.style.opacity = 0
            container.append(video);
            video.play()
            if(loader.style.visibility == "visible") {
                loader.style.display = "none";
            }
    });
}

ejs 查看文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script>
    const roomId = "<%= roomId %>"
  </script>
  <script src="peer.min.js" defer></script>
  <script src="/socket.io/socket.io.js" defer></script>
  <script src="client.js" defer></script>
</head>
<body>
    <div class="container background-black" id="loader">
        <div class="loader"></div>
    </div>
    <div class="views-container background-black" id="container"></div>
</body>
</html>

寻求帮助

【问题讨论】:

    标签: express npm webrtc peerjs


    【解决方案1】:

    好吧,我不是专业人士,但我不久前完成了我的第一个 webrtc 项目

    首先你应该检查你的浏览器控制台是否有错误

    其次,您似乎在某些部分使用了 peerjs,而在其他一些部分使用了纯 WEBRTC!我认为这行不通.....你需要选择一个

    您需要peer.on('call') 来监听其他用户连接,call.answer(stream) 为呼叫者发送您的流,而call.on('stream') 来接收呼叫者流

    是这样的

    var peer = new Peer({
        config: {'iceServers': [
                { url: 'stun:stun.l.google.com:19302' },
            ]} /* Sample servers, please use appropriate ones */
    });
    
    
    peer.on('open', function(id) {
        MY_PEER_ID = id ;
        io.emit('peer_id_offer' , {  chat_room  : ROOM , id : id}); // send your peerid to other users in the room via socket.io 
    });
    
    
    
    // call other peers when you receive their id 
    io.on('peer_id_recived' , function(data){
         callPeer(value.peer_id); // look at the function below 
    });
    
    // calling other peer when we receive their id via socket.io sending them our stream and expecting to receive theirs 
     function callPeer( id )
    {
            navigator.mediaDevices.getUserMedia({ video : true , audio : true })
            .then(  (stream) => {
    
                addOurVideo(stream);
                
                let  call = peer.call(id , stream);
                
                call.on('stream' , function(remoteStream){
                        addRemoteVideo(remoteStream);
    
                })
            })
            .catch( (e)=>{
                console.log('error1' , e );
            });
    }
    
    
    
    
    // handle reciving call from other clients in the room 
    peer.on('call' , function (call) {
    
    
        /// send your own stream for the caller and add the caller stream to your page 
        navigator.mediaDevices.getUserMedia({ video : true , audio : true })
            .then((stream) => {
                
                call.answer(stream);
                call.on('stream' , function(remoteStream){
                    
                        addRemoteVideo(remoteStream);
                })
    
            })
            .catch( (e)=>{
                console.log('error2' , e );
            });
    
    })
    

    您需要仔细检查以避免调用/添加重复的流/对等体

    这是我的代码,看看我是怎么做到的

    https://chate-test-3000.herokuapp.com/peer?room=someRomeName

    提醒一下

    var peer = new Peer({
        config: {'iceServers':  clientICE.iceServers } /* Sample servers, please use appropriate ones */
    });
    

    而不是clientICE.iceServers,我使用了一些商业转服务器

    您必须提供自己的 iceserver 并在此处替换它们

    你可以使用免费的谷歌服务

    var peer = new Peer({
        config: {'iceServers': [
                { url: 'stun:stun.l.google.com:19302' },
            ]} /* Sample servers, please use appropriate ones */
    });
    

    最终你需要使用商业转向服务器来处理更复杂的网络配置,但现在如果你的同行在同一地区,谷歌 stun 服务器可以正常工作

    【讨论】:

    • 它在网络到网络上完美运行。但是为什么不能在移动设备上工作?
    • @FelixChristo 您可以尝试查看浏览器控制台上是否有任何 js 错误(您可以搜索以查看如何在移动浏览器中执行此操作)...但我认为旧版本不支持 webrtc ios设备所以可能是这样的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 2020-06-08
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多