Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

connectionquality.bundle.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.connectionquality=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. var EventEmitter = require("events");
  3. var eventEmitter = new EventEmitter();
  4. /**
  5. * local stats
  6. * @type {{}}
  7. */
  8. var stats = {};
  9. /**
  10. * remote stats
  11. * @type {{}}
  12. */
  13. var remoteStats = {};
  14. /**
  15. * Interval for sending statistics to other participants
  16. * @type {null}
  17. */
  18. var sendIntervalId = null;
  19. /**
  20. * Start statistics sending.
  21. */
  22. function startSendingStats() {
  23. sendStats();
  24. sendIntervalId = setInterval(sendStats, 10000);
  25. }
  26. /**
  27. * Sends statistics to other participants
  28. */
  29. function sendStats() {
  30. xmpp.addToPresence("connectionQuality", convertToMUCStats(stats));
  31. }
  32. /**
  33. * Converts statistics to format for sending through XMPP
  34. * @param stats the statistics
  35. * @returns {{bitrate_donwload: *, bitrate_uplpoad: *, packetLoss_total: *, packetLoss_download: *, packetLoss_upload: *}}
  36. */
  37. function convertToMUCStats(stats) {
  38. return {
  39. "bitrate_download": stats.bitrate.download,
  40. "bitrate_upload": stats.bitrate.upload,
  41. "packetLoss_total": stats.packetLoss.total,
  42. "packetLoss_download": stats.packetLoss.download,
  43. "packetLoss_upload": stats.packetLoss.upload
  44. };
  45. }
  46. /**
  47. * Converts statitistics to format used by VideoLayout
  48. * @param stats
  49. * @returns {{bitrate: {download: *, upload: *}, packetLoss: {total: *, download: *, upload: *}}}
  50. */
  51. function parseMUCStats(stats) {
  52. return {
  53. bitrate: {
  54. download: stats.bitrate_download,
  55. upload: stats.bitrate_upload
  56. },
  57. packetLoss: {
  58. total: stats.packetLoss_total,
  59. download: stats.packetLoss_download,
  60. upload: stats.packetLoss_upload
  61. }
  62. };
  63. }
  64. var ConnectionQuality = {
  65. init: function () {
  66. xmpp.addListener(XMPPEvents.REMOTE_STATS, this.updateRemoteStats);
  67. statistics.addConnectionStatsListener(this.updateLocalStats);
  68. statistics.addRemoteStatsStopListener(this.stopSendingStats);
  69. },
  70. /**
  71. * Updates the local statistics
  72. * @param data new statistics
  73. */
  74. updateLocalStats: function (data) {
  75. stats = data;
  76. eventEmitter.emit(CQEvents.LOCALSTATS_UPDATED, 100 - stats.packetLoss.total, stats);
  77. if (sendIntervalId == null) {
  78. startSendingStats();
  79. }
  80. },
  81. /**
  82. * Updates remote statistics
  83. * @param jid the jid associated with the statistics
  84. * @param data the statistics
  85. */
  86. updateRemoteStats: function (jid, data) {
  87. if (data == null || data.packetLoss_total == null) {
  88. eventEmitter.emit(CQEvents.REMOTESTATS_UPDATED, jid, null, null);
  89. return;
  90. }
  91. remoteStats[jid] = parseMUCStats(data);
  92. eventEmitter.emit(CQEvents.REMOTESTATS_UPDATED,
  93. jid, 100 - data.packetLoss_total, remoteStats[jid]);
  94. },
  95. /**
  96. * Stops statistics sending.
  97. */
  98. stopSendingStats: function () {
  99. clearInterval(sendIntervalId);
  100. sendIntervalId = null;
  101. //notify UI about stopping statistics gathering
  102. eventEmitter.emit(CQEvents.STOP);
  103. },
  104. /**
  105. * Returns the local statistics.
  106. */
  107. getStats: function () {
  108. return stats;
  109. },
  110. addListener: function (type, listener) {
  111. eventEmitter.on(type, listener);
  112. }
  113. };
  114. module.exports = ConnectionQuality;
  115. },{"events":2}],2:[function(require,module,exports){
  116. // Copyright Joyent, Inc. and other Node contributors.
  117. //
  118. // Permission is hereby granted, free of charge, to any person obtaining a
  119. // copy of this software and associated documentation files (the
  120. // "Software"), to deal in the Software without restriction, including
  121. // without limitation the rights to use, copy, modify, merge, publish,
  122. // distribute, sublicense, and/or sell copies of the Software, and to permit
  123. // persons to whom the Software is furnished to do so, subject to the
  124. // following conditions:
  125. //
  126. // The above copyright notice and this permission notice shall be included
  127. // in all copies or substantial portions of the Software.
  128. //
  129. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  130. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  131. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  132. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  133. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  134. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  135. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  136. function EventEmitter() {
  137. this._events = this._events || {};
  138. this._maxListeners = this._maxListeners || undefined;
  139. }
  140. module.exports = EventEmitter;
  141. // Backwards-compat with node 0.10.x
  142. EventEmitter.EventEmitter = EventEmitter;
  143. EventEmitter.prototype._events = undefined;
  144. EventEmitter.prototype._maxListeners = undefined;
  145. // By default EventEmitters will print a warning if more than 10 listeners are
  146. // added to it. This is a useful default which helps finding memory leaks.
  147. EventEmitter.defaultMaxListeners = 10;
  148. // Obviously not all Emitters should be limited to 10. This function allows
  149. // that to be increased. Set to zero for unlimited.
  150. EventEmitter.prototype.setMaxListeners = function(n) {
  151. if (!isNumber(n) || n < 0 || isNaN(n))
  152. throw TypeError('n must be a positive number');
  153. this._maxListeners = n;
  154. return this;
  155. };
  156. EventEmitter.prototype.emit = function(type) {
  157. var er, handler, len, args, i, listeners;
  158. if (!this._events)
  159. this._events = {};
  160. // If there is no 'error' event listener then throw.
  161. if (type === 'error') {
  162. if (!this._events.error ||
  163. (isObject(this._events.error) && !this._events.error.length)) {
  164. er = arguments[1];
  165. if (er instanceof Error) {
  166. throw er; // Unhandled 'error' event
  167. }
  168. throw TypeError('Uncaught, unspecified "error" event.');
  169. }
  170. }
  171. handler = this._events[type];
  172. if (isUndefined(handler))
  173. return false;
  174. if (isFunction(handler)) {
  175. switch (arguments.length) {
  176. // fast cases
  177. case 1:
  178. handler.call(this);
  179. break;
  180. case 2:
  181. handler.call(this, arguments[1]);
  182. break;
  183. case 3:
  184. handler.call(this, arguments[1], arguments[2]);
  185. break;
  186. // slower
  187. default:
  188. len = arguments.length;
  189. args = new Array(len - 1);
  190. for (i = 1; i < len; i++)
  191. args[i - 1] = arguments[i];
  192. handler.apply(this, args);
  193. }
  194. } else if (isObject(handler)) {
  195. len = arguments.length;
  196. args = new Array(len - 1);
  197. for (i = 1; i < len; i++)
  198. args[i - 1] = arguments[i];
  199. listeners = handler.slice();
  200. len = listeners.length;
  201. for (i = 0; i < len; i++)
  202. listeners[i].apply(this, args);
  203. }
  204. return true;
  205. };
  206. EventEmitter.prototype.addListener = function(type, listener) {
  207. var m;
  208. if (!isFunction(listener))
  209. throw TypeError('listener must be a function');
  210. if (!this._events)
  211. this._events = {};
  212. // To avoid recursion in the case that type === "newListener"! Before
  213. // adding it to the listeners, first emit "newListener".
  214. if (this._events.newListener)
  215. this.emit('newListener', type,
  216. isFunction(listener.listener) ?
  217. listener.listener : listener);
  218. if (!this._events[type])
  219. // Optimize the case of one listener. Don't need the extra array object.
  220. this._events[type] = listener;
  221. else if (isObject(this._events[type]))
  222. // If we've already got an array, just append.
  223. this._events[type].push(listener);
  224. else
  225. // Adding the second element, need to change to array.
  226. this._events[type] = [this._events[type], listener];
  227. // Check for listener leak
  228. if (isObject(this._events[type]) && !this._events[type].warned) {
  229. var m;
  230. if (!isUndefined(this._maxListeners)) {
  231. m = this._maxListeners;
  232. } else {
  233. m = EventEmitter.defaultMaxListeners;
  234. }
  235. if (m && m > 0 && this._events[type].length > m) {
  236. this._events[type].warned = true;
  237. console.error('(node) warning: possible EventEmitter memory ' +
  238. 'leak detected. %d listeners added. ' +
  239. 'Use emitter.setMaxListeners() to increase limit.',
  240. this._events[type].length);
  241. if (typeof console.trace === 'function') {
  242. // not supported in IE 10
  243. console.trace();
  244. }
  245. }
  246. }
  247. return this;
  248. };
  249. EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  250. EventEmitter.prototype.once = function(type, listener) {
  251. if (!isFunction(listener))
  252. throw TypeError('listener must be a function');
  253. var fired = false;
  254. function g() {
  255. this.removeListener(type, g);
  256. if (!fired) {
  257. fired = true;
  258. listener.apply(this, arguments);
  259. }
  260. }
  261. g.listener = listener;
  262. this.on(type, g);
  263. return this;
  264. };
  265. // emits a 'removeListener' event iff the listener was removed
  266. EventEmitter.prototype.removeListener = function(type, listener) {
  267. var list, position, length, i;
  268. if (!isFunction(listener))
  269. throw TypeError('listener must be a function');
  270. if (!this._events || !this._events[type])
  271. return this;
  272. list = this._events[type];
  273. length = list.length;
  274. position = -1;
  275. if (list === listener ||
  276. (isFunction(list.listener) && list.listener === listener)) {
  277. delete this._events[type];
  278. if (this._events.removeListener)
  279. this.emit('removeListener', type, listener);
  280. } else if (isObject(list)) {
  281. for (i = length; i-- > 0;) {
  282. if (list[i] === listener ||
  283. (list[i].listener && list[i].listener === listener)) {
  284. position = i;
  285. break;
  286. }
  287. }
  288. if (position < 0)
  289. return this;
  290. if (list.length === 1) {
  291. list.length = 0;
  292. delete this._events[type];
  293. } else {
  294. list.splice(position, 1);
  295. }
  296. if (this._events.removeListener)
  297. this.emit('removeListener', type, listener);
  298. }
  299. return this;
  300. };
  301. EventEmitter.prototype.removeAllListeners = function(type) {
  302. var key, listeners;
  303. if (!this._events)
  304. return this;
  305. // not listening for removeListener, no need to emit
  306. if (!this._events.removeListener) {
  307. if (arguments.length === 0)
  308. this._events = {};
  309. else if (this._events[type])
  310. delete this._events[type];
  311. return this;
  312. }
  313. // emit removeListener for all listeners on all events
  314. if (arguments.length === 0) {
  315. for (key in this._events) {
  316. if (key === 'removeListener') continue;
  317. this.removeAllListeners(key);
  318. }
  319. this.removeAllListeners('removeListener');
  320. this._events = {};
  321. return this;
  322. }
  323. listeners = this._events[type];
  324. if (isFunction(listeners)) {
  325. this.removeListener(type, listeners);
  326. } else {
  327. // LIFO order
  328. while (listeners.length)
  329. this.removeListener(type, listeners[listeners.length - 1]);
  330. }
  331. delete this._events[type];
  332. return this;
  333. };
  334. EventEmitter.prototype.listeners = function(type) {
  335. var ret;
  336. if (!this._events || !this._events[type])
  337. ret = [];
  338. else if (isFunction(this._events[type]))
  339. ret = [this._events[type]];
  340. else
  341. ret = this._events[type].slice();
  342. return ret;
  343. };
  344. EventEmitter.listenerCount = function(emitter, type) {
  345. var ret;
  346. if (!emitter._events || !emitter._events[type])
  347. ret = 0;
  348. else if (isFunction(emitter._events[type]))
  349. ret = 1;
  350. else
  351. ret = emitter._events[type].length;
  352. return ret;
  353. };
  354. function isFunction(arg) {
  355. return typeof arg === 'function';
  356. }
  357. function isNumber(arg) {
  358. return typeof arg === 'number';
  359. }
  360. function isObject(arg) {
  361. return typeof arg === 'object' && arg !== null;
  362. }
  363. function isUndefined(arg) {
  364. return arg === void 0;
  365. }
  366. },{}]},{},[1])(1)
  367. });