我在WebRTC和WebSockets上处理多用户视频聊天。当2个用户连接一切正常时,但当第三个用户连接第一个视频消失时,第一个和第三个用户之间的新视频建立。
错误:
"调用错误状态:STATE_INPROGRESS"
和
"处理ICE候选人"
请告知我做错了什么。提前谢谢!
这是我的代码:
var peerConnections = {};
var mainStream;
var currentId;
navigator.getUserMedia(
{ audio: true, video: true },
gotStream,
function(error) { console.log(error) }
);
function getPeerConnection(id) {
// return connection if available
if (peerConnections[id]) {
return peerConnections[id];
}
// create new connection else
var pc = new RTCPeerConnection(null);
peerConnections[id] = pc;
pc.addStream(mainStream);
pc.onicecandidate = function (event) {
console.log('on ice candidate', event);
if (event.candidate) {
sendMessage({
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate,
by: currentId,
to: id
});
}
};
pc.onaddstream = function(evt) {
var elements = document.querySelectorAll('.remoteVideo2');
// when stream arrives loop through containers and add video
for(var i =0; i < elements.length; i++) {
console.log('element[i].src', elements[i].src);
if(!elements[i].src){
elements[i].src = URL.createObjectURL(evt.stream);
break;
}
}
};
return pc;
}
// add local video
function gotStream(stream) {
mainStream = stream;
document.getElementById("localVideo").src = URL.createObjectURL(stream);
}
function createOffer(userId) {
var pc = getPeerConnection(userId);
pc.createOffer(
function(description){
pc.setLocalDescription(description);
socket.emit('message', description);
},
function(error) { console.log(error) },
);
}
function createAnswer(userId) {
var pc = getPeerConnection(userId);
pc.createAnswer(
function(description){
pc.setLocalDescription(description);
socket.emit('message', description);
},
function(error) { console.log(error) },
{ 'mandatory': { 'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true } }
);
}
////////////////////////////////////////////////
// Socket.io
var socket = io.connect('https://my.webrtc.server:8888');
window.room = prompt("Enter room name:");
if (room !== "") {
socket.emit('create or join', room);
}
function sendMessage(message) {
socket.emit('message', message);
}
socket.on('message', function (data) {
handleMessage(data);
});
// handling all type of messages
function handleMessage(message) {
var pc = getPeerConnection(message.id);
if (message.type === 'offer') {
pc.setRemoteDescription(new SessionDescription(message), function() {
createAnswer(message.id);
});
}
else if (message.type === 'answer') {
pc.setRemoteDescription(new SessionDescription(message), function() {
});
}
else if (message.type === 'candidate') {
var candidate = new IceCandidate({sdpMLineIndex: message.label, candidate: message.candidate});
pc.addIceCandidate(candidate, function(){console.log('candidate is ok')}, function(e){console.log('error candidate', e)});
}
}
// creating new offer on new peer connected to the room
socket.on('peer.connected', function (data) {
createOffer(data.id);
});
这是服务器端:
var socketIO = require('socket.io'),
module.exports = function (server, config) {
var io = socketIO.listen(server);
var rooms = {};
io.sockets.on('connection', function (client) {
client.resources = {
screen: false,
video: true,
audio: false
};
// pass a message to another id
client.on('message', function (details) {
details.id = client.id;
client.broadcast.emit('message', details);
if (!details) return;
});
// Create or join here
client.on('create or join', function(room) {
if(room){
if(!rooms[room]){
rooms[room] = [client];
} else {
rooms[room].push(client);
}
}
rooms[room].forEach(function(sock){
sock.emit('peer.connected', {id: client.id});
});
});
};