@webex/plugin-meetings 3.7.0-wxcc.1 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/dist/annotation/annotation.types.d.ts +42 -0
  2. package/dist/annotation/constants.d.ts +31 -0
  3. package/dist/annotation/index.d.ts +117 -0
  4. package/dist/breakouts/breakout.d.ts +8 -0
  5. package/dist/breakouts/breakout.js +1 -1
  6. package/dist/breakouts/collection.d.ts +5 -0
  7. package/dist/breakouts/edit-lock-error.d.ts +15 -0
  8. package/dist/breakouts/events.d.ts +8 -0
  9. package/dist/breakouts/index.d.ts +5 -0
  10. package/dist/breakouts/index.js +1 -1
  11. package/dist/breakouts/request.d.ts +22 -0
  12. package/dist/breakouts/utils.d.ts +15 -0
  13. package/dist/common/browser-detection.d.ts +9 -0
  14. package/dist/common/collection.d.ts +48 -0
  15. package/dist/common/config.d.ts +2 -0
  16. package/dist/common/errors/captcha-error.d.ts +15 -0
  17. package/dist/common/errors/intent-to-join.d.ts +16 -0
  18. package/dist/common/errors/join-meeting.d.ts +17 -0
  19. package/dist/common/errors/media.d.ts +15 -0
  20. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  21. package/dist/common/errors/parameter.d.ts +15 -0
  22. package/dist/common/errors/password-error.d.ts +15 -0
  23. package/dist/common/errors/permission.d.ts +14 -0
  24. package/dist/common/errors/reclaim-host-role-error.js +149 -0
  25. package/dist/common/errors/reclaim-host-role-error.js.map +1 -0
  26. package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
  27. package/dist/common/errors/reconnection-in-progress.d.ts +9 -0
  28. package/dist/common/errors/reconnection-in-progress.js +33 -0
  29. package/dist/common/errors/reconnection-in-progress.js.map +1 -0
  30. package/dist/common/errors/reconnection.d.ts +15 -0
  31. package/dist/common/errors/stats.d.ts +15 -0
  32. package/dist/common/errors/webex-errors.d.ts +93 -0
  33. package/dist/common/errors/webex-meetings-error.d.ts +20 -0
  34. package/dist/common/events/events-scope.d.ts +17 -0
  35. package/dist/common/events/events.d.ts +12 -0
  36. package/dist/common/events/trigger-proxy.d.ts +2 -0
  37. package/dist/common/events/util.d.ts +2 -0
  38. package/dist/common/logs/logger-config.d.ts +2 -0
  39. package/dist/common/logs/logger-proxy.d.ts +2 -0
  40. package/dist/common/logs/request.d.ts +36 -0
  41. package/dist/common/queue.d.ts +34 -0
  42. package/dist/config.d.ts +72 -0
  43. package/dist/constants.d.ts +1088 -0
  44. package/dist/constants.js +15 -3
  45. package/dist/constants.js.map +1 -1
  46. package/dist/controls-options-manager/constants.d.ts +4 -0
  47. package/dist/controls-options-manager/enums.d.ts +15 -0
  48. package/dist/controls-options-manager/index.d.ts +136 -0
  49. package/dist/controls-options-manager/types.d.ts +43 -0
  50. package/dist/controls-options-manager/util.d.ts +1 -0
  51. package/dist/index.d.ts +7 -0
  52. package/dist/interceptors/index.d.ts +2 -0
  53. package/dist/interceptors/locusRetry.d.ts +27 -0
  54. package/dist/interpretation/collection.d.ts +5 -0
  55. package/dist/interpretation/index.d.ts +5 -0
  56. package/dist/interpretation/index.js +1 -1
  57. package/dist/interpretation/siLanguage.d.ts +5 -0
  58. package/dist/interpretation/siLanguage.js +1 -1
  59. package/dist/locus-info/controlsUtils.d.ts +2 -0
  60. package/dist/locus-info/embeddedAppsUtils.d.ts +2 -0
  61. package/dist/locus-info/fullState.d.ts +2 -0
  62. package/dist/locus-info/hostUtils.d.ts +2 -0
  63. package/dist/locus-info/index.d.ts +322 -0
  64. package/dist/locus-info/infoUtils.d.ts +2 -0
  65. package/dist/locus-info/mediaSharesUtils.d.ts +2 -0
  66. package/dist/locus-info/parser.d.ts +272 -0
  67. package/dist/locus-info/selfUtils.d.ts +2 -0
  68. package/dist/locus-info/selfUtils.js +5 -0
  69. package/dist/locus-info/selfUtils.js.map +1 -1
  70. package/dist/media/MediaConnectionAwaiter.js +1 -0
  71. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  72. package/dist/media/index.d.ts +34 -0
  73. package/dist/media/properties.d.ts +93 -0
  74. package/dist/media/properties.js +30 -16
  75. package/dist/media/properties.js.map +1 -1
  76. package/dist/media/util.d.ts +2 -0
  77. package/dist/mediaQualityMetrics/config.d.ts +241 -0
  78. package/dist/mediaQualityMetrics/config.js +502 -0
  79. package/dist/mediaQualityMetrics/config.js.map +1 -0
  80. package/dist/meeting/brbState.js +167 -0
  81. package/dist/meeting/brbState.js.map +1 -0
  82. package/dist/meeting/effectsState.js +260 -0
  83. package/dist/meeting/effectsState.js.map +1 -0
  84. package/dist/meeting/in-meeting-actions.d.ts +167 -0
  85. package/dist/meeting/index.d.ts +1825 -0
  86. package/dist/meeting/index.js +363 -295
  87. package/dist/meeting/index.js.map +1 -1
  88. package/dist/meeting/locusMediaRequest.d.ts +74 -0
  89. package/dist/meeting/muteState.d.ts +178 -0
  90. package/dist/meeting/muteState.js +1 -6
  91. package/dist/meeting/muteState.js.map +1 -1
  92. package/dist/meeting/request.d.ts +295 -0
  93. package/dist/meeting/request.type.d.ts +11 -0
  94. package/dist/meeting/state.d.ts +9 -0
  95. package/dist/meeting/util.d.ts +119 -0
  96. package/dist/meeting/voicea-meeting.d.ts +16 -0
  97. package/dist/meeting-info/collection.d.ts +20 -0
  98. package/dist/meeting-info/index.d.ts +69 -0
  99. package/dist/meeting-info/meeting-info-v2.d.ts +123 -0
  100. package/dist/meeting-info/meeting-info-v2.js +19 -12
  101. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  102. package/dist/meeting-info/request.d.ts +22 -0
  103. package/dist/meeting-info/util.d.ts +2 -0
  104. package/dist/meeting-info/utilv2.d.ts +2 -0
  105. package/dist/meeting-info/utilv2.js +5 -1
  106. package/dist/meeting-info/utilv2.js.map +1 -1
  107. package/dist/meetings/collection.d.ts +40 -0
  108. package/dist/meetings/index.d.ts +390 -0
  109. package/dist/meetings/meetings.types.d.ts +4 -0
  110. package/dist/meetings/request.d.ts +27 -0
  111. package/dist/meetings/util.d.ts +18 -0
  112. package/dist/member/index.d.ts +160 -0
  113. package/dist/member/member.types.js +17 -0
  114. package/dist/member/member.types.js.map +1 -0
  115. package/dist/member/types.d.ts +32 -0
  116. package/dist/member/util.d.ts +2 -0
  117. package/dist/members/collection.d.ts +29 -0
  118. package/dist/members/index.d.ts +353 -0
  119. package/dist/members/request.d.ts +114 -0
  120. package/dist/members/types.d.ts +25 -0
  121. package/dist/members/util.d.ts +215 -0
  122. package/dist/metrics/config.js +276 -0
  123. package/dist/metrics/config.js.map +1 -0
  124. package/dist/metrics/constants.d.ts +70 -0
  125. package/dist/metrics/constants.js +2 -0
  126. package/dist/metrics/constants.js.map +1 -1
  127. package/dist/metrics/index.d.ts +45 -0
  128. package/dist/multistream/mediaRequestManager.d.ts +119 -0
  129. package/dist/multistream/receiveSlot.d.ts +68 -0
  130. package/dist/multistream/receiveSlotManager.d.ts +56 -0
  131. package/dist/multistream/remoteMedia.d.ts +72 -0
  132. package/dist/multistream/remoteMediaGroup.d.ts +49 -0
  133. package/dist/multistream/remoteMediaManager.d.ts +300 -0
  134. package/dist/multistream/sendSlotManager.d.ts +69 -0
  135. package/dist/networkQualityMonitor/index.d.ts +70 -0
  136. package/dist/networkQualityMonitor/index.js +221 -0
  137. package/dist/networkQualityMonitor/index.js.map +1 -0
  138. package/dist/peer-connection-manager/index.js +671 -0
  139. package/dist/peer-connection-manager/index.js.map +1 -0
  140. package/dist/peer-connection-manager/util.js +109 -0
  141. package/dist/peer-connection-manager/util.js.map +1 -0
  142. package/dist/personal-meeting-room/index.d.ts +47 -0
  143. package/dist/personal-meeting-room/request.d.ts +14 -0
  144. package/dist/personal-meeting-room/util.d.ts +2 -0
  145. package/dist/reachability/clusterReachability.d.ts +109 -0
  146. package/dist/reachability/index.d.ts +105 -0
  147. package/dist/reachability/index.js +31 -3
  148. package/dist/reachability/index.js.map +1 -1
  149. package/dist/reachability/request.d.ts +39 -0
  150. package/dist/reachability/util.d.ts +8 -0
  151. package/dist/reactions/constants.d.ts +3 -0
  152. package/dist/reactions/reactions.d.ts +4 -0
  153. package/dist/reactions/reactions.type.d.ts +52 -0
  154. package/dist/reconnection-manager/index.d.ts +136 -0
  155. package/dist/recording-controller/enums.d.ts +7 -0
  156. package/dist/recording-controller/index.d.ts +207 -0
  157. package/dist/recording-controller/util.d.ts +14 -0
  158. package/dist/roap/collection.js +62 -0
  159. package/dist/roap/collection.js.map +1 -0
  160. package/dist/roap/handler.js +275 -0
  161. package/dist/roap/handler.js.map +1 -0
  162. package/dist/roap/index.d.ts +86 -0
  163. package/dist/roap/request.d.ts +39 -0
  164. package/dist/roap/state.js +126 -0
  165. package/dist/roap/state.js.map +1 -0
  166. package/dist/roap/turnDiscovery.d.ts +155 -0
  167. package/dist/roap/util.js +75 -0
  168. package/dist/roap/util.js.map +1 -0
  169. package/dist/rtcMetrics/constants.d.ts +4 -0
  170. package/dist/rtcMetrics/constants.js +11 -0
  171. package/dist/rtcMetrics/constants.js.map +1 -0
  172. package/dist/rtcMetrics/index.d.ts +61 -0
  173. package/dist/rtcMetrics/index.js +197 -0
  174. package/dist/rtcMetrics/index.js.map +1 -0
  175. package/dist/statsAnalyzer/global.d.ts +36 -0
  176. package/dist/statsAnalyzer/global.js +126 -0
  177. package/dist/statsAnalyzer/global.js.map +1 -0
  178. package/dist/statsAnalyzer/index.d.ts +217 -0
  179. package/dist/statsAnalyzer/index.js +1013 -0
  180. package/dist/statsAnalyzer/index.js.map +1 -0
  181. package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
  182. package/dist/statsAnalyzer/mqaUtil.js +179 -0
  183. package/dist/statsAnalyzer/mqaUtil.js.map +1 -0
  184. package/dist/transcription/index.d.ts +64 -0
  185. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  186. package/dist/types/constants.d.ts +9 -2
  187. package/dist/types/mediaQualityMetrics/config.d.ts +241 -0
  188. package/dist/types/meeting/brbState.d.ts +54 -0
  189. package/dist/types/meeting/index.d.ts +23 -0
  190. package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -1
  191. package/dist/types/metrics/constants.d.ts +2 -0
  192. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  193. package/dist/types/reachability/index.d.ts +9 -1
  194. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  195. package/dist/types/rtcMetrics/index.d.ts +71 -0
  196. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  197. package/dist/types/statsAnalyzer/index.d.ts +217 -0
  198. package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
  199. package/dist/webinar/collection.d.ts +16 -0
  200. package/dist/webinar/index.d.ts +5 -0
  201. package/dist/webinar/index.js +1 -1
  202. package/package.json +23 -23
  203. package/src/constants.ts +10 -2
  204. package/src/locus-info/selfUtils.ts +5 -0
  205. package/src/media/MediaConnectionAwaiter.ts +2 -0
  206. package/src/media/properties.ts +34 -13
  207. package/src/meeting/brbState.ts +169 -0
  208. package/src/meeting/index.ts +112 -26
  209. package/src/meeting/muteState.ts +1 -6
  210. package/src/meeting-info/meeting-info-v2.ts +9 -1
  211. package/src/meeting-info/utilv2.ts +14 -2
  212. package/src/metrics/constants.ts +2 -0
  213. package/src/reachability/index.ts +29 -1
  214. package/test/unit/spec/locus-info/selfUtils.js +10 -0
  215. package/test/unit/spec/media/properties.ts +15 -0
  216. package/test/unit/spec/meeting/brbState.ts +114 -0
  217. package/test/unit/spec/meeting/index.js +92 -30
  218. package/test/unit/spec/meeting/muteState.js +0 -24
  219. package/test/unit/spec/meeting-info/utilv2.js +9 -0
  220. package/test/unit/spec/reachability/index.ts +120 -10
@@ -0,0 +1,1013 @@
1
+ "use strict";
2
+
3
+ var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
5
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
+ _Object$defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.StatsAnalyzer = exports.EVENTS = void 0;
10
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
11
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
12
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
13
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
14
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
15
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
16
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
17
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
18
+ var _cloneDeep2 = _interopRequireDefault(require("lodash/cloneDeep"));
19
+ var _eventsScope = _interopRequireDefault(require("../common/events/events-scope"));
20
+ var _constants = require("../constants");
21
+ var _config = _interopRequireDefault(require("../mediaQualityMetrics/config"));
22
+ var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
23
+ var _global = _interopRequireDefault(require("./global"));
24
+ var _mqaUtil = require("./mqaUtil");
25
+ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
26
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable prefer-destructuring */
27
+ var EVENTS = exports.EVENTS = {
28
+ MEDIA_QUALITY: 'MEDIA_QUALITY',
29
+ NO_FRAMES_SENT: 'NO_FRAMES_SENT',
30
+ NO_VIDEO_ENCODED: 'NO_VIDEO_ENCODED',
31
+ LOCAL_MEDIA_STARTED: 'LOCAL_MEDIA_STARTED',
32
+ LOCAL_MEDIA_STOPPED: 'LOCAL_MEDIA_STOPPED',
33
+ REMOTE_MEDIA_STARTED: 'REMOTE_MEDIA_STARTED',
34
+ REMOTE_MEDIA_STOPPED: 'REMOTE_MEDIA_STOPPED'
35
+ };
36
+
37
+ /**
38
+ * Stats Analyzer class that will emit events based on detected quality
39
+ *
40
+ * @export
41
+ * @class StatsAnalyzer
42
+ * @extends {EventsScope}
43
+ */
44
+ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
45
+ /**
46
+ * Creates a new instance of StatsAnalyzer
47
+ * @constructor
48
+ * @public
49
+ * @param {Object} config SDK Configuration Object
50
+ * @param {Object} networkQualityMonitor class for assessing network characteristics (jitter, packetLoss, latency)
51
+ * @param {Object} statsResults Default properties for stats
52
+ */
53
+ function StatsAnalyzer(config) {
54
+ var _this;
55
+ var networkQualityMonitor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
56
+ var statsResults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _global.default;
57
+ (0, _classCallCheck2.default)(this, StatsAnalyzer);
58
+ _this = _callSuper(this, StatsAnalyzer);
59
+ (0, _defineProperty2.default)(_this, "config", void 0);
60
+ (0, _defineProperty2.default)(_this, "correlationId", void 0);
61
+ (0, _defineProperty2.default)(_this, "lastEmittedStartStopEvent", void 0);
62
+ (0, _defineProperty2.default)(_this, "lastMqaDataSent", void 0);
63
+ (0, _defineProperty2.default)(_this, "lastStatsResults", void 0);
64
+ (0, _defineProperty2.default)(_this, "localMQEStats", void 0);
65
+ (0, _defineProperty2.default)(_this, "meetingMediaStatus", void 0);
66
+ (0, _defineProperty2.default)(_this, "mqaInterval", void 0);
67
+ (0, _defineProperty2.default)(_this, "mqaSentCount", void 0);
68
+ (0, _defineProperty2.default)(_this, "networkQualityMonitor", void 0);
69
+ (0, _defineProperty2.default)(_this, "peerConnection", void 0);
70
+ (0, _defineProperty2.default)(_this, "statsInterval", void 0);
71
+ (0, _defineProperty2.default)(_this, "statsResults", void 0);
72
+ (0, _defineProperty2.default)(_this, "statsStarted", void 0);
73
+ /**
74
+ * emits started/stopped events for local/remote media by checking
75
+ * if given values are increasing or not. The previousValue, currentValue
76
+ * params can be any numerical value like number of receive packets or
77
+ * decoded frames, etc.
78
+ *
79
+ * @private
80
+ * @param {string} mediaType
81
+ * @param {number} previousValue - value to compare
82
+ * @param {number} currentValue - value to compare (must be same type of value as previousValue)
83
+ * @param {boolean} isLocal - true if stats are for local media being sent out, false for remote media being received
84
+ * @memberof StatsAnalyzer
85
+ * @returns {void}
86
+ */
87
+ (0, _defineProperty2.default)(_this, "emitStartStopEvents", function (mediaType, previousValue, currentValue, isLocal) {
88
+ if (mediaType !== 'audio' && mediaType !== 'video' && mediaType !== 'share') {
89
+ throw new Error("Unsupported mediaType: ".concat(mediaType));
90
+ }
91
+
92
+ // eslint-disable-next-line no-param-reassign
93
+ if (previousValue === undefined) previousValue = 0;
94
+ // eslint-disable-next-line no-param-reassign
95
+ if (currentValue === undefined) currentValue = 0;
96
+ var lastEmittedEvent = isLocal ? _this.lastEmittedStartStopEvent[mediaType].local : _this.lastEmittedStartStopEvent[mediaType].remote;
97
+ var newEvent;
98
+ if (currentValue - previousValue > 0) {
99
+ newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STARTED : EVENTS.REMOTE_MEDIA_STARTED;
100
+ } else if (currentValue === previousValue && currentValue >= 0) {
101
+ newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STOPPED : EVENTS.REMOTE_MEDIA_STOPPED;
102
+ }
103
+ if (newEvent && lastEmittedEvent !== newEvent) {
104
+ if (isLocal) {
105
+ _this.lastEmittedStartStopEvent[mediaType].local = newEvent;
106
+ } else {
107
+ _this.lastEmittedStartStopEvent[mediaType].remote = newEvent;
108
+ }
109
+ _this.emit({
110
+ file: 'statsAnalyzer/index',
111
+ function: 'compareLastStatsResult'
112
+ }, newEvent, {
113
+ type: mediaType
114
+ });
115
+ }
116
+ });
117
+ /**
118
+ * Processes remote and local candidate result and stores
119
+ * @private
120
+ * @param {*} result
121
+ * @param {*} type
122
+ * @param {boolean} isSender
123
+ * @param {boolean} isRemote
124
+ *
125
+ * @returns {void}
126
+ */
127
+ (0, _defineProperty2.default)(_this, "parseCandidate", function (result, type, isSender, isRemote) {
128
+ if (!result || !result.id) {
129
+ return;
130
+ }
131
+ var RemoteCandidateType = {};
132
+ var RemoteTransport = {};
133
+ var RemoteIpAddress = {};
134
+ var RemoteNetworkType = {};
135
+ if (!result.id) return;
136
+ var sendRecvType = isSender ? _constants.STATS.SEND_DIRECTION : _constants.STATS.RECEIVE_DIRECTION;
137
+ var ipType = isRemote ? _constants.STATS.REMOTE : _constants.STATS.LOCAL;
138
+ if (!RemoteCandidateType[result.id]) {
139
+ RemoteCandidateType[result.id] = [];
140
+ }
141
+ if (!RemoteTransport[result.id]) {
142
+ RemoteTransport[result.id] = [];
143
+ }
144
+ if (!RemoteIpAddress[result.id]) {
145
+ RemoteIpAddress[result.id] = [];
146
+ }
147
+ if (!RemoteNetworkType[result.id]) {
148
+ RemoteNetworkType[result.id] = [];
149
+ }
150
+ if (result.candidateType && RemoteCandidateType[result.id].indexOf(result.candidateType) === -1) {
151
+ RemoteCandidateType[result.id].push(result.candidateType);
152
+ }
153
+ if (result.protocol && RemoteTransport[result.id].indexOf(result.protocol) === -1) {
154
+ RemoteTransport[result.id].push(result.protocol.toUpperCase());
155
+ }
156
+ if (result.ip && RemoteIpAddress[result.id].indexOf("".concat(result.ip, ":").concat(result.portNumber)) === -1) {
157
+ RemoteIpAddress[result.id].push("".concat(result.ip)); // TODO: Add ports
158
+ }
159
+ if (result.networkType && RemoteNetworkType[result.id].indexOf(result.networkType) === -1) {
160
+ RemoteNetworkType[result.id].push(result.networkType);
161
+ }
162
+ _this.statsResults.internal.candidates[result.id] = {
163
+ candidateType: RemoteCandidateType[result.id],
164
+ ipAddress: RemoteIpAddress[result.id],
165
+ portNumber: result.port,
166
+ networkType: RemoteNetworkType[result.id],
167
+ priority: result.priority,
168
+ transport: RemoteTransport[result.id],
169
+ timestamp: result.time,
170
+ id: result.id,
171
+ type: result.type
172
+ };
173
+ _this.statsResults.connectionType[ipType].candidateType = RemoteCandidateType[result.id];
174
+ _this.statsResults.connectionType[ipType].ipAddress = RemoteIpAddress[result.id];
175
+ _this.statsResults.connectionType[ipType].networkType = RemoteNetworkType[result.id][0] === _constants.NETWORK_TYPE.VPN ? _constants.NETWORK_TYPE.UNKNOWN : RemoteNetworkType[result.id][0];
176
+ _this.statsResults.connectionType[ipType].transport = RemoteTransport[result.id];
177
+ _this.statsResults[type][sendRecvType].totalRoundTripTime = result.totalRoundTripTime;
178
+ });
179
+ _this.statsStarted = false;
180
+ _this.statsResults = statsResults;
181
+ _this.lastStatsResults = null;
182
+ _this.config = config;
183
+ _this.networkQualityMonitor = networkQualityMonitor;
184
+ _this.correlationId = config.correlationId;
185
+ _this.mqaSentCount = -1;
186
+ _this.lastMqaDataSent = {
187
+ resolutions: {
188
+ video: {
189
+ send: {},
190
+ recv: {}
191
+ },
192
+ audio: {
193
+ send: {},
194
+ recv: {}
195
+ },
196
+ share: {
197
+ send: {},
198
+ recv: {}
199
+ }
200
+ },
201
+ video: {
202
+ send: {},
203
+ recv: {}
204
+ },
205
+ audio: {
206
+ send: {},
207
+ recv: {}
208
+ },
209
+ share: {
210
+ send: {},
211
+ recv: {}
212
+ }
213
+ };
214
+ _this.localMQEStats = {
215
+ audio: {
216
+ RX: {
217
+ packetsLost: [],
218
+ jitter: [],
219
+ latency: [],
220
+ bitRate: []
221
+ },
222
+ TX: {
223
+ packetsLost: [],
224
+ jitter: [],
225
+ latency: [],
226
+ bitRate: []
227
+ }
228
+ },
229
+ video: {
230
+ RX: {
231
+ packetsLost: [],
232
+ jitter: [],
233
+ latency: [],
234
+ bitRate: [],
235
+ frameRate: [],
236
+ resolutionWidth: [],
237
+ resolutionHeight: [],
238
+ requestedKeyFrame: [],
239
+ receivedKeyFrame: []
240
+ },
241
+ TX: {
242
+ packetsLost: [],
243
+ jitter: [],
244
+ latency: [],
245
+ bitRate: [],
246
+ frameRate: [],
247
+ resolutionWidth: [],
248
+ resolutionHeight: [],
249
+ requestedKeyFrame: [],
250
+ receivedKeyFrame: []
251
+ }
252
+ }
253
+ };
254
+ _this.lastEmittedStartStopEvent = {
255
+ audio: {
256
+ local: undefined,
257
+ remote: undefined
258
+ },
259
+ video: {
260
+ local: undefined,
261
+ remote: undefined
262
+ },
263
+ share: {
264
+ local: undefined,
265
+ remote: undefined
266
+ }
267
+ };
268
+ return _this;
269
+ }
270
+ (0, _inherits2.default)(StatsAnalyzer, _EventsScope);
271
+ return (0, _createClass2.default)(StatsAnalyzer, [{
272
+ key: "populateResults",
273
+ value: function populateResults(lastMqa) {
274
+ // Audio
275
+
276
+ this.localMQEStats.audio.RX.packetsLost.push(lastMqa.audioReceive[0].common.mediaHopByHopLost);
277
+ this.localMQEStats.audio.RX.jitter.push(lastMqa.audioReceive[0].streams[0].common.rtpJitter);
278
+ this.localMQEStats.audio.RX.latency.push(lastMqa.audioReceive[0].common.roundTripTime);
279
+ this.localMQEStats.audio.RX.bitRate.push(lastMqa.audioReceive[0].streams[0].common.receivedBitrate);
280
+ this.localMQEStats.audio.TX.packetsLost.push(lastMqa.audioTransmit[0].common.remoteLossRate);
281
+ this.localMQEStats.audio.TX.jitter.push(lastMqa.audioTransmit[0].common.remoteJitter);
282
+ this.localMQEStats.audio.TX.latency.push(lastMqa.audioTransmit[0].common.roundTripTime);
283
+ this.localMQEStats.audio.TX.bitRate.push(lastMqa.audioTransmit[0].streams[0].common.transmittedBitrate);
284
+
285
+ // Video
286
+
287
+ this.localMQEStats.video.RX.packetsLost.push(lastMqa.videoReceive[0].common.mediaHopByHopLost);
288
+ this.localMQEStats.video.RX.jitter.push(lastMqa.videoReceive[0].streams[0].common.rtpJitter);
289
+ this.localMQEStats.video.RX.latency.push(lastMqa.videoReceive[0].streams[0].common.roundTripTime);
290
+ this.localMQEStats.video.RX.bitRate.push(lastMqa.videoReceive[0].streams[0].common.receivedBitrate);
291
+ this.localMQEStats.video.RX.frameRate.push(lastMqa.videoReceive[0].streams[0].common.receivedFrameRate);
292
+ this.localMQEStats.video.RX.resolutionWidth.push(lastMqa.videoReceive[0].streams[0].receivedWidth);
293
+ this.localMQEStats.video.RX.resolutionHeight.push(lastMqa.videoReceive[0].streams[0].receivedHeight);
294
+ this.localMQEStats.video.RX.requestedKeyFrame.push();
295
+ this.localMQEStats.video.RX.receivedKeyFrame.push();
296
+ this.localMQEStats.video.TX.packetsLost.push(lastMqa.videoTransmit[0].common.remoteLossRate);
297
+ this.localMQEStats.video.TX.jitter.push(lastMqa.videoTransmit[0].common.remoteJitter);
298
+ this.localMQEStats.video.TX.latency.push(lastMqa.videoTransmit[0].common.roundTripTime);
299
+ this.localMQEStats.video.TX.bitRate.push(lastMqa.videoTransmit[0].streams[0].common.transmittedBitrate);
300
+ this.localMQEStats.video.TX.frameRate.push(lastMqa.videoTransmit[0].streams[0].common.transmittedFrameRate);
301
+ this.localMQEStats.video.TX.resolutionWidth.push(lastMqa.videoTransmit[0].streams[0].transmittedWidth);
302
+ this.localMQEStats.video.TX.resolutionHeight.push(lastMqa.videoTransmit[0].streams[0].transmittedHeight);
303
+ this.localMQEStats.video.TX.requestedKeyFrame.push(lastMqa.videoTransmit[0].streams[0].requestedKeyFrames);
304
+ this.localMQEStats.video.TX.receivedKeyFrame.push();
305
+ }
306
+ }, {
307
+ key: "resetStatsResults",
308
+ value: function resetStatsResults() {
309
+ this.statsResults.audio.send.meanRemoteJitter = [];
310
+ this.statsResults.video.send.meanRemoteJitter = [];
311
+ this.statsResults.share.send.meanRemoteJitter = [];
312
+ this.statsResults.audio.recv.meanRtpJitter = [];
313
+
314
+ // TODO: currently no values are present
315
+ this.statsResults.video.recv.meanRtpJitter = [];
316
+ this.statsResults.share.recv.meanRtpJitter = [];
317
+
318
+ // Reset the roundTripTime
319
+ this.statsResults.audio.send.meanRoundTripTime = [];
320
+ this.statsResults.video.send.meanRoundTripTime = [];
321
+ this.statsResults.share.send.meanRoundTripTime = [];
322
+ }
323
+
324
+ /**
325
+ * sets mediaStatus status for analyzing metrics
326
+ *
327
+ * @public
328
+ * @param {Object} status for the audio and video
329
+ * @memberof StatsAnalyzer
330
+ * @returns {void}
331
+ */
332
+ }, {
333
+ key: "updateMediaStatus",
334
+ value: function updateMediaStatus(status) {
335
+ this.meetingMediaStatus = status;
336
+ }
337
+
338
+ /**
339
+ * captures MQA data from peerconnection
340
+ *
341
+ * @public
342
+ * @memberof StatsAnalyzer
343
+ * @returns {void}
344
+ */
345
+ }, {
346
+ key: "sendMqaData",
347
+ value: function sendMqaData() {
348
+ var _this$peerConnection, _this$peerConnection$, _this$peerConnection$2, _this$peerConnection$3, _this$peerConnection2, _this$peerConnection3, _this$peerConnection4, _this$peerConnection5;
349
+ var audioReceiver = _config.default.intervals[0].audioReceive[0];
350
+ var audioSender = _config.default.intervals[0].audioTransmit[0];
351
+ var videoReceiver = _config.default.intervals[0].videoReceive[0];
352
+ var videoSender = _config.default.intervals[0].videoTransmit[0];
353
+ var shareSender = _config.default.intervals[0].videoTransmit[1];
354
+ var shareReceiver = _config.default.intervals[0].videoReceive[1];
355
+ (0, _mqaUtil.getAudioSenderMqa)({
356
+ audioSender: audioSender,
357
+ statsResults: this.statsResults,
358
+ lastMqaDataSent: this.lastMqaDataSent
359
+ });
360
+ (0, _mqaUtil.getAudioReceiverMqa)({
361
+ audioReceiver: audioReceiver,
362
+ statsResults: this.statsResults,
363
+ lastMqaDataSent: this.lastMqaDataSent
364
+ });
365
+ (0, _mqaUtil.getVideoReceiverMqa)({
366
+ videoReceiver: videoReceiver,
367
+ statsResults: this.statsResults,
368
+ lastMqaDataSent: this.lastMqaDataSent
369
+ });
370
+ (0, _mqaUtil.getVideoSenderMqa)({
371
+ videoSender: videoSender,
372
+ statsResults: this.statsResults,
373
+ lastMqaDataSent: this.lastMqaDataSent
374
+ });
375
+
376
+ // Capture mqa for share scenario
377
+
378
+ (0, _mqaUtil.getVideoSenderMqa)({
379
+ videoSender: shareSender,
380
+ statsResults: this.statsResults,
381
+ lastMqaDataSent: this.lastMqaDataSent,
382
+ isShareStream: true
383
+ });
384
+ (0, _mqaUtil.getVideoReceiverMqa)({
385
+ videoReceiver: shareReceiver,
386
+ statsResults: this.statsResults,
387
+ lastMqaDataSent: this.lastMqaDataSent,
388
+ isShareStream: true
389
+ });
390
+ _config.default.intervals[0].intervalMetadata.peerReflexiveIP = this.statsResults.connectionType.local.ipAddress[0];
391
+
392
+ // Adding peripheral information
393
+ _config.default.intervals[0].intervalMetadata.peripherals = [];
394
+ _config.default.intervals[0].intervalMetadata.peripherals.push({
395
+ information: _constants._UNKNOWN_,
396
+ name: _constants.MEDIA_DEVICES.SPEAKER
397
+ });
398
+ _config.default.intervals[0].intervalMetadata.peripherals.push({
399
+ information: ((_this$peerConnection = this.peerConnection) === null || _this$peerConnection === void 0 ? void 0 : (_this$peerConnection$ = _this$peerConnection.audioTransceiver) === null || _this$peerConnection$ === void 0 ? void 0 : (_this$peerConnection$2 = _this$peerConnection$.sender) === null || _this$peerConnection$2 === void 0 ? void 0 : (_this$peerConnection$3 = _this$peerConnection$2.track) === null || _this$peerConnection$3 === void 0 ? void 0 : _this$peerConnection$3.label) || _constants._UNKNOWN_,
400
+ name: _constants.MEDIA_DEVICES.MICROPHONE
401
+ });
402
+ _config.default.intervals[0].intervalMetadata.peripherals.push({
403
+ information: ((_this$peerConnection2 = this.peerConnection) === null || _this$peerConnection2 === void 0 ? void 0 : (_this$peerConnection3 = _this$peerConnection2.videoTransceiver) === null || _this$peerConnection3 === void 0 ? void 0 : (_this$peerConnection4 = _this$peerConnection3.sender) === null || _this$peerConnection4 === void 0 ? void 0 : (_this$peerConnection5 = _this$peerConnection4.track) === null || _this$peerConnection5 === void 0 ? void 0 : _this$peerConnection5.label) || _constants._UNKNOWN_,
404
+ name: _constants.MEDIA_DEVICES.CAMERA
405
+ });
406
+
407
+ // @ts-ignore
408
+ _config.default.networkType = this.statsResults.connectionType.local.networkType;
409
+ this.mqaSentCount += 1;
410
+ _config.default.intervals[0].intervalNumber = this.mqaSentCount;
411
+
412
+ // DO Deep copy, for some reason it takes the reference all the time rather then old value set
413
+ this.lastMqaDataSent = (0, _cloneDeep2.default)(this.statsResults);
414
+ this.populateResults(_config.default.intervals[0]);
415
+ this.resetStatsResults();
416
+ this.emit({
417
+ file: 'statsAnalyzer',
418
+ function: 'sendMqaData'
419
+ }, EVENTS.MEDIA_QUALITY, {
420
+ data: _config.default.intervals[0],
421
+ // @ts-ignore
422
+ networkType: _config.default.networkType
423
+ });
424
+ }
425
+
426
+ /**
427
+ * updated the peerconnection when changed
428
+ *
429
+ * @private
430
+ * @memberof updatePeerconnection
431
+ * @param {PeerConnection} peerConnection
432
+ * @returns {void}
433
+ */
434
+ }, {
435
+ key: "updatePeerconnection",
436
+ value: function updatePeerconnection(peerConnection) {
437
+ this.peerConnection = peerConnection;
438
+ }
439
+
440
+ /**
441
+ * Starts the stats analyzer on interval
442
+ *
443
+ * @public
444
+ * @memberof StatsAnalyzer
445
+ * @param {PeerConnection} peerConnection
446
+ * @returns {Promise}
447
+ */
448
+ }, {
449
+ key: "startAnalyzer",
450
+ value: function startAnalyzer(peerConnection) {
451
+ var _this2 = this;
452
+ if (!this.statsStarted) {
453
+ this.statsStarted = true;
454
+ this.peerConnection = peerConnection;
455
+ return this.getStatsAndParse().then(function () {
456
+ _this2.statsInterval = setInterval(function () {
457
+ _this2.getStatsAndParse();
458
+ }, _this2.config.analyzerInterval);
459
+ // Trigger initial fetch
460
+ _this2.sendMqaData();
461
+ _this2.mqaInterval = setInterval(function () {
462
+ _this2.sendMqaData();
463
+ }, _constants.MQA_INTEVAL);
464
+ });
465
+ }
466
+ return _promise.default.resolve();
467
+ }
468
+
469
+ /**
470
+ * Cleans up the analyzer when done
471
+ *
472
+ * @public
473
+ * @memberof StatsAnalyzer
474
+ * @returns {void}
475
+ */
476
+ }, {
477
+ key: "stopAnalyzer",
478
+ value: function stopAnalyzer() {
479
+ var _this3 = this;
480
+ var sendOneLastMqa = this.mqaInterval && this.statsInterval;
481
+ if (this.statsInterval) {
482
+ clearInterval(this.statsInterval);
483
+ this.statsInterval = undefined;
484
+ }
485
+ if (this.mqaInterval) {
486
+ clearInterval(this.mqaInterval);
487
+ this.mqaInterval = undefined;
488
+ }
489
+ if (sendOneLastMqa) {
490
+ return this.getStatsAndParse().then(function () {
491
+ _this3.sendMqaData();
492
+ _this3.peerConnection = null;
493
+ });
494
+ }
495
+ return _promise.default.resolve();
496
+ }
497
+
498
+ /**
499
+ * Parse a single result of get stats
500
+ *
501
+ * @private
502
+ * @param {*} getStatsResult
503
+ * @param {String} type
504
+ * @param {boolean} isSender
505
+ * @returns {void}
506
+ * @memberof StatsAnalyzer
507
+ */
508
+ }, {
509
+ key: "parseGetStatsResult",
510
+ value: function parseGetStatsResult(getStatsResult, type, isSender) {
511
+ if (!getStatsResult) {
512
+ return;
513
+ }
514
+ switch (getStatsResult.type) {
515
+ case 'outbound-rtp':
516
+ this.processOutboundRTPResult(getStatsResult, type);
517
+ break;
518
+ case 'inbound-rtp':
519
+ this.processInboundRTPResult(getStatsResult, type);
520
+ break;
521
+ case 'remote-inbound-rtp':
522
+ case 'remote-outbound-rtp':
523
+ // @ts-ignore
524
+ this.compareSentAndReceived(getStatsResult, type, isSender);
525
+ break;
526
+ case 'remotecandidate':
527
+ case 'remote-candidate':
528
+ this.parseCandidate(getStatsResult, type, isSender, true);
529
+ break;
530
+ case 'local-candidate':
531
+ this.parseCandidate(getStatsResult, type, isSender, false);
532
+ break;
533
+ case 'media-source':
534
+ // @ts-ignore
535
+ this.parseAudioSource(getStatsResult, type);
536
+ break;
537
+ default:
538
+ break;
539
+ }
540
+ }
541
+
542
+ /**
543
+ * Filters the get stats results for types
544
+ * @private
545
+ * @param {Array} getStatsResults
546
+ * @param {String} type
547
+ * @param {boolean} isSender
548
+ * @returns {void}
549
+ */
550
+ }, {
551
+ key: "filterAndParseGetStatsResults",
552
+ value: function filterAndParseGetStatsResults(getStatsResults, type, isSender) {
553
+ var _this4 = this;
554
+ var types = _constants.DEFAULT_GET_STATS_FILTER.types;
555
+ getStatsResults.forEach(function (result) {
556
+ if (types.includes(result.type)) {
557
+ _this4.parseGetStatsResult(result, type, isSender);
558
+ }
559
+ });
560
+ }
561
+
562
+ /**
563
+ * parse the audio
564
+ * @param {String} result
565
+ * @param {boolean} type
566
+ * @returns {void}
567
+ */
568
+ }, {
569
+ key: "parseAudioSource",
570
+ value: function parseAudioSource(result, type) {
571
+ if (!result) {
572
+ return;
573
+ }
574
+ if (type === _constants.STATS.AUDIO_CORRELATE) {
575
+ this.statsResults[type].send.audioLevel = result.audioLevel;
576
+ this.statsResults[type].send.totalAudioEnergy = result.totalAudioEnergy;
577
+ }
578
+ }
579
+ }, {
580
+ key: "compareLastStatsResult",
581
+ value:
582
+ /**
583
+ * compares current and previous stats to check if packets are not sent
584
+ *
585
+ * @private
586
+ * @memberof StatsAnalyzer
587
+ * @returns {void}
588
+ */
589
+ function compareLastStatsResult() {
590
+ if (this.lastStatsResults !== null && this.meetingMediaStatus) {
591
+ // compare audio stats sent
592
+ var mediaType = _constants.STATS.AUDIO_CORRELATE;
593
+ var currentStats = null;
594
+ var previousStats = null;
595
+ if (this.meetingMediaStatus.expected.sendAudio) {
596
+ currentStats = this.statsResults[mediaType].send;
597
+ previousStats = this.lastStatsResults[mediaType].send;
598
+ if (currentStats.totalPacketsSent === previousStats.totalPacketsSent || currentStats.totalPacketsSent === 0) {
599
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets sent"));
600
+ } else {
601
+ if (currentStats.totalAudioEnergy === previousStats.totalAudioEnergy || currentStats.totalAudioEnergy === 0) {
602
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " Energy present"));
603
+ }
604
+ if (currentStats.audioLevel === 0) {
605
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> ".concat(mediaType, " level is 0 for the user"));
606
+ }
607
+ }
608
+ this.emitStartStopEvents(mediaType, previousStats.totalPacketsSent, currentStats.totalPacketsSent, true);
609
+ }
610
+ if (this.meetingMediaStatus.expected.receiveAudio) {
611
+ // compare audio stats received
612
+ currentStats = this.statsResults[mediaType].recv;
613
+ previousStats = this.lastStatsResults[mediaType].recv;
614
+ if (currentStats.totalPacketsReceived === previousStats.totalPacketsReceived || currentStats.totalPacketsReceived === 0) {
615
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets received"));
616
+ } else if (currentStats.totalSamplesReceived === previousStats.totalSamplesReceived || currentStats.totalSamplesReceived === 0) {
617
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " samples received"));
618
+ }
619
+ this.emitStartStopEvents(mediaType, previousStats.totalPacketsReceived, currentStats.totalPacketsReceived, false);
620
+ }
621
+ mediaType = _constants.STATS.VIDEO_CORRELATE;
622
+ if (this.meetingMediaStatus.expected.sendVideo) {
623
+ // compare video stats sent
624
+ currentStats = this.statsResults[mediaType].send;
625
+ previousStats = this.lastStatsResults[mediaType].send;
626
+ if (currentStats.totalPacketsSent === previousStats.totalPacketsSent || currentStats.totalPacketsSent === 0) {
627
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets sent"));
628
+ } else if (this.lastEmittedStartStopEvent[mediaType].local !== EVENTS.LOCAL_MEDIA_STOPPED) {
629
+ if (currentStats.framesEncoded === previousStats.framesEncoded || currentStats.framesEncoded === 0) {
630
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
631
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " Frames Encoded"));
632
+ this.emit({
633
+ file: 'statsAnalyzer',
634
+ function: 'compareLastStatsResult'
635
+ }, EVENTS.NO_VIDEO_ENCODED, {
636
+ mediaType: mediaType
637
+ });
638
+ }
639
+ if (this.statsResults.resolutions[mediaType].send.framesSent === this.lastStatsResults.resolutions[mediaType].send.framesSent || this.statsResults.resolutions[mediaType].send.framesSent === 0) {
640
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " Frames sent"));
641
+ }
642
+
643
+ // Video is encoded but frames are not sent
644
+ if (currentStats.framesEncoded !== previousStats.framesEncoded && (currentStats.framesSent === previousStats.framesSent || currentStats.framesSent === 0)) {
645
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
646
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames sent even though frames are encoded"));
647
+ this.emit({
648
+ file: 'statsAnalyzer',
649
+ function: 'compareLastStatsResult'
650
+ }, EVENTS.NO_FRAMES_SENT, {
651
+ mediaType: mediaType
652
+ });
653
+ }
654
+ }
655
+ this.emitStartStopEvents(mediaType, previousStats.framesSent, currentStats.framesSent, true);
656
+ }
657
+ if (this.meetingMediaStatus.expected.receiveVideo) {
658
+ // compare video stats reveived
659
+
660
+ currentStats = this.statsResults[mediaType].recv;
661
+ previousStats = this.lastStatsResults[mediaType].recv;
662
+ if (currentStats.totalPacketsReceived === previousStats.totalPacketsReceived || currentStats.totalPacketsReceived === 0) {
663
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets received"));
664
+ } else {
665
+ if (this.statsResults.resolutions[mediaType].recv.framesReceived === this.lastStatsResults.resolutions[mediaType].recv.framesReceived || this.statsResults.resolutions[mediaType].recv.framesReceived === 0) {
666
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames received"));
667
+ }
668
+ if (this.statsResults[mediaType].recv.framesDecoded === this.lastStatsResults[mediaType].recv.framesDecoded || this.statsResults.resolutions[mediaType].send.framesDecoded === 0) {
669
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames decoded"));
670
+ }
671
+ if (this.statsResults.resolutions[mediaType].recv.framesDropped - this.lastStatsResults.resolutions[mediaType].recv.framesDropped > 10) {
672
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> ".concat(mediaType, " frames are getting dropped"));
673
+ }
674
+ }
675
+ this.emitStartStopEvents(mediaType, previousStats.framesDecoded, currentStats.framesDecoded, false);
676
+ }
677
+ mediaType = _constants.STATS.SHARE_CORRELATE;
678
+ if (this.meetingMediaStatus.expected.sendShare) {
679
+ // compare share stats sent
680
+
681
+ currentStats = this.statsResults[mediaType].send;
682
+ previousStats = this.lastStatsResults[mediaType].send;
683
+ if (currentStats.totalPacketsSent === previousStats.totalPacketsSent || currentStats.totalPacketsSent === 0) {
684
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets sent"));
685
+ } else if (this.lastEmittedStartStopEvent[mediaType].local !== EVENTS.LOCAL_MEDIA_STOPPED) {
686
+ if (currentStats.framesEncoded === previousStats.framesEncoded || currentStats.framesEncoded === 0) {
687
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
688
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames getting encoded"));
689
+ this.emit({
690
+ file: 'statsAnalyzer',
691
+ function: 'compareLastStatsResult'
692
+ }, EVENTS.NO_VIDEO_ENCODED, {
693
+ mediaType: mediaType
694
+ });
695
+ }
696
+ if (this.statsResults.resolutions[mediaType].send.framesSent === this.lastStatsResults.resolutions[mediaType].send.framesSent || this.statsResults.resolutions[mediaType].send.framesSent === 0) {
697
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames sent"));
698
+ }
699
+
700
+ // Share video is encoded but frames are not sent
701
+ if (currentStats.framesEncoded !== previousStats.framesEncoded && (currentStats.framesSent === previousStats.framesSent || currentStats.framesSent === 0)) {
702
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
703
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " Frames sent even though frames are being encoded"));
704
+ this.emit({
705
+ file: 'statsAnalyzer',
706
+ function: 'compareLastStatsResult'
707
+ }, EVENTS.NO_FRAMES_SENT, {
708
+ mediaType: mediaType
709
+ });
710
+ }
711
+ }
712
+
713
+ // TODO:need to check receive share value
714
+ // compare share stats reveived
715
+ currentStats = this.statsResults[mediaType].recv;
716
+ previousStats = this.lastStatsResults[mediaType].recv;
717
+ if (currentStats.totalPacketsReceived === previousStats.totalPacketsReceived || currentStats.totalPacketsSent === 0) {
718
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " RTP packets received"));
719
+ } else {
720
+ if (this.statsResults.resolutions[mediaType].recv.framesReceived === this.lastStatsResults.resolutions[mediaType].recv.framesReceived || this.statsResults.resolutions[mediaType].recv.framesReceived === 0) {
721
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames received"));
722
+ }
723
+ if (this.statsResults[mediaType].recv.framesDecoded === this.lastStatsResults[mediaType].recv.framesDecoded || this.statsResults.resolutions[mediaType].send.framesDecoded === 0) {
724
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> No ".concat(mediaType, " frames decoded"));
725
+ }
726
+ if (this.statsResults.resolutions[mediaType].recv.framesDropped - this.lastStatsResults.resolutions[mediaType].recv.framesDropped > 10) {
727
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#compareLastStatsResult --> ".concat(mediaType, " frames are getting dropped"));
728
+ }
729
+ }
730
+
731
+ // we are not calling emitStartStopEvents() for sending or receiving share because sharing is often started and stopped
732
+ // in meetings and this.meetingMediaStatus.expected values can be out of sync with the actual packet flow
733
+ // so we would send "sharing stopped" events incorrectly
734
+ }
735
+ }
736
+ }
737
+
738
+ /**
739
+ * Does a `getStats` on all the transceivers and parses the results
740
+ *
741
+ * @private
742
+ * @memberof StatsAnalyzer
743
+ * @returns {Promise}
744
+ */
745
+ }, {
746
+ key: "getStatsAndParse",
747
+ value: function getStatsAndParse() {
748
+ var _this5 = this;
749
+ if (!this.peerConnection) {
750
+ return _promise.default.resolve();
751
+ }
752
+ if (this.peerConnection && this.peerConnection.connectionState === _constants.CONNECTION_STATE.FAILED) {
753
+ _loggerProxy.default.logger.trace('StatsAnalyzer:index#getStatsAndParse --> PeerConnection is in failed state');
754
+ return _promise.default.resolve();
755
+ }
756
+ _loggerProxy.default.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Collecting Stats');
757
+ return _promise.default.all([this.peerConnection.videoTransceiver.sender.getStats().then(function (res) {
758
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.VIDEO_CORRELATE, true);
759
+ }), this.peerConnection.videoTransceiver.receiver.getStats().then(function (res) {
760
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.VIDEO_CORRELATE, false);
761
+ }), this.peerConnection.audioTransceiver.sender.getStats().then(function (res) {
762
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.AUDIO_CORRELATE, true);
763
+ }), this.peerConnection.audioTransceiver.receiver.getStats().then(function (res) {
764
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.AUDIO_CORRELATE, false);
765
+ }),
766
+ // TODO: add checks for screen share
767
+ this.peerConnection.shareTransceiver.sender.getStats().then(function (res) {
768
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.SHARE_CORRELATE, true);
769
+ }), this.peerConnection.shareTransceiver.receiver.getStats().then(function (res) {
770
+ _this5.filterAndParseGetStatsResults(res, _constants.STATS.SHARE_CORRELATE, false);
771
+ })]).then(function () {
772
+ _this5.statsResults[_constants.STATS.AUDIO_CORRELATE].direction = _this5.peerConnection.audioTransceiver.currentDirection;
773
+ _this5.statsResults[_constants.STATS.VIDEO_CORRELATE].direction = _this5.peerConnection.videoTransceiver.currentDirection;
774
+ _this5.statsResults[_constants.STATS.SHARE_CORRELATE].direction = _this5.peerConnection.shareTransceiver.currentDirection;
775
+
776
+ // Process Stats results every 5 seconds
777
+ _this5.compareLastStatsResult();
778
+
779
+ // Save the last results to compare with the current
780
+ _this5.lastStatsResults = JSON.parse((0, _stringify.default)(_this5.statsResults));
781
+ _loggerProxy.default.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Finished Collecting Stats');
782
+ });
783
+ }
784
+
785
+ /**
786
+ * Processes OutboundRTP stats result and stores
787
+ * @private
788
+ * @param {*} result
789
+ * @param {*} type
790
+ * @returns {void}
791
+ */
792
+ }, {
793
+ key: "processOutboundRTPResult",
794
+ value: function processOutboundRTPResult(result, type) {
795
+ var mediaType = type || _constants.STATS.AUDIO_CORRELATE;
796
+ var sendrecvType = _constants.STATS.SEND_DIRECTION;
797
+ this.processTrackResult(result, type, sendrecvType);
798
+ if (result.bytesSent) {
799
+ var kilobytes = 0;
800
+ if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesSent) {
801
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
802
+ }
803
+ if (!this.statsResults.internal[mediaType][sendrecvType].framesEncoded) {
804
+ this.statsResults.internal[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
805
+ }
806
+ if (!this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded) {
807
+ this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded = result.keyFramesEncoded;
808
+ }
809
+ var bytes = result.bytesSent - this.statsResults.internal[mediaType][sendrecvType].prevBytesSent;
810
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
811
+ kilobytes = bytes / 1024;
812
+ this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
813
+ this.statsResults[mediaType].bytesSent = kilobytes;
814
+ this.statsResults[mediaType][sendrecvType].framesEncoded = result.framesEncoded - this.statsResults.internal[mediaType][sendrecvType].framesEncoded;
815
+ this.statsResults[mediaType][sendrecvType].keyFramesEncoded = result.keyFramesEncoded - this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded;
816
+ this.statsResults.internal[mediaType].outboundRtpId = result.id;
817
+ if (!this.statsResults.internal[mediaType][sendrecvType].packetsSent) {
818
+ this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
819
+ }
820
+ this.statsResults[mediaType][sendrecvType].packetsSent = result.packetsSent - this.statsResults.internal[mediaType][sendrecvType].packetsSent;
821
+ this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
822
+
823
+ // Data saved to send MQA metrics
824
+
825
+ this.statsResults[mediaType][sendrecvType].totalKeyFramesEncoded = result.keyFramesEncoded;
826
+ this.statsResults[mediaType][sendrecvType].totalNackCount = result.nackCount;
827
+ this.statsResults[mediaType][sendrecvType].totalPliCount = result.pliCount;
828
+ this.statsResults[mediaType][sendrecvType].totalPacketsSent = result.packetsSent;
829
+ this.statsResults[mediaType][sendrecvType].totalFirCount = result.firCount;
830
+ this.statsResults[mediaType][sendrecvType].framesSent = result.framesSent;
831
+ this.statsResults[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
832
+ this.statsResults[mediaType][sendrecvType].encoderImplementation = result.encoderImplementation;
833
+ this.statsResults[mediaType][sendrecvType].qualityLimitationReason = result.qualityLimitationReason;
834
+ this.statsResults[mediaType][sendrecvType].qualityLimitationResolutionChanges = result.qualityLimitationResolutionChanges;
835
+ this.statsResults[mediaType][sendrecvType].retransmittedPacketsSent = result.retransmittedPacketsSent;
836
+ this.statsResults[mediaType][sendrecvType].totalBytesSent = result.bytesSent;
837
+ this.statsResults[mediaType][sendrecvType].headerBytesSent = result.headerBytesSent;
838
+ this.statsResults[mediaType][sendrecvType].retransmittedBytesSent = result.retransmittedBytesSent;
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Processes InboundRTP stats result and stores
844
+ * @private
845
+ * @param {*} result
846
+ * @param {*} type
847
+ * @returns {void}
848
+ */
849
+ }, {
850
+ key: "processInboundRTPResult",
851
+ value: function processInboundRTPResult(result, type) {
852
+ var mediaType = type || _constants.STATS.AUDIO_CORRELATE;
853
+ var sendrecvType = _constants.STATS.RECEIVE_DIRECTION;
854
+ this.processTrackResult(result, type, sendrecvType);
855
+ if (result.bytesReceived) {
856
+ var kilobytes = 0;
857
+ if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived) {
858
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
859
+ }
860
+ if (!this.statsResults.internal[mediaType][sendrecvType].pliCount) {
861
+ this.statsResults.internal[mediaType][sendrecvType].pliCount = result.pliCount;
862
+ }
863
+ if (!this.statsResults.internal[mediaType][sendrecvType].packetsLost) {
864
+ this.statsResults.internal[mediaType][sendrecvType].packetsLost = result.packetsLost;
865
+ }
866
+ if (!this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived) {
867
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
868
+ }
869
+ if (!this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp) {
870
+ this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp = result.lastPacketReceivedTimestamp;
871
+ }
872
+ var bytes = result.bytesReceived - this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived;
873
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
874
+ kilobytes = bytes / 1024;
875
+ this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
876
+ this.statsResults[mediaType].bytesReceived = kilobytes.toFixed(1);
877
+ this.statsResults[mediaType][sendrecvType].pliCount = result.pliCount - this.statsResults.internal[mediaType][sendrecvType].pliCount;
878
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost = result.packetsLost - this.statsResults.internal[mediaType][sendrecvType].packetsLost;
879
+ if (this.statsResults[mediaType][sendrecvType].currentPacketsLost < 0) {
880
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost = 0;
881
+ }
882
+ this.statsResults[mediaType][sendrecvType].packetsReceived = result.packetsReceived - this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived;
883
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
884
+ if (this.statsResults[mediaType][sendrecvType].packetsReceived === 0) {
885
+ _loggerProxy.default.logger.info("StatsAnalyzer:index#processInboundRTPResult --> No packets received for ".concat(mediaType, " "), this.statsResults[mediaType][sendrecvType].packetsReceived);
886
+ }
887
+
888
+ // Check the over all packet Lost ratio
889
+ this.statsResults[mediaType][sendrecvType].currentPacketLossRatio = this.statsResults[mediaType][sendrecvType].currentPacketsLost > 0 ? this.statsResults[mediaType][sendrecvType].currentPacketsLost / (this.statsResults[mediaType][sendrecvType].packetsReceived + this.statsResults[mediaType][sendrecvType].currentPacketsLost) : 0;
890
+ if (this.statsResults[mediaType][sendrecvType].currentPacketLossRatio > 3) {
891
+ _loggerProxy.default.logger.info('StatsAnalyzer:index#processInboundRTPResult --> Packets getting lost from the receiver ', this.statsResults[mediaType][sendrecvType].currentPacketLossRatio);
892
+ }
893
+
894
+ // TODO: check the packet loss value is negative values here
895
+
896
+ if (result.packetsLost) {
897
+ this.statsResults[mediaType][sendrecvType].totalPacketsLost = result.packetsLost > 0 ? result.packetsLost : -result.packetsLost;
898
+ } else {
899
+ this.statsResults[mediaType][sendrecvType].totalPacketsLost = 0;
900
+ }
901
+ this.statsResults[mediaType][sendrecvType].lastPacketReceivedTimestamp = result.lastPacketReceivedTimestamp;
902
+
903
+ // From Thin
904
+ this.statsResults[mediaType][sendrecvType].totalNackCount = result.nackCount;
905
+ this.statsResults[mediaType][sendrecvType].totalPliCount = result.pliCount;
906
+ this.statsResults[mediaType][sendrecvType].framesDecoded = result.framesDecoded;
907
+ this.statsResults[mediaType][sendrecvType].keyFramesDecoded = result.keyFramesDecoded;
908
+ this.statsResults[mediaType][sendrecvType].decoderImplementation = result.decoderImplementation;
909
+ this.statsResults[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
910
+ this.statsResults[mediaType][sendrecvType].fecPacketsDiscarded = result.fecPacketsDiscarded;
911
+ this.statsResults[mediaType][sendrecvType].fecPacketsReceived = result.fecPacketsReceived;
912
+ this.statsResults[mediaType][sendrecvType].totalBytesReceived = result.bytesReceived;
913
+ this.statsResults[mediaType][sendrecvType].headerBytesReceived = result.headerBytesReceived;
914
+ this.statsResults[mediaType][sendrecvType].meanRtpJitter.push(result.jitter);
915
+
916
+ // Audio stats
917
+
918
+ this.statsResults[mediaType][sendrecvType].audioLevel = result.audioLevel;
919
+ this.statsResults[mediaType][sendrecvType].totalAudioEnergy = result.totalAudioEnergy;
920
+ this.statsResults[mediaType][sendrecvType].totalSamplesReceived = result.totalSamplesReceived || 0;
921
+ this.statsResults[mediaType][sendrecvType].totalSamplesDecoded = result.totalSamplesDecoded || 0;
922
+ this.statsResults[mediaType][sendrecvType].concealedSamples = result.concealedSamples || 0;
923
+ }
924
+ }
925
+ }, {
926
+ key: "processTrackResult",
927
+ value:
928
+ /**
929
+ * Process Track results
930
+ *
931
+ * @private
932
+ * @param {*} result
933
+ * @param {*} mediaType
934
+ * @param {*} sendrecvType
935
+ * @returns {void}
936
+ * @memberof StatsAnalyzer
937
+ */
938
+ function processTrackResult(result, mediaType, sendrecvType) {
939
+ if (!result || mediaType === _constants.STATS.AUDIO_CORRELATE) {
940
+ return;
941
+ }
942
+ if (result.type !== 'inbound-rtp' && result.type !== 'outbound-rtp') {
943
+ return;
944
+ }
945
+ if (result.frameWidth && result.frameHeight) {
946
+ this.statsResults.resolutions[mediaType][sendrecvType].width = result.frameWidth;
947
+ this.statsResults.resolutions[mediaType][sendrecvType].height = result.frameHeight;
948
+ }
949
+ if (sendrecvType === _constants.STATS.RECEIVE_DIRECTION) {
950
+ this.statsResults.resolutions[mediaType][sendrecvType].framesReceived = result.framesReceived;
951
+ this.statsResults.resolutions[mediaType][sendrecvType].framesDecoded = result.framesDecoded;
952
+ this.statsResults.resolutions[mediaType][sendrecvType].framesDropped = result.framesDropped;
953
+ } else if (sendrecvType === _constants.STATS.SEND_DIRECTION) {
954
+ this.statsResults.resolutions[mediaType][sendrecvType].framesSent = result.framesSent;
955
+ this.statsResults.resolutions[mediaType][sendrecvType].hugeFramesSent = result.hugeFramesSent;
956
+ }
957
+ if (result.trackIdentifier && mediaType !== _constants.STATS.AUDIO_CORRELATE) {
958
+ this.statsResults.resolutions[mediaType][sendrecvType].trackIdentifier = result.trackIdentifier;
959
+ var jitterBufferDelay = result && result.jitterBufferDelay;
960
+ var jitterBufferEmittedCount = result && result.jitterBufferEmittedCount;
961
+ this.statsResults.resolutions[mediaType][sendrecvType].avgJitterDelay = jitterBufferEmittedCount && +jitterBufferDelay / +jitterBufferEmittedCount;
962
+
963
+ // Used to calculate the jitter
964
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay = result.jitterBufferDelay;
965
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount = result.jitterBufferEmittedCount;
966
+ }
967
+ }
968
+
969
+ /**
970
+ *
971
+ * @private
972
+ * @param {*} result
973
+ * @param {*} type
974
+ * @returns {void}
975
+ * @memberof StatsAnalyzer
976
+ */
977
+ }, {
978
+ key: "compareSentAndReceived",
979
+ value: function compareSentAndReceived(result, type) {
980
+ if (!type) {
981
+ return;
982
+ }
983
+ var mediaType = type;
984
+ if (!this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver) {
985
+ this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
986
+ }
987
+ var currentPacketLoss = result.packetsLost - this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver;
988
+ this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
989
+ this.statsResults[mediaType].send.packetsLostOnReceiver = currentPacketLoss;
990
+ this.statsResults[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
991
+ this.statsResults[mediaType].send.meanRemoteJitter.push(result.jitter);
992
+ this.statsResults[mediaType].send.meanRoundTripTime.push(result.roundTripTime);
993
+ this.statsResults[mediaType].send.timestamp = result.timestamp;
994
+ this.statsResults[mediaType].send.ssrc = result.ssrc;
995
+ this.statsResults[mediaType].send.reportsReceived = result.reportsReceived;
996
+
997
+ // Total packloss ratio on this video section of the call
998
+ this.statsResults[mediaType].send.overAllPacketLossRatio = this.statsResults[mediaType].send.totalPacketsLostOnReceiver > 0 ? this.statsResults[mediaType].send.totalPacketsLostOnReceiver / this.statsResults[mediaType].send.totalPacketsSent : 0;
999
+ this.statsResults[mediaType].send.currentPacketLossRatio = this.statsResults[mediaType].send.packetsLostOnReceiver > 0 ? this.statsResults[mediaType].send.packetsLostOnReceiver * 100 / (this.statsResults[mediaType].send.packetsSent + this.statsResults[mediaType].send.packetsLostOnReceiver) : 0;
1000
+ if (this.statsResults[mediaType].send.maxPacketLossRatio < this.statsResults[mediaType].send.currentPacketLossRatio) {
1001
+ this.statsResults[mediaType].send.maxPacketLossRatio = this.statsResults[mediaType].send.currentPacketLossRatio;
1002
+ }
1003
+ if (result.type === 'remote-inbound-rtp') {
1004
+ this.networkQualityMonitor.determineUplinkNetworkQuality({
1005
+ mediaType: mediaType,
1006
+ remoteRtpResults: result,
1007
+ statsAnalyzerCurrentStats: this.statsResults
1008
+ });
1009
+ }
1010
+ }
1011
+ }]);
1012
+ }(_eventsScope.default);
1013
+ //# sourceMappingURL=index.js.map