123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- 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;
|