You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.0 KiB
157 lines
5.0 KiB
var util = require('util');
|
|
var webrtcSupport = require('webrtcsupport');
|
|
var mockconsole = require('mockconsole');
|
|
var localMedia = require('localmedia');
|
|
var Peer = require('./peer');
|
|
|
|
|
|
function WebRTC(opts) {
|
|
var self = this;
|
|
var options = opts || {};
|
|
var config = this.config = {
|
|
debug: false,
|
|
// makes the entire PC config overridable
|
|
peerConnectionConfig: {
|
|
iceServers: [{'urls': 'stun:stun.l.google.com:19302'}]
|
|
},
|
|
peerConnectionConstraints: {
|
|
optional: []
|
|
},
|
|
receiveMedia: {
|
|
offerToReceiveAudio: 1,
|
|
offerToReceiveVideo: 1
|
|
},
|
|
enableDataChannels: true
|
|
};
|
|
var item;
|
|
|
|
// We also allow a 'logger' option. It can be any object that implements
|
|
// log, warn, and error methods.
|
|
// We log nothing by default, following "the rule of silence":
|
|
// http://www.linfo.org/rule_of_silence.html
|
|
this.logger = function () {
|
|
// we assume that if you're in debug mode and you didn't
|
|
// pass in a logger, you actually want to log as much as
|
|
// possible.
|
|
if (opts.debug) {
|
|
return opts.logger || console;
|
|
} else {
|
|
// or we'll use your logger which should have its own logic
|
|
// for output. Or we'll return the no-op.
|
|
return opts.logger || mockconsole;
|
|
}
|
|
}();
|
|
|
|
// set options
|
|
for (item in options) {
|
|
if (options.hasOwnProperty(item)) {
|
|
this.config[item] = options[item];
|
|
}
|
|
}
|
|
|
|
// check for support
|
|
if (!webrtcSupport.support) {
|
|
this.logger.error('Your browser doesn\'t seem to support WebRTC');
|
|
}
|
|
|
|
// where we'll store our peer connections
|
|
this.peers = [];
|
|
|
|
// call localMedia constructor
|
|
localMedia.call(this, this.config);
|
|
|
|
this.on('speaking', function () {
|
|
if (!self.hardMuted) {
|
|
// FIXME: should use sendDirectlyToAll, but currently has different semantics wrt payload
|
|
self.peers.forEach(function (peer) {
|
|
if (peer.enableDataChannels) {
|
|
var dc = peer.getDataChannel('hark');
|
|
if (dc.readyState != 'open') return;
|
|
dc.send(JSON.stringify({type: 'speaking'}));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
this.on('stoppedSpeaking', function () {
|
|
if (!self.hardMuted) {
|
|
// FIXME: should use sendDirectlyToAll, but currently has different semantics wrt payload
|
|
self.peers.forEach(function (peer) {
|
|
if (peer.enableDataChannels) {
|
|
var dc = peer.getDataChannel('hark');
|
|
if (dc.readyState != 'open') return;
|
|
dc.send(JSON.stringify({type: 'stoppedSpeaking'}));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
this.on('volumeChange', function (volume, treshold) {
|
|
if (!self.hardMuted) {
|
|
// FIXME: should use sendDirectlyToAll, but currently has different semantics wrt payload
|
|
self.peers.forEach(function (peer) {
|
|
if (peer.enableDataChannels) {
|
|
var dc = peer.getDataChannel('hark');
|
|
if (dc.readyState != 'open') return;
|
|
dc.send(JSON.stringify({type: 'volume', volume: volume }));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// log events in debug mode
|
|
if (this.config.debug) {
|
|
this.on('*', function (event, val1, val2) {
|
|
var logger;
|
|
// if you didn't pass in a logger and you explicitly turning on debug
|
|
// we're just going to assume you're wanting log output with console
|
|
if (self.config.logger === mockconsole) {
|
|
logger = console;
|
|
} else {
|
|
logger = self.logger;
|
|
}
|
|
logger.log('event:', event, val1, val2);
|
|
});
|
|
}
|
|
}
|
|
|
|
util.inherits(WebRTC, localMedia);
|
|
|
|
WebRTC.prototype.createPeer = function (opts) {
|
|
var peer;
|
|
opts.parent = this;
|
|
peer = new Peer(opts);
|
|
this.peers.push(peer);
|
|
return peer;
|
|
};
|
|
|
|
// removes peers
|
|
WebRTC.prototype.removePeers = function (id, type) {
|
|
this.getPeers(id, type).forEach(function (peer) {
|
|
peer.end();
|
|
});
|
|
};
|
|
|
|
// fetches all Peer objects by session id and/or type
|
|
WebRTC.prototype.getPeers = function (sessionId, type) {
|
|
return this.peers.filter(function (peer) {
|
|
return (!sessionId || peer.id === sessionId) && (!type || peer.type === type);
|
|
});
|
|
};
|
|
|
|
// sends message to all
|
|
WebRTC.prototype.sendToAll = function (message, payload) {
|
|
this.peers.forEach(function (peer) {
|
|
peer.send(message, payload);
|
|
});
|
|
};
|
|
|
|
// sends message to all using a datachannel
|
|
// only sends to anyone who has an open datachannel
|
|
WebRTC.prototype.sendDirectlyToAll = function (channel, message, payload) {
|
|
this.peers.forEach(function (peer) {
|
|
if (peer.enableDataChannels) {
|
|
peer.sendDirectly(channel, message, payload);
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = WebRTC;
|
|
|