javascript - 在 WebRTC 中添加和接收曲目时遇到问题
问题描述
我正在基于此示例构建 p2p 群组视频聊天:https ://github.com/eugenp/tutorials/tree/master/webrtc
我更改了代码,为每个用户提供了一个 ID,并创建了一个字典,在其中保存了为每个对等点创建的连接(键:id,值:RTCPeerConnection)。
它的工作原理是,当用户进入房间时,他会获得所有当前连接用户的列表,然后为每个连接的用户创建连接并发送优惠。当用户得到答案时,每个用户之间建立连接。我可以使用连接发送和接收短信,但是在尝试 .addTracks() 到各个连接时没有任何反应。使用 onTrack 或 eventlistener("track") 我无法检索流。
当它是 1on1 时,我能够实现视频和音频,但在尝试建立多个连接时,它不再工作了。我认为这与报价有关,因为它们似乎缺少接收音频/视频,我尝试使用 offerToReceiveAudio:1, offerToReceiveVideo:1 但似乎并没有改善这种情况。
var conn = new WebSocket('wss://192.168.5.11:8443/socket');
const messageBox = document.getElementById('messageBox')
const videoGrid = document.getElementById('video-grid')
const myVideo = document.createElement('video')
myVideo.muted = true
var input = document.getElementById("messageInput");
let myID;
const configuration = {
"iceServers": [{
"urls": "stun:stun.l.google.com:19302"
}]
};
connections = {}
dataChannels = {}
conn.onopen = function() {
console.log("Connected to the signaling server");
};
conn.onmessage = function(msg) {
console.log("Got message", msg.data);
var content = JSON.parse(msg.data);
var data = content.data;
switch (content.event) {
//upon a new user joining we will be getting an offer from them
case "offer":
if(content.to!=myID) break;
var from = content.from;
peerConnecting(content.from);
handleOffer(data,connections[from],from);
break;
//the joined user gets answers and handles them
case "answer":
if(content.to!=myID) break;
handleAnswer(data,connections[content.from]);
break;
// when a remote peer sends an ice candidate to us
case "candidate":
if(content.to!=myID) break;
handleCandidate(data,connections[content.from]);
break;
//when a user joins he gets list of all users with the event of NEW_CONNECTION, he creates offers which are sent
// to all the users
case "NEW_CONNECTION":
peerConnecting(data);
createOffer(connections[data],data);
console.log(data);
break;
//upon joining the room we get sent our own id so we can check which messages are meant for us
case "OWN_ID":
myID=data;
break;
default:
break;
}
};
//sends message to the socket handler
function send(message) {
conn.send(JSON.stringify(message));
}
//creating new RTCPeerConnection for user with the ID
function peerConnecting(ID){
connections[ID]= new RTCPeerConnection(configuration);
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).
then(stream => {
addVideoStream(myVideo, stream)
stream.getTracks().forEach(track => connections[ID].addTrack(track,stream),console.log("track added"))
}).catch(function(err) {
/* handle the error */
});
connections[ID].onicecandidate = function(event) {
if (event.candidate) {
send({
event : "candidate",
data : event.candidate,
from : myID,
to : ID
});
}
};
dataChannels[ID] = connections[ID].createDataChannel("dataChannel",{
reliable : true
});
dataChannels[ID].onerror = function(error) {
console.log("Error occured on datachannel:", error);
};
// when we receive a message from the other peer, printing it on the console
dataChannels[ID].onmessage = function(event) {
console.log("message:", event.data);
messageBox.append("them:"+event.data);
};
dataChannels[ID].onclose = function() {
console.log("data channel is closed");
};
connections[ID].ondatachannel = function (event) {
console.log("data channel is open");
dataChannels[ID] = event.channel;
};
//addind src to remotevideo element
const remoteStream = new MediaStream();
const remoteVideo = document.querySelector('#remoteVideo');
remoteVideo.srcObject = remoteStream;
connections[ID].addEventListener('track', async (event) => {
remoteStream.addTrack(event.track);
});
}
function createOffer(peerConnection,ID) {
peerConnection.createOffer({
offerToReceiveAudio:1,
offerToReceiveVideo:1
}).then(offer => {
send({
event : "offer",
data : offer,
from : myID,
to : ID
});
peerConnection.setLocalDescription(offer);
}, function(error) {
alert("Error creating an offer");
});
}
function handleOffer(offer,peerConnection,ID) {
peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
// create and send an answer to an offer
peerConnection.createAnswer({
offerToReceiveAudio:1,
offerToReceiveVideo:1
}).then(answer=> {
peerConnection.setLocalDescription(answer);
send({
event : "answer",
data : answer,
from : myID,
to : ID
});
}, function(error) {
alert("Error creating an answer");
});
};
function handleCandidate(candidate,peerConnection) {
peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
};
function handleAnswer(answer, peerConnection) {
peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
console.log("connection established successfully!!");
};
function sendMessage() {
for (const [key, value] of Object.entries(dataChannels)) {
value.send(input.value)
}
messageBox.append("me:"+input.value);
input.value = "";
}
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}```
解决方案
推荐阅读
- python - 将数据帧的标题拖放/移动到第一行
- sql - 从地址sql查询中分离机构名称和电话
- excel - 在 VB 运行时启动后仅显示 Excel 启动画面
- javascript - 呈现 HTML 模板并使用它发送上下文,但获取响应未读取上下文并显示有关 JSON 的错误
- vb.net - Visual Studio IDE - 从我的代码中删除标题 0
- php - 具有固定位置和内联块的多重回显/打印
- r - R循环随机正态分布
- xml - 如何将价格从 WWW 导入 Google 表格
- node.js - 如何通过`process.stdout.write`在lambda中记录`DEBUG`?
- angular - “AppComponent”类型上不存在属性“app”