diff --git a/video-client/SignalExchangerClient.js b/video-client/SignalExchangerClient.js new file mode 100644 index 0000000..341fa62 --- /dev/null +++ b/video-client/SignalExchangerClient.js @@ -0,0 +1,203 @@ +/** + * Signal exchanger web client + * + * @author Pierre HUBERT + */ + +class SignalExchangerClient { + + /** + * Server domain + * + * @type {String} + */ + //domain; + + /** + * Server port + * + * @type {Number} + */ + //port; + + /** + * Current client ID + * + * @type {String} + */ + //clientID; + + /** + * Socket connection to the server + * + * @type {WebSocket} + */ + //socket; + + /** + * Function called in case of error + * + * @type {Function} + */ + //onError = null; + + /** + * Function called when the connection is etablished + * + * @type {Function} + */ + //onConnected = null; + + /** + * Function called when the connection to the socket is closed + * + * @type {Function} + */ + //onClosed = null; + + /** + * Function called when we get a new signal information + * + * @type {Function} + */ + //onSignal = null; + + /** + * Construct a client instance + * + * @param {String} domain The name of the signal server + * @param {Number} port The port of the server to use + * @param {String} clientID The ID of current client + */ + constructor(domain, port, clientID) { + + //Save information + this.domain = domain, + this.port = port; + this.clientID = clientID; + + this.socket = new WebSocket("ws://" + this.domain + ":" + this.port + "/socket"); + + //Add a few events listeners + this.socket.addEventListener("open", () => { + this.serverConnected(); + + if(this.onConnected != null) + setTimeout(this.onConnected, 10); + }); + + this.socket.addEventListener("message", message => { + + let data; + try { + data = JSON.parse(message.data); + } catch(e){ + console.error("Could not parse message from server!"); + return; + } + + console.log("New message from socket", data); + + this.serverMessage(data); + }); + + this.socket.addEventListener("error", () => { + if(this.onError != null) + setTimeout(this.onError, 0); + }); + + this.socket.addEventListener("close", () => { + if(this.onClosed != null) + setTimeout(this.onClosed, 0); + }); + } + + /** + * Method called once the client is successfully + * connected to the client + */ + serverConnected(){ + + //Send data to the server to identificate client + this.sendData({ + client_id: this.clientID + }); + + } + + /** + * Send a signal to the server + * + * @param target_id The ID of the target for the signal + * @param content Signal to send to the target + */ + sendSignal(target_id, content){ + + //Send directly the message to the server + this.sendData({ + signal: content, + target_id: target_id + }); + + //Save the current signal being sent to be able to send + //it again in case of failure + this.pending_signal = content; + this.pending_signal_target = target_id; + } + + /** + * Stop to try to send the current signal message in queue + * + * This does not cancel the sending of messages already sent through + * socket + */ + cancelCurrentSignal() { + this.pending_signal = undefined; + this.pending_signal_target = undefined; + } + + /** + * Send data to the server + * + * @param {Object} data The data to send to the server + */ + sendData(data){ + console.log("Sending data to server", data); + this.socket.send(JSON.stringify(data)); + } + + /** + * This method is called when the server has sent a new message to this client + * + * @param {Object} message The message sent by the server, as a JSON object + */ + serverMessage(message){ + + //Check if it is a callback for a pending message + if(message.signal_sent){ + if(message.number_of_targets < 1 && this.pending_signal && this.pending_signal_target){ + + //We have to send the message again + setTimeout(() => { + this.sendSignal(this.pending_signal, this.pending_signal_target); + }, 1000); + + } + + else { + + //Else we can remove from this class information about the signal being sent + this.cancelCurrentSignal(); + + } + } + + // Check if the message is a signal + else if(message.signal){ + if(this.onSignal != null) + this.onSignal(message.signal, message.source_id); + } + + + } +} \ No newline at end of file diff --git a/video-client/server.py b/video-client/server.py new file mode 100755 index 0000000..a36f522 --- /dev/null +++ b/video-client/server.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python +import SimpleHTTPServer +SimpleHTTPServer.test(); \ No newline at end of file diff --git a/video-client/simplepeer.min.js b/video-client/simplepeer.min.js new file mode 100644 index 0000000..bb0fa8e --- /dev/null +++ b/video-client/simplepeer.min.js @@ -0,0 +1,11 @@ +(function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"==typeof window?"undefined"==typeof global?"undefined"==typeof self?this:self:global:window,t.SimplePeer=e()}})(function(){var t=Math.floor,n=Math.abs,r=Math.pow;return function(){function s(d,e,n){function t(o,i){if(!e[o]){if(!d[o]){var l="function"==typeof require&&require;if(!i&&l)return l(o,!0);if(r)return r(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var a=e[o]={exports:{}};d[o][0].call(a.exports,function(e){var r=d[o][1][e];return t(r||e)},a,a.exports,s,d,e,n)}return e[o].exports}for(var r="function"==typeof require&&require,o=0;o>16,d[l++]=255&t>>8,d[l++]=255&t;return 2===s&&(t=p[e.charCodeAt(u)]<<2|p[e.charCodeAt(u+1)]>>4,d[l++]=255&t),1===s&&(t=p[e.charCodeAt(u)]<<10|p[e.charCodeAt(u+1)]<<4|p[e.charCodeAt(u+2)]>>2,d[l++]=255&t>>8,d[l++]=255&t),d}function s(e){return c[63&e>>18]+c[63&e>>12]+c[63&e>>6]+c[63&e]}function d(e,t,n){for(var r,o=[],a=t;al?l:s+a));return 1===r?(t=e[n-1],o.push(c[t>>2]+c[63&t<<4]+"==")):2===r&&(t=(e[n-2]<<8)+e[n-1],o.push(c[t>>10]+c[63&t>>4]+c[63&t<<2]+"=")),o.join("")}n.byteLength=function(e){var t=r(e),n=t[0],o=t[1];return 3*(n+o)/4-o},n.toByteArray=a,n.fromByteArray=l;for(var c=[],p=[],f="undefined"==typeof Uint8Array?Array:Uint8Array,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g=0,h=u.length;g + * @license MIT + */"use strict";var $=String.fromCharCode,J=Math.min;function o(e){if(2147483647e)throw new RangeError("The value \""+e+"\" is invalid for option \"size\"")}function c(e,t,n){return l(e),0>=e?o(e):void 0===t?o(e):"string"==typeof n?o(e).fill(t,n):o(e).fill(t)}function p(e){return l(e),o(0>e?0:0|m(e))}function f(e,t){if(("string"!=typeof t||""===t)&&(t="utf8"),!s.isEncoding(t))throw new TypeError("Unknown encoding: "+t);var n=0|_(e,t),r=o(n),a=r.write(e,t);return a!==n&&(r=r.slice(0,a)),r}function u(e){for(var t=0>e.length?0:0|m(e.length),n=o(t),r=0;rt||e.byteLength=2147483647)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+2147483647 .toString(16)+" bytes");return 0|e}function _(e,t){if(s.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Y(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError("The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type "+typeof e);var n=e.length,r=2>>1;case"base64":return V(e).length;default:if(o)return r?-1:q(e).length;t=(""+t).toLowerCase(),o=!0;}}function b(e,t,n){var r=!1;if((void 0===t||0>t)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),0>=n)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return F(this,t,n);case"utf8":case"utf-8":return A(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return B(this,t,n);case"base64":return E(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0;}}function y(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function C(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647n&&(n=-2147483648),n=+n,X(n)&&(n=o?0:e.length-1),0>n&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(0>n)if(o)n=0;else return-1;if("string"==typeof t&&(t=s.from(t,r)),s.isBuffer(t))return 0===t.length?-1:w(e,t,n,r,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):w(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function w(e,t,n,r,o){function a(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}var s=1,d=e.length,l=t.length;if(void 0!==r&&(r=(r+"").toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(2>e.length||2>t.length)return-1;s=2,d/=2,l/=2,n/=2}var c;if(o){var p=-1;for(c=n;cd&&(n=d-l),c=n;0<=c;c--){for(var f=!0,u=0;uo&&(r=o)):r=o;var a=t.length;r>a/2&&(r=a/2);for(var s,d=0;da&&(s=a):2===d?(l=e[o+1],128==(192&l)&&(f=(31&a)<<6|63&l,127f||57343f&&(s=f))):void 0}null===s?(s=65533,d=1):65535>>10),s=56320|1023&s),r.push(s),o+=d}return L(r)}function L(e){var t=e.length;if(t<=4096)return $.apply(String,e);for(var n="",r=0;rt)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var o="",a=t;ae)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function D(e,t,n,r,o,a){if(!s.isBuffer(e))throw new TypeError("\"buffer\" argument must be a Buffer instance");if(t>o||te.length)throw new RangeError("Index out of range")}function P(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(0>n)throw new RangeError("Index out of range")}function O(e,t,n,r,o){return t=+t,n>>>=0,o||P(e,t,n,4,34028234663852886e22,-34028234663852886e22),Z.write(e,t,n,r,23,4),n+4}function j(e,t,n,r,o){return t=+t,n>>>=0,o||P(e,t,n,8,17976931348623157e292,-17976931348623157e292),Z.write(e,t,n,r,52,8),n+8}function U(e){if(e=e.split("=")[0],e=e.trim().replace(Q,""),2>e.length)return"";for(;0!=e.length%4;)e+="=";return e}function W(e){return 16>e?"0"+e.toString(16):e.toString(16)}function q(e,t){t=t||1/0;for(var n,r=e.length,o=null,a=[],s=0;sn){if(!o){if(56319n){-1<(t-=3)&&a.push(239,191,189),o=n;continue}n=(o-55296<<10|n-56320)+65536}else o&&-1<(t-=3)&&a.push(239,191,189);if(o=null,128>n){if(0>(t-=1))break;a.push(n)}else if(2048>n){if(0>(t-=2))break;a.push(192|n>>6,128|63&n)}else if(65536>n){if(0>(t-=3))break;a.push(224|n>>12,128|63&n>>6,128|63&n)}else if(1114112>n){if(0>(t-=4))break;a.push(240|n>>18,128|63&n>>12,128|63&n>>6,128|63&n)}else throw new Error("Invalid code point")}return a}function H(e){for(var t=[],n=0;n(t-=2));++s)n=e.charCodeAt(s),r=n>>8,o=n%256,a.push(o),a.push(r);return a}function V(e){return K.toByteArray(U(e))}function G(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}function Y(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function X(e){return e!==e}var K=e("base64-js"),Z=e("ieee754");n.Buffer=s,n.SlowBuffer=function(e){return+e!=e&&(e=0),s.alloc(+e)},n.INSPECT_MAX_BYTES=50;n.kMaxLength=2147483647,s.TYPED_ARRAY_SUPPORT=function(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()}catch(t){return!1}}(),s.TYPED_ARRAY_SUPPORT||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(s.prototype,"parent",{enumerable:!0,get:function(){return s.isBuffer(this)?this.buffer:void 0}}),Object.defineProperty(s.prototype,"offset",{enumerable:!0,get:function(){return s.isBuffer(this)?this.byteOffset:void 0}}),"undefined"!=typeof Symbol&&null!=Symbol.species&&s[Symbol.species]===s&&Object.defineProperty(s,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),s.poolSize=8192,s.from=function(e,t,n){return d(e,t,n)},s.prototype.__proto__=Uint8Array.prototype,s.__proto__=Uint8Array,s.alloc=function(e,t,n){return c(e,t,n)},s.allocUnsafe=function(e){return p(e)},s.allocUnsafeSlow=function(e){return p(e)},s.isBuffer=function(e){return null!=e&&!0===e._isBuffer&&e!==s.prototype},s.compare=function(e,t){if(Y(e,Uint8Array)&&(e=s.from(e,e.offset,e.byteLength)),Y(t,Uint8Array)&&(t=s.from(t,t.offset,t.byteLength)),!s.isBuffer(e)||!s.isBuffer(t))throw new TypeError("The \"buf1\", \"buf2\" arguments must be one of type Buffer or Uint8Array");if(e===t)return 0;for(var n=e.length,r=t.length,o=0,d=J(n,r);ot&&(e+=" ... "),""},s.prototype.compare=function(e,t,n,r,o){if(Y(e,Uint8Array)&&(e=s.from(e,e.offset,e.byteLength)),!s.isBuffer(e))throw new TypeError("The \"target\" argument must be one of type Buffer or Uint8Array. Received type "+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),0>t||n>e.length||0>r||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,o>>>=0,this===e)return 0;for(var a=o-r,d=n-t,l=J(a,d),c=this.slice(r,o),p=e.slice(t,n),f=0;f>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0);else throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");var o=this.length-t;if((void 0===n||n>o)&&(n=o),0n||0>t)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return S(this,e,t,n);case"utf8":case"utf-8":return v(this,e,t,n);case"ascii":return k(this,e,t,n);case"latin1":case"binary":return T(this,e,t,n);case"base64":return R(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0;}},s.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};s.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),t>>=0,t>>>=0,n||M(e,t,this.length);for(var r=this[e],o=1,a=0;++a>>=0,t>>>=0,n||M(e,t,this.length);for(var r=this[e+--t],o=1;0>>=0,t||M(e,1,this.length),this[e]},s.prototype.readUInt16LE=function(e,t){return e>>>=0,t||M(e,2,this.length),this[e]|this[e+1]<<8},s.prototype.readUInt16BE=function(e,t){return e>>>=0,t||M(e,2,this.length),this[e]<<8|this[e+1]},s.prototype.readUInt32LE=function(e,t){return e>>>=0,t||M(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},s.prototype.readUInt32BE=function(e,t){return e>>>=0,t||M(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},s.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||M(e,t,this.length);for(var o=this[e],a=1,s=0;++s=a&&(o-=r(2,8*t)),o},s.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||M(e,t,this.length);for(var o=t,a=1,s=this[e+--o];0=a&&(s-=r(2,8*t)),s},s.prototype.readInt8=function(e,t){return e>>>=0,t||M(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},s.prototype.readInt16LE=function(e,t){e>>>=0,t||M(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},s.prototype.readInt16BE=function(e,t){e>>>=0,t||M(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},s.prototype.readInt32LE=function(e,t){return e>>>=0,t||M(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},s.prototype.readInt32BE=function(e,t){return e>>>=0,t||M(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},s.prototype.readFloatLE=function(e,t){return e>>>=0,t||M(e,4,this.length),Z.read(this,e,!0,23,4)},s.prototype.readFloatBE=function(e,t){return e>>>=0,t||M(e,4,this.length),Z.read(this,e,!1,23,4)},s.prototype.readDoubleLE=function(e,t){return e>>>=0,t||M(e,8,this.length),Z.read(this,e,!0,52,8)},s.prototype.readDoubleBE=function(e,t){return e>>>=0,t||M(e,8,this.length),Z.read(this,e,!1,52,8)},s.prototype.writeUIntLE=function(e,t,n,o){if(e=+e,t>>>=0,n>>>=0,!o){var a=r(2,8*n)-1;D(this,e,t,n,a,0)}var s=1,d=0;for(this[t]=255&e;++d>>=0,n>>>=0,!o){var a=r(2,8*n)-1;D(this,e,t,n,a,0)}var s=n-1,d=1;for(this[t+s]=255&e;0<=--s&&(d*=256);)this[t+s]=255&e/d;return t+n},s.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,1,255,0),this[t]=255&e,t+1},s.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},s.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},s.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},s.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},s.prototype.writeIntLE=function(e,t,n,o){if(e=+e,t>>>=0,!o){var a=r(2,8*n-1);D(this,e,t,n,a-1,-a)}var s=0,d=1,l=0;for(this[t]=255&e;++se&&0===l&&0!==this[t+s-1]&&(l=1),this[t+s]=255&(e/d>>0)-l;return t+n},s.prototype.writeIntBE=function(e,t,n,o){if(e=+e,t>>>=0,!o){var a=r(2,8*n-1);D(this,e,t,n,a-1,-a)}var s=n-1,d=1,l=0;for(this[t+s]=255&e;0<=--s&&(d*=256);)0>e&&0===l&&0!==this[t+s+1]&&(l=1),this[t+s]=255&(e/d>>0)-l;return t+n},s.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,1,127,-128),0>e&&(e=255+e+1),this[t]=255&e,t+1},s.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},s.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},s.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},s.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},s.prototype.writeFloatLE=function(e,t,n){return O(this,e,t,!0,n)},s.prototype.writeFloatBE=function(e,t,n){return O(this,e,t,!1,n)},s.prototype.writeDoubleLE=function(e,t,n){return j(this,e,t,!0,n)},s.prototype.writeDoubleBE=function(e,t,n){return j(this,e,t,!1,n)},s.prototype.copy=function(e,t,n,r){if(!s.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),0t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("Index out of range");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-to||"latin1"===r)&&(e=o)}}else"number"==typeof e&&(e&=255);if(0>t||this.length>>=0,n=n===void 0?this.length:n>>>0,e||(e=0);var a;if("number"==typeof e)for(a=t;aa)){s.warned=!0;var d=new Error("Possible EventEmitter memory leak detected. "+s.length+" \""+(t+"\" listeners added. Use emitter.setMaxListeners() to increase limit."));d.name="MaxListenersExceededWarning",d.emitter=e,d.type=t,d.count=s.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",d.name,d.message)}return e}function f(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var e=Array(arguments.length),t=0;te||e!==e)throw new TypeError("\"defaultMaxListeners\" must be a positive number");v=e}}):n.defaultMaxListeners=v,n.prototype.setMaxListeners=function(e){if("number"!=typeof e||0>e||isNaN(e))throw new TypeError("\"n\" argument must be a positive number");return this._maxListeners=e,this},n.prototype.getMaxListeners=function(){return r(this)},n.prototype.emit=function(e){var t,n,r,o,p,f,u="error"===e;if(f=this._events,f)u=u&&null==f.error;else if(!u)return!1;if(u){if(1o)return this;0===o?n.shift():m(n,o),1===n.length&&(r[e]=n[0]),r.removeListener&&this.emit("removeListener",e,s||t)}return this},n.prototype.removeAllListeners=function(e){var t,n,r;if(n=this._events,!n)return this;if(!n.removeListener)return 0===arguments.length?(this._events=y(null),this._eventsCount=0):n[e]&&(0==--this._eventsCount?this._events=y(null):delete n[e]),this;if(0===arguments.length){var o,a=C(n);for(r=0;r{"%%"===e||(r++,"%c"===e&&(o=r))}),e.splice(o,0,n)},n.save=function(e){try{e?n.storage.setItem("debug",e):n.storage.removeItem("debug")}catch(e){}},n.load=a,n.useColors=function(){return!!("undefined"!=typeof window&&window.process&&("renderer"===window.process.type||window.process.__nwjs))||!("undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&31<=parseInt(RegExp.$1,10)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},n.storage=function(){try{return localStorage}catch(e){}}(),n.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.exports=e("./common")(n);const{formatters:i}=t.exports;i.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}).call(this,e("_process"))},{"./common":7,_process:15}],7:[function(e,t){t.exports=function(t){function r(e){let t=0;for(let n=0;n{if("%%"===t)return t;s++;const a=o.formatters[n];if("function"==typeof a){const n=e[s];t=a.call(r,n),e.splice(s,1),s--}return t}),o.formatArgs.call(r,e);const d=r.log||o.log;d.apply(r,e)}let n;return t.namespace=e,t.enabled=o.enabled(e),t.useColors=o.useColors(),t.color=r(e),t.destroy=a,t.extend=i,"function"==typeof o.init&&o.init(t),o.instances.push(t),t}function a(){const e=o.instances.indexOf(this);return-1!==e&&(o.instances.splice(e,1),!0)}function i(e,t){return o(this.namespace+("undefined"==typeof t?":":t)+e)}function s(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return o.debug=o,o.default=o,o.coerce=function(e){return e instanceof Error?e.stack||e.message:e},o.disable=function(){const e=[...o.names.map(s),...o.skips.map(s).map(e=>"-"+e)].join(",");return o.enable(""),e},o.enable=function(e){o.save(e),o.names=[],o.skips=[];let t;const n=("string"==typeof e?e:"").split(/[\s,]+/),r=n.length;for(t=0;t{o[e]=t[e]}),o.instances=[],o.names=[],o.skips=[],o.formatters={},o.selectColor=r,o.enable(o.load()),o}},{ms:13}],8:[function(e,t){t.exports=function(){if("undefined"==typeof window)return null;var e={RTCPeerConnection:window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection,RTCSessionDescription:window.RTCSessionDescription||window.mozRTCSessionDescription||window.webkitRTCSessionDescription,RTCIceCandidate:window.RTCIceCandidate||window.mozRTCIceCandidate||window.webkitRTCIceCandidate};return e.RTCPeerConnection?e:null}},{}],9:[function(e,o,a){a.read=function(t,n,o,a,l){var c,p,f=8*l-a-1,u=(1<>1,h=-7,_=o?l-1:0,b=o?-1:1,d=t[n+_];for(_+=b,c=d&(1<<-h)-1,d>>=-h,h+=f;0>=-h,h+=a;0>1,v=23===f?r(2,-24)-r(2,-77):0,k=p?0:u-1,T=p?1:-1,d=0>a||0===a&&0>1/a?1:0;for(a=n(a),isNaN(a)||a===1/0?(b=isNaN(a)?1:0,_=w):(_=t(h(a)/g),1>a*(y=r(2,-_))&&(_--,y*=2),a+=1<=_+S?v/y:v*r(2,1-S),2<=a*y&&(_++,y/=2),_+S>=w?(b=0,_=w):1<=_+S?(b=(a*y-1)*r(2,f),_+=S):(b=a*r(2,S-1)*r(2,f),_=0));8<=f;o[l+k]=255&b,k+=T,b/=256,f-=8);for(_=_< + * @license MIT + */t.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},{}],12:[function(e,t){var n={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},{}],13:[function(e,t){var s=Math.round;function r(e){if(e+="",!(100=1.5*r?"s":"")}var l=24*(60*60000);t.exports=function(e,t){t=t||{};var n=typeof e;if("string"==n&&0>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function h(e,t){return 0>=e||0===t.length&&t.ended?0:t.objectMode?1:e===e?(e>t.highWaterMark&&(t.highWaterMark=g(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0)):t.flowing&&t.length?t.buffer.head.data.length:t.length}function m(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,_(e)}}function _(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(H("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?F.nextTick(b,e):b(e))}function b(e){H("emit readable"),e.emit("readable"),T(e)}function y(e,t){t.readingMore||(t.readingMore=!0,F.nextTick(C,e,t))}function C(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=x(e,t.buffer,t.decoder),n}function x(e,t,n){var r;return ei.length?i.length:e;if(a+=s===i.length?i:i.slice(0,e),e-=s,0===e){s===i.length?(++o,t.head=r.next?r.next:t.tail=null):(t.head=r,r.data=i.slice(s));break}++o}return t.length-=o,a}function A(e,t){var r=j.allocUnsafe(e),o=t.head,a=1;for(o.data.copy(r),e-=o.data.length;o=o.next;){var i=o.data,s=e>i.length?i.length:e;if(i.copy(r,r.length-e,0,s),e-=s,0===e){s===i.length?(++a,t.head=o.next?o.next:t.tail=null):(t.head=o,o.data=i.slice(s));break}++a}return t.length-=a,r}function L(e){var t=e._readableState;if(0=t.highWaterMark||t.ended))return H("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?L(this):_(this),null;if(e=h(e,t),0===e&&t.ended)return 0===t.length&&L(this),null;var o=t.needReadable;H("need readable",o),(0===t.length||t.length-e>>0),n=this.head,a=0;n;)r(n.data,t,a),a+=n.data.length,n=n.next;return t},e}(),a&&a.inspect&&a.inspect.custom&&(t.exports.prototype[a.inspect.custom]=function(){var e=a.inspect({length:this.length});return this.constructor.name+" "+e})},{"safe-buffer":26,util:2}],23:[function(e,t){"use strict";function n(e,t){e.emit("error",t)}var r=e("process-nextick-args");t.exports={destroy:function(e,t){var o=this,a=this._readableState&&this._readableState.destroyed,i=this._writableState&&this._writableState.destroyed;return a||i?(t?t(e):e&&(!this._writableState||!this._writableState.errorEmitted)&&r.nextTick(n,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(n,o,e),o._writableState&&(o._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},{"process-nextick-args":14}],24:[function(e,t){t.exports=e("events").EventEmitter},{events:4}],25:[function(e,t,n){n=t.exports=e("./lib/_stream_readable.js"),n.Stream=n,n.Readable=n,n.Writable=e("./lib/_stream_writable.js"),n.Duplex=e("./lib/_stream_duplex.js"),n.Transform=e("./lib/_stream_transform.js"),n.PassThrough=e("./lib/_stream_passthrough.js")},{"./lib/_stream_duplex.js":17,"./lib/_stream_passthrough.js":18,"./lib/_stream_readable.js":19,"./lib/_stream_transform.js":20,"./lib/_stream_writable.js":21}],26:[function(e,t,n){function r(e,t){for(var n in e)t[n]=e[n]}function o(e,t,n){return i(e,t,n)}var a=e("buffer"),i=a.Buffer;i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?t.exports=a:(r(a,n),n.Buffer=o),r(i,o),o.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return i(e,t,n)},o.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=i(e);return void 0===t?r.fill(0):"string"==typeof n?r.fill(t,n):r.fill(t),r},o.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return i(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return a.SlowBuffer(e)}},{buffer:3}],27:[function(e,t,n){"use strict";function r(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0;}}function o(e){var t=r(e);if("string"!=typeof t&&(_.isEncoding===b||!b(e)))throw new Error("Unknown encoding: "+e);return t||e}function a(e){this.encoding=o(e);var t;switch(this.encoding){case"utf16le":this.text=p,this.end=f,t=4;break;case"utf8":this.fillLast=c,t=4;break;case"base64":this.text=u,this.end=g,t=3;break;default:return this.write=h,void(this.end=m);}this.lastNeed=0,this.lastTotal=0,this.lastChar=_.allocUnsafe(t)}function s(e){if(127>=e)return 0;return 6==e>>5?2:14==e>>4?3:30==e>>3?4:2==e>>6?-1:-2}function d(e,t,n){var r=t.length-1;if(r=r)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function f(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function u(e,t){var r=(e.length-t)%3;return 0==r?e.toString("base64",t):(this.lastNeed=3-r,this.lastTotal=3,1==r?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-r))}function g(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function m(e){return e&&e.length?this.write(e):""}var _=e("safe-buffer").Buffer,b=_.isEncoding||function(e){switch(e=""+e,e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1;}};n.StringDecoder=a,a.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(t=this.fillLast(e),void 0===t)return"";n=this.lastNeed,this.lastNeed=0}else n=0;return narguments.length)&&s.call(arguments,1);return d[t]=!0,a(function(){d[t]&&(r?e.apply(null,r):e.call(null),n.clearImmediate(t))}),t},n.clearImmediate="function"==typeof r?r:function(e){delete d[e]}}).call(this,e("timers").setImmediate,e("timers").clearImmediate)},{"process/browser.js":15,timers:28}],29:[function(e,t){(function(e){function n(t){try{if(!e.localStorage)return!1}catch(e){return!1}var n=e.localStorage[t];return null!=n&&"true"===(n+"").toLowerCase()}t.exports=function(e,t){function r(){if(!o){if(n("throwDeprecation"))throw new Error(t);else n("traceDeprecation")?console.trace(t):console.warn(t);o=!0}return e.apply(this,arguments)}if(n("noDeprecation"))return e;var o=!1;return r}}).call(this,"undefined"==typeof global?"undefined"==typeof self?"undefined"==typeof window?{}:window:self:global)},{}],"/":[function(e,t){(function(n){function r(e){var t=this;if(!(t instanceof r))return new r(e);if(t._id=p(4).toString("hex").slice(0,7),t._debug("new peer %o",e),e=Object.assign({allowHalfOpen:!1},e),f.Duplex.call(t,e),t.channelName=e.initiator?e.channelName||p(20).toString("hex"):null,t._isChromium="undefined"!=typeof window&&!!window.webkitRTCPeerConnection,t.initiator=e.initiator||!1,t.channelConfig=e.channelConfig||r.channelConfig,t.config=e.config||r.config,t.constraints=t._transformConstraints(e.constraints||r.constraints),t.offerConstraints=t._transformConstraints(e.offerConstraints||{}),t.answerConstraints=t._transformConstraints(e.answerConstraints||{}),t.sdpTransform=e.sdpTransform||function(e){return e},t.streams=e.streams||(e.stream?[e.stream]:[]),t.trickle=void 0===e.trickle||e.trickle,t.allowHalfTrickle=void 0!==e.allowHalfTrickle&&e.allowHalfTrickle,t.iceCompleteTimeout=e.iceCompleteTimeout||5000,t.destroyed=!1,t.connected=!1,t.remoteAddress=void 0,t.remoteFamily=void 0,t.remotePort=void 0,t.localAddress=void 0,t.localPort=void 0,t._wrtc=e.wrtc&&"object"==typeof e.wrtc?e.wrtc:l(),!t._wrtc)if("undefined"==typeof window)throw i("No WebRTC support: Specify `opts.wrtc` option in this environment","ERR_WEBRTC_SUPPORT");else throw i("No WebRTC support: Not a supported browser","ERR_WEBRTC_SUPPORT");t._pcReady=!1,t._channelReady=!1,t._iceComplete=!1,t._iceCompleteTimer=null,t._channel=null,t._pendingCandidates=[],t._isNegotiating=!t.initiator,t._batchedNegotiation=!1,t._queuedNegotiation=!1,t._sendersAwaitingStable=[],t._senderMap=new WeakMap,t._firstStable=!0,t._closingInterval=null,t._remoteTracks=[],t._remoteStreams=[],t._chunk=null,t._cb=null,t._interval=null,t._pc=new t._wrtc.RTCPeerConnection(t.config,t.constraints),(t._isChromium||t._wrtc&&t._wrtc.electronDaemon)&&o(t._wrtc.RTCPeerConnection,t._pc),t._isReactNativeWebrtc="number"==typeof t._pc._peerConnectionId,t._pc.oniceconnectionstatechange=function(){t._onIceStateChange()},t._pc.onicegatheringstatechange=function(){t._onIceStateChange()},t._pc.onsignalingstatechange=function(){t._onSignalingStateChange()},t._pc.onicecandidate=function(e){t._onIceCandidate(e)},t.initiator?t._setupData({channel:t._pc.createDataChannel(t.channelName,t.channelConfig)}):t._pc.ondatachannel=function(e){t._setupData(e)},"addTrack"in t._pc&&(t.streams&&t.streams.forEach(function(e){t.addStream(e)}),t._pc.ontrack=function(e){t._onTrack(e)}),t.initiator&&t._needsNegotiation(),t._onFinishBound=function(){t._onFinish()},t.once("finish",t._onFinishBound)}function o(e,t){t.createOffer=function(t){return new Promise((n,r)=>{e.prototype.createOffer.call(this,n,r,t)})},t.createAnswer=function(t){return new Promise((n,r)=>{e.prototype.createAnswer.call(this,n,r,t)})},t.setLocalDescription=function(t){return new Promise((n,r)=>{e.prototype.setLocalDescription.call(this,t,n,r)})},t.setRemoteDescription=function(t){return new Promise((n,r)=>{e.prototype.setRemoteDescription.call(this,t,n,r)})}}function a(e){return e.replace(/a=ice-options:trickle\s\n/g,"")}function i(e,t){var n=new Error(e);return n.code=t,n}function s(){}t.exports=r;var d=e("debug")("simple-peer"),l=e("get-browser-rtc"),c=e("inherits"),p=e("randombytes"),f=e("readable-stream"),u=65536;c(r,f.Duplex),r.WEBRTC_SUPPORT=!!l(),r.config={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:global.stun.twilio.com:3478?transport=udp"}]},r.constraints={},r.channelConfig={},Object.defineProperty(r.prototype,"bufferSize",{get:function(){var e=this;return e._channel&&e._channel.bufferedAmount||0}}),r.prototype.address=function(){var e=this;return{port:e.localPort,family:"IPv4",address:e.localAddress}},r.prototype.signal=function(e){var t=this;if(t.destroyed)throw i("cannot signal after peer is destroyed","ERR_SIGNALING");if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e={}}t._debug("signal()"),e.renegotiate&&t.initiator&&(t._debug("got request to renegotiate"),t._needsNegotiation()),e.candidate&&(t._pc.remoteDescription&&t._pc.remoteDescription.type?t._addIceCandidate(e.candidate):t._pendingCandidates.push(e.candidate)),e.sdp&&t._pc.setRemoteDescription(new t._wrtc.RTCSessionDescription(e)).then(function(){t.destroyed||(t._pendingCandidates.forEach(function(e){t._addIceCandidate(e)}),t._pendingCandidates=[],"offer"===t._pc.remoteDescription.type&&t._createAnswer())}).catch(function(e){t.destroy(i(e,"ERR_SET_REMOTE_DESCRIPTION"))}),e.sdp||e.candidate||e.renegotiate||t.destroy(i("signal() called with invalid signal data","ERR_SIGNALING"))},r.prototype._addIceCandidate=function(e){var t=this;try{t._pc.addIceCandidate(new t._wrtc.RTCIceCandidate(e),s,function(e){t.destroy(i(e,"ERR_ADD_ICE_CANDIDATE"))})}catch(e){t.destroy(i("error adding candidate: "+e.message,"ERR_ADD_ICE_CANDIDATE"))}},r.prototype.send=function(e){var t=this;t._channel.send(e)},r.prototype.addStream=function(e){var t=this;t._debug("addStream()"),e.getTracks().forEach(function(n){t.addTrack(n,e)})},r.prototype.addTrack=function(e,t){var n=this;n._debug("addTrack()");var r=n._pc.addTrack(e,t),o=n._senderMap.get(e)||new WeakMap;o.set(t,r),n._senderMap.set(e,o),n._needsNegotiation()},r.prototype.replaceTrack=async function(e,t,n){var r=this;r._debug("replaceTrack()");var o=r._senderMap.get(e),a=o?o.get(n):null;a||r.destroy(new Error("Cannot replace track that was never added.")),t&&r._senderMap.set(t,o),null==a.replaceTrack?r.destroy(i("replaceTrack is not supported in this browser","ERR_UNSUPPORTED_REPLACETRACK")):await a.replaceTrack(t)},r.prototype.removeTrack=function(e,t){var n=this;n._debug("removeSender()");var r=n._senderMap.get(e),o=r?r.get(t):null;o||n.destroy(new Error("Cannot remove track that was never added."));try{n._pc.removeTrack(o)}catch(e){"NS_ERROR_UNEXPECTED"===e.name?n._sendersAwaitingStable.push(o):n.destroy(e)}},r.prototype.removeStream=function(e){var t=this;t._debug("removeSenders()"),e.getTracks().forEach(function(n){t.removeTrack(n,e)})},r.prototype._needsNegotiation=function(){var e=this;e._debug("_needsNegotiation"),e._batchedNegotiation||(e._batchedNegotiation=!0,setTimeout(function(){e._batchedNegotiation=!1,e._debug("starting batched negotiation"),e.negotiate()},0))},r.prototype.negotiate=function(){var e=this;e.initiator?e._isNegotiating?(e._queuedNegotiation=!0,e._debug("already negotiating, queueing")):(e._debug("start negotiation"),e._createOffer()):!e._isNegotiating&&(e._debug("requesting negotiation from initiator"),e.emit("signal",{renegotiate:!0})),e._isNegotiating=!0},r.prototype.destroy=function(e){var t=this;t._destroy(e,function(){})},r.prototype._destroy=function(e,t){var n=this;if(!n.destroyed){if(n._debug("destroy (error: %s)",e&&(e.message||e)),n.readable=n.writable=!1,n._readableState.ended||n.push(null),n._writableState.finished||n.end(),n.destroyed=!0,n.connected=!1,n._pcReady=!1,n._channelReady=!1,n._remoteTracks=null,n._remoteStreams=null,n._senderMap=null,clearInterval(n._closingInterval),n._closingInterval=null,clearInterval(n._interval),n._interval=null,n._chunk=null,n._cb=null,n._onFinishBound&&n.removeListener("finish",n._onFinishBound),n._onFinishBound=null,n._channel){try{n._channel.close()}catch(e){}n._channel.onmessage=null,n._channel.onopen=null,n._channel.onclose=null,n._channel.onerror=null}if(n._pc){try{n._pc.close()}catch(e){}n._pc.oniceconnectionstatechange=null,n._pc.onicegatheringstatechange=null,n._pc.onsignalingstatechange=null,n._pc.onicecandidate=null,"addTrack"in n._pc&&(n._pc.ontrack=null),n._pc.ondatachannel=null}n._pc=null,n._channel=null,e&&n.emit("error",e),n.emit("close"),t()}},r.prototype._setupData=function(e){var t=this;if(!e.channel)return t.destroy(i("Data channel event is missing `channel` property","ERR_DATA_CHANNEL"));t._channel=e.channel,t._channel.binaryType="arraybuffer","number"==typeof t._channel.bufferedAmountLowThreshold&&(t._channel.bufferedAmountLowThreshold=u),t.channelName=t._channel.label,t._channel.onmessage=function(e){t._onChannelMessage(e)},t._channel.onbufferedamountlow=function(){t._onChannelBufferedAmountLow()},t._channel.onopen=function(){t._onChannelOpen()},t._channel.onclose=function(){t._onChannelClose()},t._channel.onerror=function(e){t.destroy(i(e,"ERR_DATA_CHANNEL"))};var n=!1;t._closingInterval=setInterval(function(){t._channel&&"closing"===t._channel.readyState?(n&&t._onChannelClose(),n=!0):n=!1},5000)},r.prototype._read=function(){},r.prototype._write=function(e,t,n){var r=this;if(r.destroyed)return n(i("cannot write after peer is destroyed","ERR_DATA_CHANNEL"));if(r.connected){try{r.send(e)}catch(e){return r.destroy(i(e,"ERR_DATA_CHANNEL"))}r._channel.bufferedAmount>u?(r._debug("start backpressure: bufferedAmount %d",r._channel.bufferedAmount),r._cb=n):n(null)}else r._debug("write before connect"),r._chunk=e,r._cb=n},r.prototype._onFinish=function(){function e(){setTimeout(function(){t.destroy()},1e3)}var t=this;t.destroyed||(t.connected?e():t.once("connect",e))},r.prototype._startIceCompleteTimeout=function(){d("started iceComplete timeout");var e=this;e.destroyed||e._iceCompleteTimer||(e._iceCompleteTimer=setTimeout(function(){e._iceComplete||(e._iceComplete=!0,e.emit("iceTimeout"),e.emit("_iceComplete"))},this.iceCompleteTimeout))},r.prototype._createOffer=function(){var e=this;e.destroyed||e._pc.createOffer(e.offerConstraints).then(function(t){function n(){if(!e.destroyed){var n=e._pc.localDescription||t;e._debug("signal"),e.emit("signal",{type:n.type,sdp:n.sdp})}}e.destroyed||(!e.trickle&&!e.allowHalfTrickle&&(t.sdp=a(t.sdp)),t.sdp=e.sdpTransform(t.sdp),e._pc.setLocalDescription(t).then(function(){e._debug("createOffer success"),e.destroyed||(e.trickle||e._iceComplete?n():e.once("_iceComplete",n))}).catch(function(t){e.destroy(i(t,"ERR_SET_LOCAL_DESCRIPTION"))}))}).catch(function(t){e.destroy(i(t,"ERR_CREATE_OFFER"))})},r.prototype._createAnswer=function(){var e=this;e.destroyed||e._pc.createAnswer(e.answerConstraints).then(function(t){function n(){if(!e.destroyed){var n=e._pc.localDescription||t;e._debug("signal"),e.emit("signal",{type:n.type,sdp:n.sdp})}}e.destroyed||(!e.trickle&&!e.allowHalfTrickle&&(t.sdp=a(t.sdp)),t.sdp=e.sdpTransform(t.sdp),e._pc.setLocalDescription(t).then(function(){e.destroyed||(e.trickle||e._iceComplete?n():e.once("_iceComplete",n))}).catch(function(t){e.destroy(i(t,"ERR_SET_LOCAL_DESCRIPTION"))}))}).catch(function(t){e.destroy(i(t,"ERR_CREATE_ANSWER"))})},r.prototype._onIceStateChange=function(){var e=this;if(!e.destroyed){var t=e._pc.iceConnectionState,n=e._pc.iceGatheringState;e._debug("iceStateChange (connection: %s) (gathering: %s)",t,n),e.emit("iceStateChange",t,n),("connected"===t||"completed"===t)&&(e._pcReady=!0,e._maybeReady()),"failed"===t&&e.destroy(i("Ice connection failed.","ERR_ICE_CONNECTION_FAILURE")),"closed"===t&&e.destroy(new Error("Ice connection closed."))}},r.prototype.getStats=function(e){var t=this;0===t._pc.getStats.length?t._pc.getStats().then(function(t){var n=[];t.forEach(function(e){n.push(e)}),e(null,n)},function(t){e(t)}):t._isReactNativeWebrtc?t._pc.getStats(null,function(t){var n=[];t.forEach(function(e){n.push(e)}),e(null,n)},function(t){e(t)}):0u)&&e._onChannelBufferedAmountLow()},r.prototype._onSignalingStateChange=function(){var e=this;e.destroyed||("stable"===e._pc.signalingState&&!e._firstStable&&(e._isNegotiating=!1,e._debug("flushing sender queue",e._sendersAwaitingStable),e._sendersAwaitingStable.forEach(function(t){e._pc.removeTrack(t),e._queuedNegotiation=!0}),e._sendersAwaitingStable=[],e._queuedNegotiation&&(e._debug("flushing negotiation queue"),e._queuedNegotiation=!1,e._needsNegotiation()),e._debug("negotiate"),e.emit("negotiate")),e._firstStable=!1,e._debug("signalingStateChange %s",e._pc.signalingState),e.emit("signalingStateChange",e._pc.signalingState))},r.prototype._onIceCandidate=function(e){var t=this;t.destroyed||(e.candidate&&t.trickle?t.emit("signal",{candidate:{candidate:e.candidate.candidate,sdpMLineIndex:e.candidate.sdpMLineIndex,sdpMid:e.candidate.sdpMid}}):!e.candidate&&!t._iceComplete&&(t._iceComplete=!0,t.emit("_iceComplete")),e.candidate&&t._startIceCompleteTimeout())},r.prototype._onChannelMessage=function(e){var t=this;if(!t.destroyed){var r=e.data;r instanceof ArrayBuffer&&(r=n.from(r)),t.push(r)}},r.prototype._onChannelBufferedAmountLow=function(){var e=this;if(!e.destroyed&&e._cb){e._debug("ending backpressure: bufferedAmount %d",e._channel.bufferedAmount);var t=e._cb;e._cb=null,t(null)}},r.prototype._onChannelOpen=function(){var e=this;e.connected||e.destroyed||(e._debug("on channel open"),e._channelReady=!0,e._maybeReady())},r.prototype._onChannelClose=function(){var e=this;e.destroyed||(e._debug("on channel close"),e.destroy())},r.prototype._onTrack=function(e){var t=this;t.destroyed||e.streams.forEach(function(n){t._debug("on track"),t.emit("track",e.track,n),t._remoteTracks.push({track:e.track,stream:n}),t._remoteStreams.some(function(e){return e.id===n.id})||(t._remoteStreams.push(n),setTimeout(function(){t.emit("stream",n)},0))})},r.prototype.setConstraints=function(e){var t=this;t.initiator?t.offerConstraints=t._transformConstraints(e):t.answerConstraints=t._transformConstraints(e)},r.prototype._debug=function(){var e=this,t=[].slice.call(arguments);t[0]="["+e._id+"] "+t[0],d.apply(null,t)},r.prototype._transformConstraints=function(e){var t=this;if(0===Object.keys(e).length)return e;if((e.mandatory||e.optional)&&!t._isChromium){var n=Object.assign({},e.optional,e.mandatory);return void 0!==n.OfferToReceiveVideo&&(n.offerToReceiveVideo=n.OfferToReceiveVideo,delete n.OfferToReceiveVideo),void 0!==n.OfferToReceiveAudio&&(n.offerToReceiveAudio=n.OfferToReceiveAudio,delete n.OfferToReceiveAudio),n}return e.mandatory||e.optional||!t._isChromium?e:(void 0!==e.offerToReceiveVideo&&(e.OfferToReceiveVideo=e.offerToReceiveVideo,delete e.offerToReceiveVideo),void 0!==e.offerToReceiveAudio&&(e.OfferToReceiveAudio=e.offerToReceiveAudio,delete e.offerToReceiveAudio),{mandatory:e})}}).call(this,e("buffer").Buffer)},{buffer:3,debug:6,"get-browser-rtc":8,inherits:10,randombytes:16,"readable-stream":25}]},{},[])("/")}); \ No newline at end of file diff --git a/video-client/test-video-client.html b/video-client/test-video-client.html new file mode 100644 index 0000000..b6b7eda --- /dev/null +++ b/video-client/test-video-client.html @@ -0,0 +1,28 @@ + + + + + + + Signal Exchanger Video test client + + + + +

Signal Exchanger test video client

+ + + + + + + + + + \ No newline at end of file diff --git a/video-client/test-video-client.js b/video-client/test-video-client.js new file mode 100644 index 0000000..231c38a --- /dev/null +++ b/video-client/test-video-client.js @@ -0,0 +1,114 @@ +/** + * Node Signal Exchanger test client + * + * @author Pierre HUBERT + */ + +function byId(id){ + return document.getElementById(id); +} + +const Config = { + port: 8081, + server_name: "localhost", + clientID: location.href.toString().includes("#1") ? "client-1" : "client-2", + otherPeerID: location.href.toString().includes("#1") ? "client-2" : "client-1" +}; + +let client = new SignalExchangerClient( + Config.server_name, + Config.port, + Config.clientID +); + +let peer; +let localStream; + +client.onConnected = function(){ + console.log("Connected to signal exchanger server."); + + InitializeVideo(); +} + +client.onError = function() { + console.error("An error occurred with the connection to the signal exchanger server"); +} + +client.onClosed = function() { + console.log("Connection to server closed."); +} + +client.onSignal = function(signal, peerID){ + + if(peerID !== Config.otherPeerID) + return alert("A signal from an unknow peer ID has just been received!"); + + peer.signal(JSON.parse(signal)); + + +} + +function InitializeVideo(){ + + navigator.mediaDevices + .getUserMedia({ + audio: true, + video: true + }) + .then(stream => { + localStream = stream; + + InitializePeer(); + + //Play local video + let video = byId("localVideo"); + video.srcObject = stream; + video.play(); + }) + .catch(err => { + alert("Can not continue because you did not accept to share your camera!"); + console.error(err); + }); + +} + +/** + * Initialize peer connection + * + * Warning : It is better to wait for the socket connection to be ready before + * launching this function if this peer is the initiator of the connection + */ +function InitializePeer() { + + peer = new SimplePeer({ + initiator: location.hash === '#1', + stream: localStream, + trickle: false, + config: { + 'iceServers': [ + { urls: 'stun:127.0.0.1:3478' }, + {"url":"turn:127.0.0.1:3478", + "credential":"anonymous", + "username": "anonymous"} + ] + } + }); + + peer.on('error', function (err) { console.log('SimplePeer error', err) }); + + //Automatically send new signals to the other peer + peer.on('signal', function (data) { + console.log('SIGNAL', JSON.stringify(data)) + client.sendSignal(Config.otherPeerID, JSON.stringify(data)); + }); + + peer.on("stream", stream => { + let video = byId("remoteVideo"); + video.srcObject = stream; + video.play(); + }); + + peer.on("message", message => { + console.log("Message from remote peer: " + message); + }); +} \ No newline at end of file