gpt4 book ai didi

javascript - session 、WebRTC 的点对点返工

转载 作者:数据小太阳 更新时间:2023-10-29 03:57:20 25 4
gpt4 key购买 nike

今天又要问这个问题了。

我正在处理代码以一对一连接到允许群组对话的代码。不用拐弯抹 Angular ,我有这段代码:

CallToUsers = function(connection) {
var connection = connection;
var isChannelReady;
var isInitiator = false;
var isStarted = false;
var servers = null;
var localStream = connection.getStream();
var localStreams = [];
var localConnection;
var turnReady;
var remoteStreams = [];
var remoteStream;
var pcConfig = {
'iceServers': [{
'url': 'stun:stun.l.google.com:19302'
}]
};
var pcConstraints = {
'optional': [{
'DtlsSrtpKeyAgreement': true
}]
};
var sdpConstraints = {
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
};
var room;
var socket = io.connect();
var divElement = document.createElement('div');
divElement.setAttribute('id', 'remotesVideo');
document.body.appendChild(divElement);

var createRoom = function(room) {
room = room;
if(room !== '') {
console.log('Create or join to room', room);
socket.emit('create or join', room);
}

socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
});

/*socket.on('full', function(room) {
console.log('Room' + room + ' is full');
});*/

socket.on('join', function(room) {
console.log('Another peer made request to join ' + room);
isChannelReady = true;
});

socket.on('joined', function(room) {
console.log('User joined to room ' + room);
isChannelReady = true;
});

socket.on('log', function(array) {
console.log.apply(console, array);
});
};

var sendMessage = function(message) {
console.log('Client sending a message: ', message);
socket.emit('message', message);
};

window.onbeforeunload = function(e){
sendMessage('bye');
};

var startCall = function() {
sendMessage('got user media');

if(isInitiator) {
maybeStart();
}

socket.on('message', function(message) {
console.log('Client received a message: ' + message);
if(message === 'got user media') {
maybeStart();
} else if(message.type === 'offer') {
if(!isInitiator && !isStarted) {
maybeStart();
}

for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setRemoteDescription(new RTCSessionDescription(message));
}

doAnswer();
} else if(message.type === 'answer' && isStarted) {
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setRemoteDescription(new RTCSessionDescription(message));
}
} else if(message.type === 'candidate' && isStarted) {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});

for(var i = 0; i < localStreams.length; i++) {
localStreams[i].addIceCandidate(candidate);
}
} else if(message === 'bye' && isStarted) {
handleRemoteEndCall();
}
});

//if(location.hostname != 'localhost') {
//requestTurn('https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913');
//}
};

var maybeStart = function() {
if(!isStarted && typeof localStream != 'undefined' && isChannelReady) {
createPeerConnection();
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].addStream(localStream);
}
isStarted = true;

if(isInitiator) {
doCall();
}
}
};

var createPeerConnection = function() {
try {
localConnection = new RTCPeerConnection(pcConfig, pcConstraints);
localConnection.onicecandidate = handleIceCandidate;
localConnection.onaddstream = handleRemoteStreamAdded;
localConnection.onremovestream = handleRemoteStreamRemoved;
localStreams.push(localConnection);
console.log('Created RTCPeerConnection');
} catch(e) {
console.log('exception ' + e.message);
return;
}
};

var handleIceCandidate = function(event) {
if(event.candidate) {
sendMessage({
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
} else {
console.log('End of candidates');
}
};

var handleRemoteStreamAdded = function(event) {
console.log('Remote stream added');
var newVideo = document.createElement('video');
newVideo.setAttribute('id', Math.floor((Math.random() * 1000) + 1));
newVideo.muted = false;
divElement.appendChild(newVideo);
attachMediaStream(newVideo, event.stream);
remoteStream = event.stream;
remoteStreams.push(remoteStream);
};

var handleRemoteStreamRemoved = function(event) {
console.log('Delete');
};

var handleCreateOfferError = function(event) {
console.log('createOffer() error: ' + e);
}

var setLocalAndSendMessage = function(sessionDescription) {
sessionDescription.sdp = preferOpus(sessionDescription.sdp);
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setLocalDescription(sessionDescription);
}
sendMessage(sessionDescription);
};

var doCall = function() {
console.log('Start call');
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].createOffer(setLocalAndSendMessage, handleCreateOfferError);
}
};

var doAnswer = function() {
console.log('Sending answer');
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].createAnswer(setLocalAndSendMessage, null, sdpConstraints);
}
};

var endCall = function() {
console.log('Hanging up');
isStarted = false;
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].close();
localStreams[i] = null;
}
sendMessage('bye');
};

var handleRemoteEndCall = function() {
};

var requestTurn = function(turnUrl) {
var turnExists = false;

for(var i in pcConfig.iceServers) {
if(pcConfig.iceServers[i].url.substr(0, 5) === 'turn:') {
turnExists = true;
turnReady = true;
break;
}
}

if(!turnExists) {
console.log('Getting TURN server from ', turnUrl);

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var turnServer = JSON.parse(xhr.responseText);
console.log('Got TURN server: ', turnServer);
pc_config.iceServers.push({
'url': 'turn:' + turnServer.username + '@' + turnServer.turn,
'credential': turnServer.password
});
turnReady = true;
}
};

xhr.open('GET', turnUrl, true);
xhr.send();
}
};

var preferOpus = function(sdp) {
var sdpLines = sdp.split('\r\n');
var mLineIndex;

for(var i = 0; i < sdpLines.length; i++) {
if(sdpLines[i].search('m=audio') !== -1) {
mLineIndex = i;
break;
}
}

if(mLineIndex === null) {
return sdp;
}

for(i = 0; i < sdpLines.length; i++) {
if(sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);

if(opusPayload) {
sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
}

break;
}
}

sdpLines = removeCN(sdpLines, mLineIndex);

sdp = sdpLines.join('\r\n');

return sdp;
};

var extractSdp = function(sdpLine, pattern) {
var result = sdpLine.match(pattern);

return result && result.length === 2 ? result[1] : null;
};

var setDefaultCodec = function(mLine, payload) {
var elements = mLine.split(' ');
var newLine = [];
var index = 0;

for(var i = 0; i < elements.length; i++) {
if(index === 3) {
newLine[index++] = payload;
}
if(elements[i] !== payload) {
newLine[index++] = elements[i];
}
}

return newLine.join(' ');
};

var removeCN = function(sdpLines, mLineIndex) {
var mLineElements = sdpLines[mLineIndex].split(' ');

for(var i = sdpLines.length - 1; i >= 0; i--) {
var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);

if(payload) {
var cnPos = mLineElements.indexOf(payload);

if(cnPos !== -1) {
mLineElements.splice(cnPos, 1);
}

sdpLines.splice(i, 1);
}
}

sdpLines[mLineIndex] = mLineElements.join(' ');

return sdpLines;
};

return {
startCall: startCall,
endCall: endCall,
createRoom: createRoom
};
};

虽然两个用户之间的对话运行良好,但是当添加另一个成员时,它不再连接到其他两个对等点,尽管我看到的日志很清楚地连接到同一个房间。

在控制台中,没有错误。

有没有人愿意帮忙?

@编辑

如果需要,我也会添加服务器代码:

var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2017);


var io = require('socket.io').listen(app);
io.sockets.on('connection', function (socket){

function log(){
var array = [">>> "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}

socket.on('message', function (message) {
log('Got message: ', message);
socket.broadcast.emit('message', message); // should be room only
});

socket.on('create or join', function (room) {
var numClients = io.sockets.clients(room).length;

log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room', room);

if (numClients == 0){
socket.join(room);
socket.emit('created', room);
} else {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
}
socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);

});

});

最佳答案

终于解决了问题。写作 session 的一般规则,所有同行都连接到的地方是这样的:每个新来的人都扮演回答者的 Angular 色,并在与所有向他发送报价的报价建立联系后,开始充当报价者(第一个同行除外,这始终是报价)。 @Mert Koksal,感谢您的关注。

关于javascript - session 、WebRTC 的点对点返工,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22696720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com