【发布时间】: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>
寻求帮助
【问题讨论】: