@webex/plugin-meetings 2.60.1-next.9 → 2.60.2

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 (539) hide show
  1. package/README.md +8 -58
  2. package/dist/common/browser-detection.js +3 -2
  3. package/dist/common/browser-detection.js.map +1 -1
  4. package/dist/common/collection.js +4 -3
  5. package/dist/common/collection.js.map +1 -1
  6. package/dist/common/config.js +2 -1
  7. package/dist/common/config.js.map +1 -1
  8. package/dist/common/errors/captcha-error.js +2 -1
  9. package/dist/common/errors/captcha-error.js.map +1 -1
  10. package/dist/common/errors/intent-to-join.js +2 -1
  11. package/dist/common/errors/intent-to-join.js.map +1 -1
  12. package/dist/common/errors/join-meeting.js +2 -1
  13. package/dist/common/errors/join-meeting.js.map +1 -1
  14. package/dist/common/errors/media.js +2 -1
  15. package/dist/common/errors/media.js.map +1 -1
  16. package/dist/common/errors/parameter.js +4 -3
  17. package/dist/common/errors/parameter.js.map +1 -1
  18. package/dist/common/errors/password-error.js +2 -1
  19. package/dist/common/errors/password-error.js.map +1 -1
  20. package/dist/common/errors/permission.js +2 -1
  21. package/dist/common/errors/permission.js.map +1 -1
  22. package/dist/common/errors/{reclaim-host-role-errors.js → reclaim-host-role-error.js} +11 -7
  23. package/dist/common/errors/reclaim-host-role-error.js.map +1 -0
  24. package/dist/common/errors/reconnection-in-progress.js +2 -1
  25. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  26. package/dist/common/errors/reconnection.js +2 -1
  27. package/dist/common/errors/reconnection.js.map +1 -1
  28. package/dist/common/errors/stats.js +2 -1
  29. package/dist/common/errors/stats.js.map +1 -1
  30. package/dist/common/errors/webex-errors.d.ts +8 -20
  31. package/dist/common/errors/webex-errors.js +28 -48
  32. package/dist/common/errors/webex-errors.js.map +1 -1
  33. package/dist/common/errors/webex-meetings-error.js +2 -1
  34. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  35. package/dist/common/events/events-scope.js +2 -1
  36. package/dist/common/events/events-scope.js.map +1 -1
  37. package/dist/common/events/events.js +2 -1
  38. package/dist/common/events/events.js.map +1 -1
  39. package/dist/common/events/trigger-proxy.js +2 -1
  40. package/dist/common/events/trigger-proxy.js.map +1 -1
  41. package/dist/common/events/util.js +2 -1
  42. package/dist/common/events/util.js.map +1 -1
  43. package/dist/common/logs/logger-config.js +2 -1
  44. package/dist/common/logs/logger-config.js.map +1 -1
  45. package/dist/common/logs/logger-proxy.js +3 -2
  46. package/dist/common/logs/logger-proxy.js.map +1 -1
  47. package/dist/common/logs/request.d.ts +1 -3
  48. package/dist/common/logs/request.js +5 -8
  49. package/dist/common/logs/request.js.map +1 -1
  50. package/dist/common/queue.d.ts +7 -9
  51. package/dist/common/queue.js +9 -22
  52. package/dist/common/queue.js.map +1 -1
  53. package/dist/config.d.ts +7 -6
  54. package/dist/config.js +10 -8
  55. package/dist/config.js.map +1 -1
  56. package/dist/constants.d.ts +100 -234
  57. package/dist/constants.js +444 -433
  58. package/dist/constants.js.map +1 -1
  59. package/dist/controls-options-manager/constants.js +6 -3
  60. package/dist/controls-options-manager/constants.js.map +1 -1
  61. package/dist/controls-options-manager/enums.d.ts +1 -11
  62. package/dist/controls-options-manager/enums.js +6 -15
  63. package/dist/controls-options-manager/enums.js.map +1 -1
  64. package/dist/controls-options-manager/index.d.ts +1 -17
  65. package/dist/controls-options-manager/index.js +38 -127
  66. package/dist/controls-options-manager/index.js.map +1 -1
  67. package/dist/controls-options-manager/util.d.ts +7 -1
  68. package/dist/controls-options-manager/util.js +19 -309
  69. package/dist/controls-options-manager/util.js.map +1 -1
  70. package/dist/index.d.ts +3 -6
  71. package/dist/index.js +5 -121
  72. package/dist/index.js.map +1 -1
  73. package/dist/locus-info/controlsUtils.js +11 -100
  74. package/dist/locus-info/controlsUtils.js.map +1 -1
  75. package/dist/locus-info/embeddedAppsUtils.js +4 -3
  76. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  77. package/dist/locus-info/fullState.js +2 -1
  78. package/dist/locus-info/fullState.js.map +1 -1
  79. package/dist/locus-info/hostUtils.js +2 -1
  80. package/dist/locus-info/hostUtils.js.map +1 -1
  81. package/dist/locus-info/index.d.ts +4 -57
  82. package/dist/locus-info/index.js +84 -425
  83. package/dist/locus-info/index.js.map +1 -1
  84. package/dist/locus-info/infoUtils.js +5 -13
  85. package/dist/locus-info/infoUtils.js.map +1 -1
  86. package/dist/locus-info/mediaSharesUtils.js +3 -58
  87. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  88. package/dist/locus-info/parser.d.ts +6 -66
  89. package/dist/locus-info/parser.js +80 -253
  90. package/dist/locus-info/parser.js.map +1 -1
  91. package/dist/locus-info/selfUtils.js +13 -97
  92. package/dist/locus-info/selfUtils.js.map +1 -1
  93. package/dist/media/index.d.ts +0 -2
  94. package/dist/media/index.js +319 -107
  95. package/dist/media/index.js.map +1 -1
  96. package/dist/media/properties.d.ts +53 -38
  97. package/dist/media/properties.js +153 -96
  98. package/dist/media/properties.js.map +1 -1
  99. package/dist/media/util.js +22 -1
  100. package/dist/media/util.js.map +1 -1
  101. package/dist/mediaQualityMetrics/config.d.ts +230 -234
  102. package/dist/mediaQualityMetrics/config.js +498 -302
  103. package/dist/mediaQualityMetrics/config.js.map +1 -1
  104. package/dist/meeting/effectsState.d.ts +42 -0
  105. package/dist/meeting/effectsState.js +260 -0
  106. package/dist/meeting/effectsState.js.map +1 -0
  107. package/dist/meeting/in-meeting-actions.d.ts +0 -88
  108. package/dist/meeting/in-meeting-actions.js +3 -94
  109. package/dist/meeting/in-meeting-actions.js.map +1 -1
  110. package/dist/meeting/index.d.ts +520 -705
  111. package/dist/meeting/index.js +3083 -5041
  112. package/dist/meeting/index.js.map +1 -1
  113. package/dist/meeting/muteState.d.ts +25 -93
  114. package/dist/meeting/muteState.js +133 -224
  115. package/dist/meeting/muteState.js.map +1 -1
  116. package/dist/meeting/request.d.ts +47 -82
  117. package/dist/meeting/request.js +199 -304
  118. package/dist/meeting/request.js.map +1 -1
  119. package/dist/meeting/state.js +2 -1
  120. package/dist/meeting/state.js.map +1 -1
  121. package/dist/meeting/util.d.ts +1 -118
  122. package/dist/meeting/util.js +435 -676
  123. package/dist/meeting/util.js.map +1 -1
  124. package/dist/meeting-info/collection.js +4 -3
  125. package/dist/meeting-info/collection.js.map +1 -1
  126. package/dist/meeting-info/index.d.ts +1 -13
  127. package/dist/meeting-info/index.js +7 -74
  128. package/dist/meeting-info/index.js.map +1 -1
  129. package/dist/meeting-info/meeting-info-v2.d.ts +1 -31
  130. package/dist/meeting-info/meeting-info-v2.js +63 -200
  131. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  132. package/dist/meeting-info/request.js +2 -1
  133. package/dist/meeting-info/request.js.map +1 -1
  134. package/dist/meeting-info/util.js +3 -2
  135. package/dist/meeting-info/util.js.map +1 -1
  136. package/dist/meeting-info/utilv2.js +41 -39
  137. package/dist/meeting-info/utilv2.js.map +1 -1
  138. package/dist/meetings/collection.d.ts +0 -17
  139. package/dist/meetings/collection.js +4 -42
  140. package/dist/meetings/collection.js.map +1 -1
  141. package/dist/meetings/index.d.ts +20 -114
  142. package/dist/meetings/index.js +133 -540
  143. package/dist/meetings/index.js.map +1 -1
  144. package/dist/meetings/request.js +3 -4
  145. package/dist/meetings/request.js.map +1 -1
  146. package/dist/meetings/util.js +6 -107
  147. package/dist/meetings/util.js.map +1 -1
  148. package/dist/member/index.d.ts +1 -13
  149. package/dist/member/index.js +2 -45
  150. package/dist/member/index.js.map +1 -1
  151. package/dist/member/member.types.js +4 -3
  152. package/dist/member/member.types.js.map +1 -1
  153. package/dist/member/util.js +29 -120
  154. package/dist/member/util.js.map +1 -1
  155. package/dist/members/collection.d.ts +0 -5
  156. package/dist/members/collection.js +2 -11
  157. package/dist/members/collection.js.map +1 -1
  158. package/dist/members/index.d.ts +11 -56
  159. package/dist/members/index.js +47 -174
  160. package/dist/members/index.js.map +1 -1
  161. package/dist/members/request.d.ts +11 -67
  162. package/dist/members/request.js +54 -102
  163. package/dist/members/request.js.map +1 -1
  164. package/dist/members/types.js +4 -3
  165. package/dist/members/types.js.map +1 -1
  166. package/dist/members/util.d.ts +1 -214
  167. package/dist/members/util.js +284 -327
  168. package/dist/members/util.js.map +1 -1
  169. package/dist/metrics/config.d.ts +169 -0
  170. package/dist/metrics/config.js +289 -0
  171. package/dist/metrics/config.js.map +1 -0
  172. package/dist/metrics/constants.d.ts +6 -15
  173. package/dist/metrics/constants.js +9 -17
  174. package/dist/metrics/constants.js.map +1 -1
  175. package/dist/metrics/index.d.ts +111 -4
  176. package/dist/metrics/index.js +452 -4
  177. package/dist/metrics/index.js.map +1 -1
  178. package/dist/networkQualityMonitor/index.js +4 -5
  179. package/dist/networkQualityMonitor/index.js.map +1 -1
  180. package/dist/peer-connection-manager/index.d.ts +6 -0
  181. package/dist/peer-connection-manager/index.js +671 -0
  182. package/dist/peer-connection-manager/index.js.map +1 -0
  183. package/dist/peer-connection-manager/util.d.ts +6 -0
  184. package/dist/peer-connection-manager/util.js +110 -0
  185. package/dist/peer-connection-manager/util.js.map +1 -0
  186. package/dist/personal-meeting-room/index.js +3 -2
  187. package/dist/personal-meeting-room/index.js.map +1 -1
  188. package/dist/personal-meeting-room/request.js +3 -2
  189. package/dist/personal-meeting-room/request.js.map +1 -1
  190. package/dist/personal-meeting-room/util.js +2 -1
  191. package/dist/personal-meeting-room/util.js.map +1 -1
  192. package/dist/reachability/index.d.ts +95 -61
  193. package/dist/reachability/index.js +392 -304
  194. package/dist/reachability/index.js.map +1 -1
  195. package/dist/reachability/request.d.ts +3 -7
  196. package/dist/reachability/request.js +10 -18
  197. package/dist/reachability/request.js.map +1 -1
  198. package/dist/reactions/reactions.d.ts +2 -2
  199. package/dist/reactions/reactions.js +6 -4
  200. package/dist/reactions/reactions.js.map +1 -1
  201. package/dist/reactions/reactions.type.d.ts +3 -23
  202. package/dist/reactions/reactions.type.js +23 -21
  203. package/dist/reactions/reactions.type.js.map +1 -1
  204. package/dist/reconnection-manager/index.d.ts +8 -32
  205. package/dist/reconnection-manager/index.js +232 -285
  206. package/dist/reconnection-manager/index.js.map +1 -1
  207. package/dist/recording-controller/enums.js +5 -4
  208. package/dist/recording-controller/enums.js.map +1 -1
  209. package/dist/recording-controller/index.d.ts +1 -15
  210. package/dist/recording-controller/index.js +46 -57
  211. package/dist/recording-controller/index.js.map +1 -1
  212. package/dist/recording-controller/util.d.ts +4 -5
  213. package/dist/recording-controller/util.js +10 -10
  214. package/dist/recording-controller/util.js.map +1 -1
  215. package/dist/roap/collection.d.ts +10 -0
  216. package/dist/roap/collection.js +63 -0
  217. package/dist/roap/collection.js.map +1 -0
  218. package/dist/roap/handler.d.ts +47 -0
  219. package/dist/roap/handler.js +279 -0
  220. package/dist/roap/handler.js.map +1 -0
  221. package/dist/roap/index.d.ts +47 -9
  222. package/dist/roap/index.js +238 -100
  223. package/dist/roap/index.js.map +1 -1
  224. package/dist/roap/request.d.ts +12 -18
  225. package/dist/roap/request.js +180 -126
  226. package/dist/roap/request.js.map +1 -1
  227. package/dist/roap/state.d.ts +9 -0
  228. package/dist/roap/state.js +127 -0
  229. package/dist/roap/state.js.map +1 -0
  230. package/dist/roap/turnDiscovery.d.ts +16 -27
  231. package/dist/roap/turnDiscovery.js +105 -115
  232. package/dist/roap/turnDiscovery.js.map +1 -1
  233. package/dist/roap/util.d.ts +2 -0
  234. package/dist/roap/util.js +76 -0
  235. package/dist/roap/util.js.map +1 -0
  236. package/dist/statsAnalyzer/global.d.ts +83 -1
  237. package/dist/statsAnalyzer/global.js +85 -2
  238. package/dist/statsAnalyzer/global.js.map +1 -1
  239. package/dist/statsAnalyzer/index.d.ts +30 -50
  240. package/dist/statsAnalyzer/index.js +511 -436
  241. package/dist/statsAnalyzer/index.js.map +1 -1
  242. package/dist/statsAnalyzer/mqaUtil.d.ts +6 -8
  243. package/dist/statsAnalyzer/mqaUtil.js +90 -130
  244. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  245. package/dist/transcription/index.js +2 -1
  246. package/dist/transcription/index.js.map +1 -1
  247. package/package.json +26 -39
  248. package/src/common/errors/webex-errors.ts +12 -36
  249. package/src/common/logs/logger-proxy.ts +1 -1
  250. package/src/common/logs/request.ts +1 -5
  251. package/src/common/queue.ts +8 -22
  252. package/src/config.ts +7 -6
  253. package/src/constants.ts +100 -265
  254. package/src/controls-options-manager/enums.ts +0 -12
  255. package/src/controls-options-manager/index.ts +21 -116
  256. package/src/controls-options-manager/util.ts +14 -294
  257. package/src/index.js +15 -0
  258. package/src/locus-info/controlsUtils.ts +0 -110
  259. package/src/locus-info/index.ts +61 -450
  260. package/src/locus-info/infoUtils.ts +2 -14
  261. package/src/locus-info/mediaSharesUtils.ts +0 -64
  262. package/src/locus-info/parser.ts +47 -258
  263. package/src/locus-info/selfUtils.ts +2 -85
  264. package/src/media/index.ts +370 -153
  265. package/src/media/properties.ts +136 -106
  266. package/src/media/util.ts +21 -0
  267. package/src/mediaQualityMetrics/config.ts +377 -244
  268. package/src/meeting/effectsState.ts +209 -0
  269. package/src/meeting/in-meeting-actions.ts +0 -176
  270. package/src/meeting/index.ts +2581 -4306
  271. package/src/meeting/muteState.ts +138 -224
  272. package/src/meeting/request.ts +127 -214
  273. package/src/meeting/util.ts +423 -687
  274. package/src/meeting-info/index.ts +8 -81
  275. package/src/meeting-info/meeting-info-v2.ts +13 -163
  276. package/src/meeting-info/util.ts +1 -1
  277. package/src/meeting-info/utilv2.ts +28 -28
  278. package/src/meetings/collection.ts +0 -33
  279. package/src/meetings/index.ts +136 -531
  280. package/src/meetings/request.ts +0 -2
  281. package/src/meetings/util.ts +5 -116
  282. package/src/member/index.ts +1 -43
  283. package/src/member/util.ts +28 -125
  284. package/src/members/collection.ts +0 -8
  285. package/src/members/index.ts +52 -187
  286. package/src/members/request.ts +27 -87
  287. package/src/members/util.ts +291 -332
  288. package/src/metrics/config.ts +485 -0
  289. package/src/metrics/constants.ts +6 -15
  290. package/src/metrics/index.ts +471 -1
  291. package/src/networkQualityMonitor/index.ts +6 -6
  292. package/src/peer-connection-manager/index.ts +847 -0
  293. package/src/peer-connection-manager/util.ts +119 -0
  294. package/src/reachability/index.ts +347 -246
  295. package/src/reachability/request.ts +8 -17
  296. package/src/reactions/reactions.ts +4 -4
  297. package/src/reactions/reactions.type.ts +4 -30
  298. package/src/reconnection-manager/index.ts +156 -168
  299. package/src/recording-controller/index.ts +3 -20
  300. package/src/recording-controller/util.ts +9 -26
  301. package/src/roap/collection.ts +62 -0
  302. package/src/roap/handler.ts +294 -0
  303. package/src/roap/index.ts +241 -96
  304. package/src/roap/request.ts +148 -74
  305. package/src/roap/state.ts +156 -0
  306. package/src/roap/turnDiscovery.ts +56 -62
  307. package/src/roap/util.ts +100 -0
  308. package/src/statsAnalyzer/global.ts +84 -1
  309. package/src/statsAnalyzer/index.ts +645 -479
  310. package/src/statsAnalyzer/mqaUtil.ts +126 -128
  311. package/test/integration/spec/journey.js +264 -320
  312. package/test/integration/spec/space-meeting.js +4 -77
  313. package/test/unit/spec/common/queue.js +2 -31
  314. package/test/unit/spec/controls-options-manager/index.js +0 -163
  315. package/test/unit/spec/controls-options-manager/util.js +60 -576
  316. package/test/unit/spec/fixture/locus.js +0 -1
  317. package/test/unit/spec/locus-info/controlsUtils.js +30 -323
  318. package/test/unit/spec/locus-info/index.js +15 -1437
  319. package/test/unit/spec/locus-info/infoUtils.js +16 -54
  320. package/test/unit/spec/locus-info/lib/SeqCmp.json +0 -16
  321. package/test/unit/spec/locus-info/lib/selfConstant.js +0 -48
  322. package/test/unit/spec/locus-info/parser.js +35 -116
  323. package/test/unit/spec/locus-info/selfUtils.js +0 -275
  324. package/test/unit/spec/media/properties.ts +84 -75
  325. package/test/unit/spec/meeting/effectsState.js +281 -0
  326. package/test/unit/spec/meeting/in-meeting-actions.ts +0 -86
  327. package/test/unit/spec/meeting/index.js +2313 -8384
  328. package/test/unit/spec/meeting/muteState.js +213 -409
  329. package/test/unit/spec/meeting/request.js +43 -523
  330. package/test/unit/spec/meeting/utils.js +24 -834
  331. package/test/unit/spec/meeting-info/meetinginfov2.js +5 -527
  332. package/test/unit/spec/meeting-info/utilv2.js +0 -21
  333. package/test/unit/spec/meetings/collection.js +0 -26
  334. package/test/unit/spec/meetings/index.js +232 -1445
  335. package/test/unit/spec/meetings/utils.js +2 -202
  336. package/test/unit/spec/member/index.js +9 -32
  337. package/test/unit/spec/member/util.js +61 -499
  338. package/test/unit/spec/members/index.js +5 -394
  339. package/test/unit/spec/members/request.js +27 -206
  340. package/test/unit/spec/members/utils.js +38 -173
  341. package/test/unit/spec/metrics/index.js +50 -1
  342. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  343. package/test/unit/spec/peerconnection-manager/index.js +218 -0
  344. package/test/unit/spec/peerconnection-manager/utils.js +49 -0
  345. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +388 -0
  346. package/test/unit/spec/reachability/index.ts +24 -532
  347. package/test/unit/spec/reconnection-manager/index.js +24 -163
  348. package/test/unit/spec/recording-controller/index.js +218 -293
  349. package/test/unit/spec/recording-controller/util.js +96 -223
  350. package/test/unit/spec/roap/index.ts +77 -187
  351. package/test/unit/spec/roap/turnDiscovery.ts +48 -86
  352. package/test/unit/spec/roap/util.js +30 -0
  353. package/test/unit/spec/stats-analyzer/index.js +165 -644
  354. package/test/utils/testUtils.js +45 -0
  355. package/test/utils/webex-config.js +0 -4
  356. package/test/utils/webex-test-users.js +3 -7
  357. package/dist/annotation/annotation.types.d.ts +0 -42
  358. package/dist/annotation/annotation.types.js +0 -7
  359. package/dist/annotation/annotation.types.js.map +0 -1
  360. package/dist/annotation/constants.d.ts +0 -31
  361. package/dist/annotation/constants.js +0 -41
  362. package/dist/annotation/constants.js.map +0 -1
  363. package/dist/annotation/index.d.ts +0 -117
  364. package/dist/annotation/index.js +0 -357
  365. package/dist/annotation/index.js.map +0 -1
  366. package/dist/breakouts/breakout.d.ts +0 -8
  367. package/dist/breakouts/breakout.js +0 -215
  368. package/dist/breakouts/breakout.js.map +0 -1
  369. package/dist/breakouts/collection.d.ts +0 -5
  370. package/dist/breakouts/collection.js +0 -22
  371. package/dist/breakouts/collection.js.map +0 -1
  372. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  373. package/dist/breakouts/edit-lock-error.js +0 -51
  374. package/dist/breakouts/edit-lock-error.js.map +0 -1
  375. package/dist/breakouts/events.d.ts +0 -8
  376. package/dist/breakouts/events.js +0 -44
  377. package/dist/breakouts/events.js.map +0 -1
  378. package/dist/breakouts/index.d.ts +0 -5
  379. package/dist/breakouts/index.js +0 -1047
  380. package/dist/breakouts/index.js.map +0 -1
  381. package/dist/breakouts/request.d.ts +0 -22
  382. package/dist/breakouts/request.js +0 -77
  383. package/dist/breakouts/request.js.map +0 -1
  384. package/dist/breakouts/utils.d.ts +0 -15
  385. package/dist/breakouts/utils.js +0 -64
  386. package/dist/breakouts/utils.js.map +0 -1
  387. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  388. package/dist/common/errors/no-meeting-info.js +0 -50
  389. package/dist/common/errors/no-meeting-info.js.map +0 -1
  390. package/dist/common/errors/reclaim-host-role-errors.js.map +0 -1
  391. package/dist/controls-options-manager/types.d.ts +0 -43
  392. package/dist/controls-options-manager/types.js +0 -7
  393. package/dist/controls-options-manager/types.js.map +0 -1
  394. package/dist/interceptors/index.d.ts +0 -2
  395. package/dist/interceptors/index.js +0 -15
  396. package/dist/interceptors/index.js.map +0 -1
  397. package/dist/interceptors/locusRetry.d.ts +0 -27
  398. package/dist/interceptors/locusRetry.js +0 -94
  399. package/dist/interceptors/locusRetry.js.map +0 -1
  400. package/dist/interpretation/collection.d.ts +0 -5
  401. package/dist/interpretation/collection.js +0 -22
  402. package/dist/interpretation/collection.js.map +0 -1
  403. package/dist/interpretation/index.d.ts +0 -5
  404. package/dist/interpretation/index.js +0 -365
  405. package/dist/interpretation/index.js.map +0 -1
  406. package/dist/interpretation/siLanguage.d.ts +0 -5
  407. package/dist/interpretation/siLanguage.js +0 -24
  408. package/dist/interpretation/siLanguage.js.map +0 -1
  409. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  410. package/dist/meeting/locusMediaRequest.js +0 -291
  411. package/dist/meeting/locusMediaRequest.js.map +0 -1
  412. package/dist/meeting/request.type.d.ts +0 -11
  413. package/dist/meeting/request.type.js +0 -7
  414. package/dist/meeting/request.type.js.map +0 -1
  415. package/dist/meeting/voicea-meeting.d.ts +0 -20
  416. package/dist/meeting/voicea-meeting.js +0 -201
  417. package/dist/meeting/voicea-meeting.js.map +0 -1
  418. package/dist/meetings/meetings.types.d.ts +0 -4
  419. package/dist/meetings/meetings.types.js +0 -7
  420. package/dist/meetings/meetings.types.js.map +0 -1
  421. package/dist/member/types.d.ts +0 -32
  422. package/dist/member/types.js +0 -23
  423. package/dist/member/types.js.map +0 -1
  424. package/dist/multistream/mediaRequestManager.d.ts +0 -118
  425. package/dist/multistream/mediaRequestManager.js +0 -344
  426. package/dist/multistream/mediaRequestManager.js.map +0 -1
  427. package/dist/multistream/receiveSlot.d.ts +0 -68
  428. package/dist/multistream/receiveSlot.js +0 -200
  429. package/dist/multistream/receiveSlot.js.map +0 -1
  430. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  431. package/dist/multistream/receiveSlotManager.js +0 -174
  432. package/dist/multistream/receiveSlotManager.js.map +0 -1
  433. package/dist/multistream/remoteMedia.d.ts +0 -72
  434. package/dist/multistream/remoteMedia.js +0 -268
  435. package/dist/multistream/remoteMedia.js.map +0 -1
  436. package/dist/multistream/remoteMediaGroup.d.ts +0 -47
  437. package/dist/multistream/remoteMediaGroup.js +0 -267
  438. package/dist/multistream/remoteMediaGroup.js.map +0 -1
  439. package/dist/multistream/remoteMediaManager.d.ts +0 -285
  440. package/dist/multistream/remoteMediaManager.js +0 -1211
  441. package/dist/multistream/remoteMediaManager.js.map +0 -1
  442. package/dist/multistream/sendSlotManager.d.ts +0 -61
  443. package/dist/multistream/sendSlotManager.js +0 -236
  444. package/dist/multistream/sendSlotManager.js.map +0 -1
  445. package/dist/reachability/clusterReachability.d.ts +0 -109
  446. package/dist/reachability/clusterReachability.js +0 -357
  447. package/dist/reachability/clusterReachability.js.map +0 -1
  448. package/dist/reachability/util.d.ts +0 -8
  449. package/dist/reachability/util.js +0 -29
  450. package/dist/reachability/util.js.map +0 -1
  451. package/dist/reactions/constants.d.ts +0 -3
  452. package/dist/reactions/constants.js +0 -12
  453. package/dist/reactions/constants.js.map +0 -1
  454. package/dist/rtcMetrics/constants.d.ts +0 -4
  455. package/dist/rtcMetrics/constants.js +0 -11
  456. package/dist/rtcMetrics/constants.js.map +0 -1
  457. package/dist/rtcMetrics/index.d.ts +0 -54
  458. package/dist/rtcMetrics/index.js +0 -140
  459. package/dist/rtcMetrics/index.js.map +0 -1
  460. package/dist/webinar/collection.d.ts +0 -16
  461. package/dist/webinar/collection.js +0 -43
  462. package/dist/webinar/collection.js.map +0 -1
  463. package/dist/webinar/index.d.ts +0 -5
  464. package/dist/webinar/index.js +0 -68
  465. package/dist/webinar/index.js.map +0 -1
  466. package/src/annotation/annotation.types.ts +0 -50
  467. package/src/annotation/constants.ts +0 -36
  468. package/src/annotation/index.ts +0 -328
  469. package/src/breakouts/README.md +0 -220
  470. package/src/breakouts/breakout.ts +0 -188
  471. package/src/breakouts/collection.ts +0 -19
  472. package/src/breakouts/edit-lock-error.ts +0 -25
  473. package/src/breakouts/events.ts +0 -56
  474. package/src/breakouts/index.ts +0 -925
  475. package/src/breakouts/request.ts +0 -55
  476. package/src/breakouts/utils.ts +0 -57
  477. package/src/common/errors/no-meeting-info.ts +0 -24
  478. package/src/controls-options-manager/types.ts +0 -59
  479. package/src/index.ts +0 -44
  480. package/src/interceptors/index.ts +0 -3
  481. package/src/interceptors/locusRetry.ts +0 -67
  482. package/src/interpretation/README.md +0 -60
  483. package/src/interpretation/collection.ts +0 -19
  484. package/src/interpretation/index.ts +0 -332
  485. package/src/interpretation/siLanguage.ts +0 -18
  486. package/src/meeting/locusMediaRequest.ts +0 -313
  487. package/src/meeting/request.type.ts +0 -13
  488. package/src/meeting/voicea-meeting.ts +0 -161
  489. package/src/meetings/meetings.types.ts +0 -12
  490. package/src/member/types.ts +0 -38
  491. package/src/multistream/mediaRequestManager.ts +0 -440
  492. package/src/multistream/receiveSlot.ts +0 -184
  493. package/src/multistream/receiveSlotManager.ts +0 -166
  494. package/src/multistream/remoteMedia.ts +0 -254
  495. package/src/multistream/remoteMediaGroup.ts +0 -284
  496. package/src/multistream/remoteMediaManager.ts +0 -1145
  497. package/src/multistream/sendSlotManager.ts +0 -170
  498. package/src/reachability/clusterReachability.ts +0 -320
  499. package/src/reachability/util.ts +0 -24
  500. package/src/reactions/constants.ts +0 -4
  501. package/src/rtcMetrics/constants.ts +0 -3
  502. package/src/rtcMetrics/index.ts +0 -124
  503. package/src/webinar/collection.ts +0 -31
  504. package/src/webinar/index.ts +0 -62
  505. package/test/integration/spec/converged-space-meetings.js +0 -233
  506. package/test/unit/spec/annotation/index.ts +0 -418
  507. package/test/unit/spec/breakouts/breakout.ts +0 -237
  508. package/test/unit/spec/breakouts/collection.ts +0 -15
  509. package/test/unit/spec/breakouts/edit-lock-error.ts +0 -30
  510. package/test/unit/spec/breakouts/events.ts +0 -89
  511. package/test/unit/spec/breakouts/index.ts +0 -1790
  512. package/test/unit/spec/breakouts/request.ts +0 -104
  513. package/test/unit/spec/breakouts/utils.js +0 -72
  514. package/test/unit/spec/interceptors/locusRetry.ts +0 -131
  515. package/test/unit/spec/interpretation/collection.ts +0 -15
  516. package/test/unit/spec/interpretation/index.ts +0 -589
  517. package/test/unit/spec/interpretation/siLanguage.ts +0 -28
  518. package/test/unit/spec/locus-info/mediaSharesUtils.ts +0 -32
  519. package/test/unit/spec/media/index.ts +0 -290
  520. package/test/unit/spec/meeting/locusMediaRequest.ts +0 -442
  521. package/test/unit/spec/meeting-info/index.js +0 -300
  522. package/test/unit/spec/multistream/mediaRequestManager.ts +0 -1418
  523. package/test/unit/spec/multistream/receiveSlot.ts +0 -163
  524. package/test/unit/spec/multistream/receiveSlotManager.ts +0 -203
  525. package/test/unit/spec/multistream/remoteMedia.ts +0 -255
  526. package/test/unit/spec/multistream/remoteMediaGroup.ts +0 -662
  527. package/test/unit/spec/multistream/remoteMediaManager.ts +0 -1924
  528. package/test/unit/spec/multistream/sendSlotManager.ts +0 -242
  529. package/test/unit/spec/reachability/clusterReachability.ts +0 -279
  530. package/test/unit/spec/reachability/request.js +0 -68
  531. package/test/unit/spec/reachability/util.ts +0 -40
  532. package/test/unit/spec/roap/request.ts +0 -255
  533. package/test/unit/spec/rtcMetrics/index.ts +0 -93
  534. package/test/unit/spec/webinar/collection.ts +0 -13
  535. package/test/unit/spec/webinar/index.ts +0 -60
  536. package/test/utils/constants.js +0 -9
  537. package/test/utils/integrationTestUtils.js +0 -46
  538. /package/dist/common/errors/{reclaim-host-role-errors.d.ts → reclaim-host-role-error.d.ts} +0 -0
  539. /package/src/common/errors/{reclaim-host-role-errors.ts → reclaim-host-role-error.ts} +0 -0
@@ -1,24 +1,18 @@
1
1
  /* eslint-disable prefer-destructuring */
2
2
 
3
- import {cloneDeep, isEmpty} from 'lodash';
4
- import {ConnectionState} from '@webex/internal-media-core';
3
+ import {cloneDeep} from 'lodash';
5
4
 
6
5
  import EventsScope from '../common/events/events-scope';
7
6
  import {
8
7
  DEFAULT_GET_STATS_FILTER,
8
+ CONNECTION_STATE,
9
9
  STATS,
10
- MQA_INTERVAL,
10
+ MQA_INTEVAL,
11
11
  NETWORK_TYPE,
12
12
  MEDIA_DEVICES,
13
13
  _UNKNOWN_,
14
14
  } from '../constants';
15
- import {
16
- emptyAudioReceive,
17
- emptyAudioTransmit,
18
- emptyMqaInterval,
19
- emptyVideoReceive,
20
- emptyVideoTransmit,
21
- } from '../mediaQualityMetrics/config';
15
+ import mqaData from '../mediaQualityMetrics/config';
22
16
  import LoggerProxy from '../common/logs/logger-proxy';
23
17
 
24
18
  import defaultStats from './global';
@@ -28,34 +22,17 @@ import {
28
22
  getVideoSenderMqa,
29
23
  getVideoReceiverMqa,
30
24
  } from './mqaUtil';
31
- import {ReceiveSlot} from '../multistream/receiveSlot';
32
25
 
33
26
  export const EVENTS = {
34
27
  MEDIA_QUALITY: 'MEDIA_QUALITY',
28
+ NO_FRAMES_SENT: 'NO_FRAMES_SENT',
29
+ NO_VIDEO_ENCODED: 'NO_VIDEO_ENCODED',
35
30
  LOCAL_MEDIA_STARTED: 'LOCAL_MEDIA_STARTED',
36
31
  LOCAL_MEDIA_STOPPED: 'LOCAL_MEDIA_STOPPED',
37
32
  REMOTE_MEDIA_STARTED: 'REMOTE_MEDIA_STARTED',
38
33
  REMOTE_MEDIA_STOPPED: 'REMOTE_MEDIA_STOPPED',
39
34
  };
40
35
 
41
- const emptySender = {
42
- trackLabel: '',
43
- maxPacketLossRatio: 0,
44
- availableBandwidth: 0,
45
- bytesSent: 0,
46
- meanRemoteJitter: [],
47
- meanRoundTripTime: [],
48
- };
49
-
50
- const emptyReceiver = {
51
- availableBandwidth: 0,
52
- bytesReceived: 0,
53
- meanRtpJitter: [],
54
- meanRoundTripTime: [],
55
- };
56
-
57
- type ReceiveSlotCallback = (csi: number) => ReceiveSlot | undefined;
58
-
59
36
  /**
60
37
  * Stats Analyzer class that will emit events based on detected quality
61
38
  *
@@ -69,30 +46,26 @@ export class StatsAnalyzer extends EventsScope {
69
46
  lastEmittedStartStopEvent: any;
70
47
  lastMqaDataSent: any;
71
48
  lastStatsResults: any;
49
+ localMQEStats: any;
72
50
  meetingMediaStatus: any;
73
51
  mqaInterval: NodeJS.Timeout;
74
52
  mqaSentCount: any;
75
53
  networkQualityMonitor: any;
76
- mediaConnection: any;
54
+ peerConnection: any;
77
55
  statsInterval: NodeJS.Timeout;
78
56
  statsResults: any;
79
57
  statsStarted: any;
80
- successfulCandidatePair: any;
81
- localIpAddress: string; // Returns the local IP address for diagnostics. this is the local IP of the interface used for the current media connection a host can have many local Ip Addresses
82
- receiveSlotCallback: ReceiveSlotCallback;
83
58
 
84
59
  /**
85
60
  * Creates a new instance of StatsAnalyzer
86
61
  * @constructor
87
62
  * @public
88
63
  * @param {Object} config SDK Configuration Object
89
- * @param {Function} receiveSlotCallback Callback used to access receive slots.
90
64
  * @param {Object} networkQualityMonitor class for assessing network characteristics (jitter, packetLoss, latency)
91
65
  * @param {Object} statsResults Default properties for stats
92
66
  */
93
67
  constructor(
94
68
  config: any,
95
- receiveSlotCallback: ReceiveSlotCallback = () => undefined,
96
69
  networkQualityMonitor: object = {},
97
70
  statsResults: object = defaultStats
98
71
  ) {
@@ -104,31 +77,147 @@ export class StatsAnalyzer extends EventsScope {
104
77
  this.networkQualityMonitor = networkQualityMonitor;
105
78
  this.correlationId = config.correlationId;
106
79
  this.mqaSentCount = -1;
107
- this.lastMqaDataSent = {};
108
- this.lastEmittedStartStopEvent = {};
109
- this.receiveSlotCallback = receiveSlotCallback;
110
- this.successfulCandidatePair = {};
111
- this.localIpAddress = '';
80
+ this.lastMqaDataSent = {
81
+ resolutions: {
82
+ video: {send: {}, recv: {}},
83
+ audio: {send: {}, recv: {}},
84
+ share: {send: {}, recv: {}},
85
+ },
86
+ video: {send: {}, recv: {}},
87
+ audio: {send: {}, recv: {}},
88
+ share: {send: {}, recv: {}},
89
+ };
90
+ this.localMQEStats = {
91
+ audio: {
92
+ RX: {
93
+ packetsLost: [],
94
+ jitter: [],
95
+ latency: [],
96
+ bitRate: [],
97
+ },
98
+ TX: {
99
+ packetsLost: [],
100
+ jitter: [],
101
+ latency: [],
102
+ bitRate: [],
103
+ },
104
+ },
105
+ video: {
106
+ RX: {
107
+ packetsLost: [],
108
+ jitter: [],
109
+ latency: [],
110
+ bitRate: [],
111
+ frameRate: [],
112
+ resolutionWidth: [],
113
+ resolutionHeight: [],
114
+ requestedKeyFrame: [],
115
+ receivedKeyFrame: [],
116
+ },
117
+ TX: {
118
+ packetsLost: [],
119
+ jitter: [],
120
+ latency: [],
121
+ bitRate: [],
122
+ frameRate: [],
123
+ resolutionWidth: [],
124
+ resolutionHeight: [],
125
+ requestedKeyFrame: [],
126
+ receivedKeyFrame: [],
127
+ },
128
+ },
129
+ };
130
+ this.lastEmittedStartStopEvent = {
131
+ audio: {
132
+ local: undefined,
133
+ remote: undefined,
134
+ },
135
+ video: {
136
+ local: undefined,
137
+ remote: undefined,
138
+ },
139
+ share: {
140
+ local: undefined,
141
+ remote: undefined,
142
+ },
143
+ };
144
+ }
145
+
146
+ populateResults(lastMqa) {
147
+ // Audio
148
+
149
+ this.localMQEStats.audio.RX.packetsLost.push(lastMqa.audioReceive[0].common.mediaHopByHopLost);
150
+ this.localMQEStats.audio.RX.jitter.push(lastMqa.audioReceive[0].streams[0].common.rtpJitter);
151
+ this.localMQEStats.audio.RX.latency.push(lastMqa.audioReceive[0].common.roundTripTime);
152
+ this.localMQEStats.audio.RX.bitRate.push(
153
+ lastMqa.audioReceive[0].streams[0].common.receivedBitrate
154
+ );
155
+
156
+ this.localMQEStats.audio.TX.packetsLost.push(lastMqa.audioTransmit[0].common.remoteLossRate);
157
+ this.localMQEStats.audio.TX.jitter.push(lastMqa.audioTransmit[0].common.remoteJitter);
158
+ this.localMQEStats.audio.TX.latency.push(lastMqa.audioTransmit[0].common.roundTripTime);
159
+ this.localMQEStats.audio.TX.bitRate.push(
160
+ lastMqa.audioTransmit[0].streams[0].common.transmittedBitrate
161
+ );
162
+
163
+ // Video
164
+
165
+ this.localMQEStats.video.RX.packetsLost.push(lastMqa.videoReceive[0].common.mediaHopByHopLost);
166
+ this.localMQEStats.video.RX.jitter.push(lastMqa.videoReceive[0].streams[0].common.rtpJitter);
167
+ this.localMQEStats.video.RX.latency.push(
168
+ lastMqa.videoReceive[0].streams[0].common.roundTripTime
169
+ );
170
+ this.localMQEStats.video.RX.bitRate.push(
171
+ lastMqa.videoReceive[0].streams[0].common.receivedBitrate
172
+ );
173
+ this.localMQEStats.video.RX.frameRate.push(
174
+ lastMqa.videoReceive[0].streams[0].common.receivedFrameRate
175
+ );
176
+ this.localMQEStats.video.RX.resolutionWidth.push(
177
+ lastMqa.videoReceive[0].streams[0].receivedWidth
178
+ );
179
+ this.localMQEStats.video.RX.resolutionHeight.push(
180
+ lastMqa.videoReceive[0].streams[0].receivedHeight
181
+ );
182
+ this.localMQEStats.video.RX.requestedKeyFrame.push();
183
+ this.localMQEStats.video.RX.receivedKeyFrame.push();
184
+
185
+ this.localMQEStats.video.TX.packetsLost.push(lastMqa.videoTransmit[0].common.remoteLossRate);
186
+ this.localMQEStats.video.TX.jitter.push(lastMqa.videoTransmit[0].common.remoteJitter);
187
+ this.localMQEStats.video.TX.latency.push(lastMqa.videoTransmit[0].common.roundTripTime);
188
+ this.localMQEStats.video.TX.bitRate.push(
189
+ lastMqa.videoTransmit[0].streams[0].common.transmittedBitrate
190
+ );
191
+ this.localMQEStats.video.TX.frameRate.push(
192
+ lastMqa.videoTransmit[0].streams[0].common.transmittedFrameRate
193
+ );
194
+ this.localMQEStats.video.TX.resolutionWidth.push(
195
+ lastMqa.videoTransmit[0].streams[0].transmittedWidth
196
+ );
197
+ this.localMQEStats.video.TX.resolutionHeight.push(
198
+ lastMqa.videoTransmit[0].streams[0].transmittedHeight
199
+ );
200
+ this.localMQEStats.video.TX.requestedKeyFrame.push(
201
+ lastMqa.videoTransmit[0].streams[0].requestedKeyFrames
202
+ );
203
+ this.localMQEStats.video.TX.receivedKeyFrame.push();
112
204
  }
113
205
 
114
- /**
115
- * Resets cumulative stats arrays.
116
- *
117
- * @public
118
- * @memberof StatsAnalyzer
119
- * @returns {void}
120
- */
121
206
  resetStatsResults() {
122
- Object.keys(this.statsResults).forEach((mediaType) => {
123
- if (mediaType.includes('recv')) {
124
- this.statsResults[mediaType].recv.meanRtpJitter = [];
125
- }
207
+ this.statsResults.audio.send.meanRemoteJitter = [];
208
+ this.statsResults.video.send.meanRemoteJitter = [];
209
+ this.statsResults.share.send.meanRemoteJitter = [];
126
210
 
127
- if (mediaType.includes('send')) {
128
- this.statsResults[mediaType].send.meanRemoteJitter = [];
129
- this.statsResults[mediaType].send.meanRoundTripTime = [];
130
- }
131
- });
211
+ this.statsResults.audio.recv.meanRtpJitter = [];
212
+
213
+ // TODO: currently no values are present
214
+ this.statsResults.video.recv.meanRtpJitter = [];
215
+ this.statsResults.share.recv.meanRtpJitter = [];
216
+
217
+ // Reset the roundTripTime
218
+ this.statsResults.audio.send.meanRoundTripTime = [];
219
+ this.statsResults.video.send.meanRoundTripTime = [];
220
+ this.statsResults.share.send.meanRoundTripTime = [];
132
221
  }
133
222
 
134
223
  /**
@@ -144,101 +233,86 @@ export class StatsAnalyzer extends EventsScope {
144
233
  }
145
234
 
146
235
  /**
147
- * captures MQA data from media connection
236
+ * captures MQA data from peerconnection
148
237
  *
149
238
  * @public
150
239
  * @memberof StatsAnalyzer
151
240
  * @returns {void}
152
241
  */
153
- sendMqaData() {
154
- const newMqa = cloneDeep(emptyMqaInterval);
155
-
156
- Object.keys(this.statsResults).forEach((mediaType) => {
157
- if (!this.lastMqaDataSent[mediaType]) {
158
- this.lastMqaDataSent[mediaType] = {};
159
- }
160
-
161
- if (!this.lastMqaDataSent[mediaType].send && mediaType.includes('-send')) {
162
- this.lastMqaDataSent[mediaType].send = {};
163
- }
164
-
165
- if (!this.lastMqaDataSent[mediaType].recv && mediaType.includes('-recv')) {
166
- this.lastMqaDataSent[mediaType].recv = {};
167
- }
168
-
169
- if (mediaType.includes('audio-send') || mediaType.includes('audio-share-send')) {
170
- const audioSender = cloneDeep(emptyAudioTransmit);
171
-
172
- getAudioSenderMqa({
173
- audioSender,
174
- statsResults: this.statsResults,
175
- lastMqaDataSent: this.lastMqaDataSent,
176
- mediaType,
177
- });
178
- newMqa.audioTransmit.push(audioSender);
179
-
180
- this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
181
- } else if (mediaType.includes('audio-recv') || mediaType.includes('audio-share-recv')) {
182
- const audioReceiver = cloneDeep(emptyAudioReceive);
183
-
184
- getAudioReceiverMqa({
185
- audioReceiver,
186
- statsResults: this.statsResults,
187
- lastMqaDataSent: this.lastMqaDataSent,
188
- mediaType,
189
- });
190
- newMqa.audioReceive.push(audioReceiver);
191
-
192
- this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
193
- } else if (mediaType.includes('video-send') || mediaType.includes('video-share-send')) {
194
- const videoSender = cloneDeep(emptyVideoTransmit);
195
-
196
- getVideoSenderMqa({
197
- videoSender,
198
- statsResults: this.statsResults,
199
- lastMqaDataSent: this.lastMqaDataSent,
200
- mediaType,
201
- });
202
- newMqa.videoTransmit.push(videoSender);
242
+ public sendMqaData() {
243
+ const audioReceiver = mqaData.intervals[0].audioReceive[0];
244
+ const audioSender = mqaData.intervals[0].audioTransmit[0];
245
+ const videoReceiver = mqaData.intervals[0].videoReceive[0];
246
+ const videoSender = mqaData.intervals[0].videoTransmit[0];
247
+ const shareSender = mqaData.intervals[0].videoTransmit[1];
248
+ const shareReceiver = mqaData.intervals[0].videoReceive[1];
249
+
250
+ getAudioSenderMqa({
251
+ audioSender,
252
+ statsResults: this.statsResults,
253
+ lastMqaDataSent: this.lastMqaDataSent,
254
+ });
255
+ getAudioReceiverMqa({
256
+ audioReceiver,
257
+ statsResults: this.statsResults,
258
+ lastMqaDataSent: this.lastMqaDataSent,
259
+ });
203
260
 
204
- this.lastMqaDataSent[mediaType].send = cloneDeep(this.statsResults[mediaType].send);
205
- } else if (mediaType.includes('video-recv') || mediaType.includes('video-share-recv')) {
206
- const videoReceiver = cloneDeep(emptyVideoReceive);
261
+ getVideoReceiverMqa({
262
+ videoReceiver,
263
+ statsResults: this.statsResults,
264
+ lastMqaDataSent: this.lastMqaDataSent,
265
+ });
266
+ getVideoSenderMqa({
267
+ videoSender,
268
+ statsResults: this.statsResults,
269
+ lastMqaDataSent: this.lastMqaDataSent,
270
+ });
207
271
 
208
- getVideoReceiverMqa({
209
- videoReceiver,
210
- statsResults: this.statsResults,
211
- lastMqaDataSent: this.lastMqaDataSent,
212
- mediaType,
213
- });
214
- newMqa.videoReceive.push(videoReceiver);
272
+ // Capture mqa for share scenario
215
273
 
216
- this.lastMqaDataSent[mediaType].recv = cloneDeep(this.statsResults[mediaType].recv);
217
- }
274
+ getVideoSenderMqa({
275
+ videoSender: shareSender,
276
+ statsResults: this.statsResults,
277
+ lastMqaDataSent: this.lastMqaDataSent,
278
+ isShareStream: true,
218
279
  });
219
280
 
220
- newMqa.intervalMetadata.peerReflexiveIP = this.statsResults.connectionType.local.ipAddress;
281
+ getVideoReceiverMqa({
282
+ videoReceiver: shareReceiver,
283
+ statsResults: this.statsResults,
284
+ lastMqaDataSent: this.lastMqaDataSent,
285
+ isShareStream: true,
286
+ });
287
+ mqaData.intervals[0].intervalMetadata.peerReflexiveIP =
288
+ this.statsResults.connectionType.local.ipAddress[0];
221
289
 
222
290
  // Adding peripheral information
223
- newMqa.intervalMetadata.peripherals.push({information: _UNKNOWN_, name: MEDIA_DEVICES.SPEAKER});
224
- if (this.statsResults['audio-send']) {
225
- newMqa.intervalMetadata.peripherals.push({
226
- information: this.statsResults['audio-send'].trackLabel || _UNKNOWN_,
227
- name: MEDIA_DEVICES.MICROPHONE,
228
- });
229
- }
230
- if (this.statsResults['video-send']) {
231
- newMqa.intervalMetadata.peripherals.push({
232
- information: this.statsResults['video-send'].trackLabel || _UNKNOWN_,
233
- name: MEDIA_DEVICES.CAMERA,
234
- });
235
- }
291
+ mqaData.intervals[0].intervalMetadata.peripherals = [];
292
+ mqaData.intervals[0].intervalMetadata.peripherals.push({
293
+ information: _UNKNOWN_,
294
+ name: MEDIA_DEVICES.SPEAKER,
295
+ });
296
+ mqaData.intervals[0].intervalMetadata.peripherals.push({
297
+ information: this.peerConnection?.audioTransceiver?.sender?.track?.label || _UNKNOWN_,
298
+ name: MEDIA_DEVICES.MICROPHONE,
299
+ });
300
+ mqaData.intervals[0].intervalMetadata.peripherals.push({
301
+ information: this.peerConnection?.videoTransceiver?.sender?.track?.label || _UNKNOWN_,
302
+ name: MEDIA_DEVICES.CAMERA,
303
+ });
236
304
 
237
- newMqa.networkType = this.statsResults.connectionType.local.networkType;
305
+ // @ts-ignore
306
+ mqaData.networkType = this.statsResults.connectionType.local.networkType;
238
307
 
239
308
  this.mqaSentCount += 1;
240
309
 
241
- newMqa.intervalNumber = this.mqaSentCount;
310
+ mqaData.intervals[0].intervalNumber = this.mqaSentCount;
311
+
312
+ // DO Deep copy, for some reason it takes the reference all the time rather then old value set
313
+ this.lastMqaDataSent = cloneDeep(this.statsResults);
314
+
315
+ this.populateResults(mqaData.intervals[0]);
242
316
 
243
317
  this.resetStatsResults();
244
318
 
@@ -249,33 +323,23 @@ export class StatsAnalyzer extends EventsScope {
249
323
  },
250
324
  EVENTS.MEDIA_QUALITY,
251
325
  {
252
- data: newMqa,
326
+ data: mqaData.intervals[0],
253
327
  // @ts-ignore
254
- networkType: newMqa.networkType,
328
+ networkType: mqaData.networkType,
255
329
  }
256
330
  );
257
331
  }
258
332
 
259
333
  /**
260
- * updated the media connection when changed
334
+ * updated the peerconnection when changed
261
335
  *
262
336
  * @private
263
- * @memberof StatsAnalyzer
264
- * @param {RoapMediaConnection} mediaConnection
337
+ * @memberof updatePeerconnection
338
+ * @param {PeerConnection} peerConnection
265
339
  * @returns {void}
266
340
  */
267
- updateMediaConnection(mediaConnection: any) {
268
- this.mediaConnection = mediaConnection;
269
- }
270
-
271
- /**
272
- * Returns the local IP address for diagnostics.
273
- * this is the local IP of the interface used for the current media connection
274
- * a host can have many local Ip Addresses
275
- * @returns {string | undefined} The local IP address.
276
- */
277
- getLocalIpAddress(): string {
278
- return this.localIpAddress;
341
+ updatePeerconnection(peerConnection: any) {
342
+ this.peerConnection = peerConnection;
279
343
  }
280
344
 
281
345
  /**
@@ -283,13 +347,13 @@ export class StatsAnalyzer extends EventsScope {
283
347
  *
284
348
  * @public
285
349
  * @memberof StatsAnalyzer
286
- * @param {RoapMediaConnection} mediaConnection
350
+ * @param {PeerConnection} peerConnection
287
351
  * @returns {Promise}
288
352
  */
289
- public startAnalyzer(mediaConnection: any) {
353
+ public startAnalyzer(peerConnection: any) {
290
354
  if (!this.statsStarted) {
291
355
  this.statsStarted = true;
292
- this.mediaConnection = mediaConnection;
356
+ this.peerConnection = peerConnection;
293
357
 
294
358
  return this.getStatsAndParse().then(() => {
295
359
  this.statsInterval = setInterval(() => {
@@ -299,7 +363,7 @@ export class StatsAnalyzer extends EventsScope {
299
363
  this.sendMqaData();
300
364
  this.mqaInterval = setInterval(() => {
301
365
  this.sendMqaData();
302
- }, MQA_INTERVAL);
366
+ }, MQA_INTEVAL);
303
367
  });
304
368
  }
305
369
 
@@ -329,7 +393,7 @@ export class StatsAnalyzer extends EventsScope {
329
393
  if (sendOneLastMqa) {
330
394
  return this.getStatsAndParse().then(() => {
331
395
  this.sendMqaData();
332
- this.mediaConnection = null;
396
+ this.peerConnection = null;
333
397
  });
334
398
  }
335
399
 
@@ -351,17 +415,6 @@ export class StatsAnalyzer extends EventsScope {
351
415
  return;
352
416
  }
353
417
 
354
- // Generate empty stats results
355
- if (!this.statsResults[type]) {
356
- this.statsResults[type] = {};
357
- }
358
-
359
- if (isSender && !this.statsResults[type].send) {
360
- this.statsResults[type].send = cloneDeep(emptySender);
361
- } else if (!isSender && !this.statsResults[type].recv) {
362
- this.statsResults[type].recv = cloneDeep(emptyReceiver);
363
- }
364
-
365
418
  switch (getStatsResult.type) {
366
419
  case 'outbound-rtp':
367
420
  this.processOutboundRTPResult(getStatsResult, type);
@@ -371,7 +424,8 @@ export class StatsAnalyzer extends EventsScope {
371
424
  break;
372
425
  case 'remote-inbound-rtp':
373
426
  case 'remote-outbound-rtp':
374
- this.compareSentAndReceived(getStatsResult, type);
427
+ // @ts-ignore
428
+ this.compareSentAndReceived(getStatsResult, type, isSender);
375
429
  break;
376
430
  case 'remotecandidate':
377
431
  case 'remote-candidate':
@@ -392,38 +446,23 @@ export class StatsAnalyzer extends EventsScope {
392
446
  /**
393
447
  * Filters the get stats results for types
394
448
  * @private
395
- * @param {Array} statsItem
449
+ * @param {Array} getStatsResults
396
450
  * @param {String} type
397
451
  * @param {boolean} isSender
398
452
  * @returns {void}
399
453
  */
400
- filterAndParseGetStatsResults(statsItem: any, type: string, isSender: boolean) {
454
+ private filterAndParseGetStatsResults(
455
+ getStatsResults: Array<any>,
456
+ type: string,
457
+ isSender: boolean
458
+ ) {
401
459
  const {types} = DEFAULT_GET_STATS_FILTER;
402
460
 
403
- // get the successful candidate pair before parsing stats.
404
- statsItem.report.forEach((report) => {
405
- if (report.type === 'candidate-pair' && report.state === 'succeeded') {
406
- this.successfulCandidatePair = report;
407
- }
408
- });
409
-
410
- statsItem.report.forEach((result) => {
461
+ getStatsResults.forEach((result) => {
411
462
  if (types.includes(result.type)) {
412
463
  this.parseGetStatsResult(result, type, isSender);
413
464
  }
414
465
  });
415
-
416
- if (this.statsResults[type]) {
417
- this.statsResults[type].direction = statsItem.currentDirection;
418
- this.statsResults[type].trackLabel = statsItem.localTrackLabel;
419
- this.statsResults[type].csi = statsItem.csi;
420
- this.extractAndSetLocalIpAddressInfoForDiagnostics(
421
- this.successfulCandidatePair?.localCandidateId,
422
- this.statsResults?.candidates
423
- );
424
- // reset the successful candidate pair.
425
- this.successfulCandidatePair = {};
426
- }
427
466
  }
428
467
 
429
468
  /**
@@ -437,7 +476,7 @@ export class StatsAnalyzer extends EventsScope {
437
476
  return;
438
477
  }
439
478
 
440
- if (type.includes('audio-send')) {
479
+ if (type === STATS.AUDIO_CORRELATE) {
441
480
  this.statsResults[type].send.audioLevel = result.audioLevel;
442
481
  this.statsResults[type].send.totalAudioEnergy = result.totalAudioEnergy;
443
482
  }
@@ -472,10 +511,6 @@ export class StatsAnalyzer extends EventsScope {
472
511
  // eslint-disable-next-line no-param-reassign
473
512
  if (currentValue === undefined) currentValue = 0;
474
513
 
475
- if (!this.lastEmittedStartStopEvent[mediaType]) {
476
- this.lastEmittedStartStopEvent[mediaType] = {};
477
- }
478
-
479
514
  const lastEmittedEvent = isLocal
480
515
  ? this.lastEmittedStartStopEvent[mediaType].local
481
516
  : this.lastEmittedStartStopEvent[mediaType].remote;
@@ -484,7 +519,7 @@ export class StatsAnalyzer extends EventsScope {
484
519
 
485
520
  if (currentValue - previousValue > 0) {
486
521
  newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STARTED : EVENTS.REMOTE_MEDIA_STARTED;
487
- } else if (currentValue === previousValue && currentValue > 0) {
522
+ } else if (currentValue === previousValue && currentValue >= 0) {
488
523
  newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STOPPED : EVENTS.REMOTE_MEDIA_STOPPED;
489
524
  }
490
525
 
@@ -516,29 +551,21 @@ export class StatsAnalyzer extends EventsScope {
516
551
  */
517
552
  private compareLastStatsResult() {
518
553
  if (this.lastStatsResults !== null && this.meetingMediaStatus) {
519
- const getCurrentStatsTotals = (keyPrefix: string, value: string): number =>
520
- Object.keys(this.statsResults)
521
- .filter((key) => key.startsWith(keyPrefix))
522
- .reduce((prev, cur) => prev + (this.statsResults[cur]?.recv[value] || 0), 0);
523
-
524
- const getPreviousStatsTotals = (keyPrefix: string, value: string): number =>
525
- Object.keys(this.statsResults)
526
- .filter((key) => key.startsWith(keyPrefix))
527
- .reduce((prev, cur) => prev + (this.lastStatsResults[cur]?.recv[value] || 0), 0);
528
-
529
- if (this.meetingMediaStatus.expected.sendAudio && this.lastStatsResults['audio-send']) {
530
- // compare audio stats sent
531
- // NOTE: relies on there being only one sender.
532
- const currentStats = this.statsResults['audio-send'].send;
533
- const previousStats = this.lastStatsResults['audio-send'].send;
554
+ // compare audio stats sent
555
+ let mediaType = STATS.AUDIO_CORRELATE;
556
+ let currentStats = null;
557
+ let previousStats = null;
558
+
559
+ if (this.meetingMediaStatus.expected.sendAudio) {
560
+ currentStats = this.statsResults[mediaType].send;
561
+ previousStats = this.lastStatsResults[mediaType].send;
534
562
 
535
563
  if (
536
564
  currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
537
565
  currentStats.totalPacketsSent === 0
538
566
  ) {
539
567
  LoggerProxy.logger.info(
540
- `StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent`,
541
- currentStats.totalPacketsSent
568
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets sent`
542
569
  );
543
570
  } else {
544
571
  if (
@@ -546,20 +573,19 @@ export class StatsAnalyzer extends EventsScope {
546
573
  currentStats.totalAudioEnergy === 0
547
574
  ) {
548
575
  LoggerProxy.logger.info(
549
- `StatsAnalyzer:index#compareLastStatsResult --> No audio Energy present`,
550
- currentStats.totalAudioEnergy
576
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Energy present`
551
577
  );
552
578
  }
553
579
 
554
580
  if (currentStats.audioLevel === 0) {
555
581
  LoggerProxy.logger.info(
556
- `StatsAnalyzer:index#compareLastStatsResult --> audio level is 0 for the user`
582
+ `StatsAnalyzer:index#compareLastStatsResult --> ${mediaType} level is 0 for the user`
557
583
  );
558
584
  }
559
585
  }
560
586
 
561
587
  this.emitStartStopEvents(
562
- 'audio',
588
+ mediaType,
563
589
  previousStats.totalPacketsSent,
564
590
  currentStats.totalPacketsSent,
565
591
  true
@@ -568,199 +594,266 @@ export class StatsAnalyzer extends EventsScope {
568
594
 
569
595
  if (this.meetingMediaStatus.expected.receiveAudio) {
570
596
  // compare audio stats received
571
- const currentPacketsReceived = getCurrentStatsTotals('audio-recv', 'totalPacketsReceived');
572
- const previousPacketsReceived = getPreviousStatsTotals(
573
- 'audio-recv',
574
- 'totalPacketsReceived'
575
- );
576
- const currentSamplesReceived = getCurrentStatsTotals('audio-recv', 'totalSamplesReceived');
577
- const previousSamplesReceived = getPreviousStatsTotals(
578
- 'audio-recv',
579
- 'totalSamplesReceived'
580
- );
597
+ currentStats = this.statsResults[mediaType].recv;
598
+ previousStats = this.lastStatsResults[mediaType].recv;
581
599
 
582
- if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
600
+ if (
601
+ currentStats.totalPacketsReceived === previousStats.totalPacketsReceived ||
602
+ currentStats.totalPacketsReceived === 0
603
+ ) {
583
604
  LoggerProxy.logger.info(
584
- `StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received`,
585
- currentPacketsReceived
605
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets received`
586
606
  );
587
607
  } else if (
588
- currentSamplesReceived === previousSamplesReceived ||
589
- currentSamplesReceived === 0
608
+ currentStats.totalSamplesReceived === previousStats.totalSamplesReceived ||
609
+ currentStats.totalSamplesReceived === 0
590
610
  ) {
591
611
  LoggerProxy.logger.info(
592
- `StatsAnalyzer:index#compareLastStatsResult --> No audio samples received`,
593
- currentSamplesReceived
612
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} samples received`
594
613
  );
595
614
  }
596
615
 
597
- this.emitStartStopEvents('audio', previousPacketsReceived, currentPacketsReceived, false);
616
+ this.emitStartStopEvents(
617
+ mediaType,
618
+ previousStats.totalPacketsReceived,
619
+ currentStats.totalPacketsReceived,
620
+ false
621
+ );
598
622
  }
599
623
 
600
- if (this.meetingMediaStatus.expected.sendVideo && this.lastStatsResults['video-send']) {
624
+ mediaType = STATS.VIDEO_CORRELATE;
625
+ if (this.meetingMediaStatus.expected.sendVideo) {
601
626
  // compare video stats sent
602
- const currentStats = this.statsResults['video-send'].send;
603
- const previousStats = this.lastStatsResults['video-send'].send;
627
+ currentStats = this.statsResults[mediaType].send;
628
+ previousStats = this.lastStatsResults[mediaType].send;
604
629
 
605
630
  if (
606
631
  currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
607
632
  currentStats.totalPacketsSent === 0
608
633
  ) {
609
634
  LoggerProxy.logger.info(
610
- `StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent`,
611
- currentStats.totalPacketsSent
635
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets sent`
612
636
  );
613
- } else {
637
+ } else if (this.lastEmittedStartStopEvent[mediaType].local !== EVENTS.LOCAL_MEDIA_STOPPED) {
614
638
  if (
615
639
  currentStats.framesEncoded === previousStats.framesEncoded ||
616
640
  currentStats.framesEncoded === 0
617
641
  ) {
642
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
618
643
  LoggerProxy.logger.info(
619
- `StatsAnalyzer:index#compareLastStatsResult --> No video Frames Encoded`,
620
- currentStats.framesEncoded
644
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Frames Encoded`
645
+ );
646
+ this.emit(
647
+ {
648
+ file: 'statsAnalyzer',
649
+ function: 'compareLastStatsResult',
650
+ },
651
+ EVENTS.NO_VIDEO_ENCODED,
652
+ {
653
+ mediaType,
654
+ }
621
655
  );
622
656
  }
623
657
 
624
658
  if (
625
- this.statsResults['video-send'].send.framesSent ===
626
- this.lastStatsResults['video-send'].send.framesSent ||
627
- this.statsResults['video-send'].send.framesSent === 0
659
+ this.statsResults.resolutions[mediaType].send.framesSent ===
660
+ this.lastStatsResults.resolutions[mediaType].send.framesSent ||
661
+ this.statsResults.resolutions[mediaType].send.framesSent === 0
628
662
  ) {
629
663
  LoggerProxy.logger.info(
630
- `StatsAnalyzer:index#compareLastStatsResult --> No video Frames sent`,
631
- this.statsResults['video-send'].send.framesSent
664
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Frames sent`
632
665
  );
633
666
  }
634
- }
635
667
 
636
- this.emitStartStopEvents('video', previousStats.framesSent, currentStats.framesSent, true);
668
+ // Video is encoded but frames are not sent
669
+ if (
670
+ currentStats.framesEncoded !== previousStats.framesEncoded &&
671
+ (currentStats.framesSent === previousStats.framesSent || currentStats.framesSent === 0)
672
+ ) {
673
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
674
+ LoggerProxy.logger.info(
675
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames sent even though frames are encoded`
676
+ );
677
+ this.emit(
678
+ {
679
+ file: 'statsAnalyzer',
680
+ function: 'compareLastStatsResult',
681
+ },
682
+ EVENTS.NO_FRAMES_SENT,
683
+ {
684
+ mediaType,
685
+ }
686
+ );
687
+ }
688
+ }
689
+ this.emitStartStopEvents(
690
+ mediaType,
691
+ previousStats.framesSent,
692
+ currentStats.framesSent,
693
+ true
694
+ );
637
695
  }
638
696
 
639
697
  if (this.meetingMediaStatus.expected.receiveVideo) {
640
- // compare video stats received
641
- const currentPacketsReceived = getCurrentStatsTotals('video-recv', 'totalPacketsReceived');
642
- const previousPacketsReceived = getPreviousStatsTotals(
643
- 'video-recv',
644
- 'totalPacketsReceived'
645
- );
646
- const currentFramesReceived = getCurrentStatsTotals('video-recv', 'framesReceived');
647
- const previousFramesReceived = getPreviousStatsTotals('video-recv', 'framesReceived');
648
- const currentFramesDecoded = getCurrentStatsTotals('video-recv', 'framesDecoded');
649
- const previousFramesDecoded = getPreviousStatsTotals('video-recv', 'framesDecoded');
650
- const currentFramesDropped = getCurrentStatsTotals('video-recv', 'framesDropped');
651
- const previousFramesDropped = getPreviousStatsTotals('video-recv', 'framesDropped');
652
-
653
- if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
698
+ // compare video stats reveived
699
+
700
+ currentStats = this.statsResults[mediaType].recv;
701
+ previousStats = this.lastStatsResults[mediaType].recv;
702
+
703
+ if (
704
+ currentStats.totalPacketsReceived === previousStats.totalPacketsReceived ||
705
+ currentStats.totalPacketsReceived === 0
706
+ ) {
654
707
  LoggerProxy.logger.info(
655
- `StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets received`,
656
- currentPacketsReceived
708
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets received`
657
709
  );
658
710
  } else {
659
- if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
711
+ if (
712
+ this.statsResults.resolutions[mediaType].recv.framesReceived ===
713
+ this.lastStatsResults.resolutions[mediaType].recv.framesReceived ||
714
+ this.statsResults.resolutions[mediaType].recv.framesReceived === 0
715
+ ) {
660
716
  LoggerProxy.logger.info(
661
- `StatsAnalyzer:index#compareLastStatsResult --> No video frames received`,
662
- currentFramesReceived
717
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames received`
663
718
  );
664
719
  }
665
720
 
666
- if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
721
+ if (
722
+ this.statsResults[mediaType].recv.framesDecoded ===
723
+ this.lastStatsResults[mediaType].recv.framesDecoded ||
724
+ this.statsResults.resolutions[mediaType].send.framesDecoded === 0
725
+ ) {
667
726
  LoggerProxy.logger.info(
668
- `StatsAnalyzer:index#compareLastStatsResult --> No video frames decoded`,
669
- currentFramesDecoded
727
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames decoded`
670
728
  );
671
729
  }
672
730
 
673
- if (currentFramesDropped - previousFramesDropped > 10) {
731
+ if (
732
+ this.statsResults.resolutions[mediaType].recv.framesDropped -
733
+ this.lastStatsResults.resolutions[mediaType].recv.framesDropped >
734
+ 10
735
+ ) {
674
736
  LoggerProxy.logger.info(
675
- `StatsAnalyzer:index#compareLastStatsResult --> video frames are getting dropped`,
676
- currentFramesDropped - previousFramesDropped
737
+ `StatsAnalyzer:index#compareLastStatsResult --> ${mediaType} frames are getting dropped`
677
738
  );
678
739
  }
679
740
  }
680
741
 
681
- this.emitStartStopEvents('video', previousFramesDecoded, currentFramesDecoded, false);
742
+ this.emitStartStopEvents(
743
+ mediaType,
744
+ previousStats.framesDecoded,
745
+ currentStats.framesDecoded,
746
+ false
747
+ );
682
748
  }
683
749
 
684
- if (this.meetingMediaStatus.expected.sendShare && this.lastStatsResults['video-share-send']) {
750
+ mediaType = STATS.SHARE_CORRELATE;
751
+ if (this.meetingMediaStatus.expected.sendShare) {
685
752
  // compare share stats sent
686
753
 
687
- const currentStats = this.statsResults['video-share-send'].send;
688
- const previousStats = this.lastStatsResults['video-share-send'].send;
754
+ currentStats = this.statsResults[mediaType].send;
755
+ previousStats = this.lastStatsResults[mediaType].send;
689
756
 
690
757
  if (
691
758
  currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
692
759
  currentStats.totalPacketsSent === 0
693
760
  ) {
694
761
  LoggerProxy.logger.info(
695
- `StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent`,
696
- currentStats.totalPacketsSent
762
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets sent`
697
763
  );
698
- } else {
764
+ } else if (this.lastEmittedStartStopEvent[mediaType].local !== EVENTS.LOCAL_MEDIA_STOPPED) {
699
765
  if (
700
766
  currentStats.framesEncoded === previousStats.framesEncoded ||
701
767
  currentStats.framesEncoded === 0
702
768
  ) {
769
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_VIDEO_ENCODED;
703
770
  LoggerProxy.logger.info(
704
- `StatsAnalyzer:index#compareLastStatsResult --> No share frames getting encoded`,
705
- currentStats.framesEncoded
771
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames getting encoded`
772
+ );
773
+ this.emit(
774
+ {
775
+ file: 'statsAnalyzer',
776
+ function: 'compareLastStatsResult',
777
+ },
778
+ EVENTS.NO_VIDEO_ENCODED,
779
+ {
780
+ mediaType,
781
+ }
706
782
  );
707
783
  }
708
784
 
709
785
  if (
710
- this.statsResults['video-share-send'].send.framesSent ===
711
- this.lastStatsResults['video-share-send'].send.framesSent ||
712
- this.statsResults['video-share-send'].send.framesSent === 0
786
+ this.statsResults.resolutions[mediaType].send.framesSent ===
787
+ this.lastStatsResults.resolutions[mediaType].send.framesSent ||
788
+ this.statsResults.resolutions[mediaType].send.framesSent === 0
713
789
  ) {
714
790
  LoggerProxy.logger.info(
715
- `StatsAnalyzer:index#compareLastStatsResult --> No share frames sent`,
716
- this.statsResults['video-share-send'].send.framesSent
791
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames sent`
792
+ );
793
+ }
794
+
795
+ // Share video is encoded but frames are not sent
796
+ if (
797
+ currentStats.framesEncoded !== previousStats.framesEncoded &&
798
+ (currentStats.framesSent === previousStats.framesSent || currentStats.framesSent === 0)
799
+ ) {
800
+ this.lastEmittedStartStopEvent[mediaType].local = EVENTS.NO_FRAMES_SENT;
801
+ LoggerProxy.logger.info(
802
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} Frames sent even though frames are being encoded`
803
+ );
804
+ this.emit(
805
+ {
806
+ file: 'statsAnalyzer',
807
+ function: 'compareLastStatsResult',
808
+ },
809
+ EVENTS.NO_FRAMES_SENT,
810
+ {
811
+ mediaType,
812
+ }
717
813
  );
718
814
  }
719
815
  }
720
- }
721
816
 
722
- if (this.meetingMediaStatus.expected.sendShare) {
723
817
  // TODO:need to check receive share value
724
- // compare share stats received
725
- const currentPacketsReceived = getCurrentStatsTotals(
726
- 'video-share-recv',
727
- 'totalPacketsReceived'
728
- );
729
- const previousPacketsReceived = getPreviousStatsTotals(
730
- 'video-share-recv',
731
- 'totalPacketsReceived'
732
- );
733
- const currentFramesReceived = getCurrentStatsTotals('video-share-recv', 'framesReceived');
734
- const previousFramesReceived = getPreviousStatsTotals('video-share-recv', 'framesReceived');
735
- const currentFramesDecoded = getCurrentStatsTotals('video-share-recv', 'framesDecoded');
736
- const previousFramesDecoded = getPreviousStatsTotals('video-share-recv', 'framesDecoded');
737
- const currentFramesDropped = getCurrentStatsTotals('video-share-recv', 'framesDropped');
738
- const previousFramesDropped = getPreviousStatsTotals('video-share-recv', 'framesDropped');
739
-
740
- if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
818
+ // compare share stats reveived
819
+ currentStats = this.statsResults[mediaType].recv;
820
+ previousStats = this.lastStatsResults[mediaType].recv;
821
+
822
+ if (
823
+ currentStats.totalPacketsReceived === previousStats.totalPacketsReceived ||
824
+ currentStats.totalPacketsSent === 0
825
+ ) {
741
826
  LoggerProxy.logger.info(
742
- `StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets received`,
743
- currentPacketsReceived
827
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} RTP packets received`
744
828
  );
745
829
  } else {
746
- if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
830
+ if (
831
+ this.statsResults.resolutions[mediaType].recv.framesReceived ===
832
+ this.lastStatsResults.resolutions[mediaType].recv.framesReceived ||
833
+ this.statsResults.resolutions[mediaType].recv.framesReceived === 0
834
+ ) {
747
835
  LoggerProxy.logger.info(
748
- `StatsAnalyzer:index#compareLastStatsResult --> No share frames received`,
749
- currentFramesReceived
836
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames received`
750
837
  );
751
838
  }
752
839
 
753
- if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
840
+ if (
841
+ this.statsResults[mediaType].recv.framesDecoded ===
842
+ this.lastStatsResults[mediaType].recv.framesDecoded ||
843
+ this.statsResults.resolutions[mediaType].send.framesDecoded === 0
844
+ ) {
754
845
  LoggerProxy.logger.info(
755
- `StatsAnalyzer:index#compareLastStatsResult --> No share frames decoded`,
756
- currentFramesDecoded
846
+ `StatsAnalyzer:index#compareLastStatsResult --> No ${mediaType} frames decoded`
757
847
  );
758
848
  }
759
849
 
760
- if (currentFramesDropped - previousFramesDropped > 10) {
850
+ if (
851
+ this.statsResults.resolutions[mediaType].recv.framesDropped -
852
+ this.lastStatsResults.resolutions[mediaType].recv.framesDropped >
853
+ 10
854
+ ) {
761
855
  LoggerProxy.logger.info(
762
- `StatsAnalyzer:index#compareLastStatsResult --> share frames are getting dropped`,
763
- currentFramesDropped - previousFramesDropped
856
+ `StatsAnalyzer:index#compareLastStatsResult --> ${mediaType} frames are getting dropped`
764
857
  );
765
858
  }
766
859
  }
@@ -780,16 +873,13 @@ export class StatsAnalyzer extends EventsScope {
780
873
  * @returns {Promise}
781
874
  */
782
875
  private getStatsAndParse() {
783
- if (!this.mediaConnection) {
876
+ if (!this.peerConnection) {
784
877
  return Promise.resolve();
785
878
  }
786
879
 
787
- if (
788
- this.mediaConnection &&
789
- this.mediaConnection.getConnectionState() === ConnectionState.Failed
790
- ) {
880
+ if (this.peerConnection && this.peerConnection.connectionState === CONNECTION_STATE.FAILED) {
791
881
  LoggerProxy.logger.trace(
792
- 'StatsAnalyzer:index#getStatsAndParse --> media connection is in failed state'
882
+ 'StatsAnalyzer:index#getStatsAndParse --> PeerConnection is in failed state'
793
883
  );
794
884
 
795
885
  return Promise.resolve();
@@ -797,49 +887,43 @@ export class StatsAnalyzer extends EventsScope {
797
887
 
798
888
  LoggerProxy.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Collecting Stats');
799
889
 
800
- return this.mediaConnection.getTransceiverStats().then((transceiverStats) => {
801
- transceiverStats.video.receivers.forEach((receiver, i) =>
802
- this.filterAndParseGetStatsResults(receiver, `video-recv-${i}`, false)
803
- );
804
- transceiverStats.audio.receivers.forEach((receiver, i) =>
805
- this.filterAndParseGetStatsResults(receiver, `audio-recv-${i}`, false)
806
- );
807
- transceiverStats.screenShareVideo.receivers.forEach((receiver, i) =>
808
- this.filterAndParseGetStatsResults(receiver, `video-share-recv-${i}`, false)
809
- );
810
- transceiverStats.screenShareAudio.receivers.forEach((receiver, i) =>
811
- this.filterAndParseGetStatsResults(receiver, `audio-share-recv-${i}`, false)
812
- );
813
-
814
- transceiverStats.video.senders.forEach((sender, i) => {
815
- if (i > 0) {
816
- throw new Error('Stats Analyzer does not support multiple senders.');
817
- }
818
- this.filterAndParseGetStatsResults(sender, 'video-send', true);
819
- });
820
- transceiverStats.audio.senders.forEach((sender, i) => {
821
- if (i > 0) {
822
- throw new Error('Stats Analyzer does not support multiple senders.');
823
- }
824
- this.filterAndParseGetStatsResults(sender, 'audio-send', true);
825
- });
826
- transceiverStats.screenShareVideo.senders.forEach((sender, i) => {
827
- if (i > 0) {
828
- throw new Error('Stats Analyzer does not support multiple senders.');
829
- }
830
- this.filterAndParseGetStatsResults(sender, 'video-share-send', true);
831
- });
832
- transceiverStats.screenShareAudio.senders.forEach((sender, i) => {
833
- if (i > 0) {
834
- throw new Error('Stats Analyzer does not support multiple senders.');
835
- }
836
- this.filterAndParseGetStatsResults(sender, 'audio-share-send', true);
837
- });
838
-
890
+ return Promise.all([
891
+ this.peerConnection.videoTransceiver.sender.getStats().then((res) => {
892
+ this.filterAndParseGetStatsResults(res, STATS.VIDEO_CORRELATE, true);
893
+ }),
894
+
895
+ this.peerConnection.videoTransceiver.receiver.getStats().then((res) => {
896
+ this.filterAndParseGetStatsResults(res, STATS.VIDEO_CORRELATE, false);
897
+ }),
898
+
899
+ this.peerConnection.audioTransceiver.sender.getStats().then((res) => {
900
+ this.filterAndParseGetStatsResults(res, STATS.AUDIO_CORRELATE, true);
901
+ }),
902
+
903
+ this.peerConnection.audioTransceiver.receiver.getStats().then((res) => {
904
+ this.filterAndParseGetStatsResults(res, STATS.AUDIO_CORRELATE, false);
905
+ }),
906
+
907
+ // TODO: add checks for screen share
908
+ this.peerConnection.shareTransceiver.sender.getStats().then((res) => {
909
+ this.filterAndParseGetStatsResults(res, STATS.SHARE_CORRELATE, true);
910
+ }),
911
+
912
+ this.peerConnection.shareTransceiver.receiver.getStats().then((res) => {
913
+ this.filterAndParseGetStatsResults(res, STATS.SHARE_CORRELATE, false);
914
+ }),
915
+ ]).then(() => {
916
+ this.statsResults[STATS.AUDIO_CORRELATE].direction =
917
+ this.peerConnection.audioTransceiver.currentDirection;
918
+ this.statsResults[STATS.VIDEO_CORRELATE].direction =
919
+ this.peerConnection.videoTransceiver.currentDirection;
920
+ this.statsResults[STATS.SHARE_CORRELATE].direction =
921
+ this.peerConnection.shareTransceiver.currentDirection;
922
+
923
+ // Process Stats results every 5 seconds
839
924
  this.compareLastStatsResult();
840
925
 
841
926
  // Save the last results to compare with the current
842
- // DO Deep copy, for some reason it takes the reference all the time rather then old value set
843
927
  this.lastStatsResults = JSON.parse(JSON.stringify(this.statsResults));
844
928
 
845
929
  LoggerProxy.logger.trace(
@@ -852,27 +936,51 @@ export class StatsAnalyzer extends EventsScope {
852
936
  * Processes OutboundRTP stats result and stores
853
937
  * @private
854
938
  * @param {*} result
855
- * @param {*} mediaType
939
+ * @param {*} type
856
940
  * @returns {void}
857
941
  */
858
- private processOutboundRTPResult(result: any, mediaType: any) {
942
+ private processOutboundRTPResult(result: any, type: any) {
943
+ const mediaType = type || STATS.AUDIO_CORRELATE;
859
944
  const sendrecvType = STATS.SEND_DIRECTION;
860
945
 
946
+ this.processTrackResult(result, type, sendrecvType);
861
947
  if (result.bytesSent) {
862
- const kilobytes = 0;
948
+ let kilobytes = 0;
863
949
 
864
- if (result.frameWidth && result.frameHeight) {
865
- this.statsResults[mediaType][sendrecvType].width = result.frameWidth;
866
- this.statsResults[mediaType][sendrecvType].height = result.frameHeight;
867
- this.statsResults[mediaType][sendrecvType].framesSent = result.framesSent;
868
- this.statsResults[mediaType][sendrecvType].hugeFramesSent = result.hugeFramesSent;
950
+ if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesSent) {
951
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
952
+ }
953
+ if (!this.statsResults.internal[mediaType][sendrecvType].framesEncoded) {
954
+ this.statsResults.internal[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
869
955
  }
956
+ if (!this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded) {
957
+ this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded =
958
+ result.keyFramesEncoded;
959
+ }
960
+
961
+ const bytes =
962
+ result.bytesSent - this.statsResults.internal[mediaType][sendrecvType].prevBytesSent;
963
+
964
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
965
+
966
+ kilobytes = bytes / 1024;
870
967
 
871
968
  this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
969
+ this.statsResults[mediaType].bytesSent = kilobytes;
970
+ this.statsResults[mediaType][sendrecvType].framesEncoded =
971
+ result.framesEncoded - this.statsResults.internal[mediaType][sendrecvType].framesEncoded;
972
+ this.statsResults[mediaType][sendrecvType].keyFramesEncoded =
973
+ result.keyFramesEncoded -
974
+ this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded;
975
+ this.statsResults.internal[mediaType].outboundRtpId = result.id;
976
+
977
+ if (!this.statsResults.internal[mediaType][sendrecvType].packetsSent) {
978
+ this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
979
+ }
872
980
 
873
- this.statsResults[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
874
- this.statsResults[mediaType][sendrecvType].keyFramesEncoded = result.keyFramesEncoded;
875
- this.statsResults[mediaType][sendrecvType].packetsSent = result.packetsSent;
981
+ this.statsResults[mediaType][sendrecvType].packetsSent =
982
+ result.packetsSent - this.statsResults.internal[mediaType][sendrecvType].packetsSent;
983
+ this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
876
984
 
877
985
  // Data saved to send MQA metrics
878
986
 
@@ -902,58 +1010,81 @@ export class StatsAnalyzer extends EventsScope {
902
1010
  * Processes InboundRTP stats result and stores
903
1011
  * @private
904
1012
  * @param {*} result
905
- * @param {*} mediaType
1013
+ * @param {*} type
906
1014
  * @returns {void}
907
1015
  */
908
- private processInboundRTPResult(result: any, mediaType: any) {
1016
+ private processInboundRTPResult(result: any, type: any) {
1017
+ const mediaType = type || STATS.AUDIO_CORRELATE;
909
1018
  const sendrecvType = STATS.RECEIVE_DIRECTION;
910
1019
 
1020
+ this.processTrackResult(result, type, sendrecvType);
911
1021
  if (result.bytesReceived) {
912
1022
  let kilobytes = 0;
913
- const receiveSlot = this.receiveSlotCallback(result.ssrc);
914
- const idAndCsi = receiveSlot
915
- ? `id: "${receiveSlot.id || ''}"${receiveSlot.csi ? ` and csi: ${receiveSlot.csi}` : ''}`
916
- : '';
917
-
918
- if (result.frameWidth && result.frameHeight) {
919
- this.statsResults[mediaType][sendrecvType].width = result.frameWidth;
920
- this.statsResults[mediaType][sendrecvType].height = result.frameHeight;
921
- this.statsResults[mediaType][sendrecvType].framesReceived = result.framesReceived;
1023
+
1024
+ if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived) {
1025
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived =
1026
+ result.bytesReceived;
1027
+ }
1028
+
1029
+ if (!this.statsResults.internal[mediaType][sendrecvType].pliCount) {
1030
+ this.statsResults.internal[mediaType][sendrecvType].pliCount = result.pliCount;
1031
+ }
1032
+
1033
+ if (!this.statsResults.internal[mediaType][sendrecvType].packetsLost) {
1034
+ this.statsResults.internal[mediaType][sendrecvType].packetsLost = result.packetsLost;
1035
+ }
1036
+
1037
+ if (!this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived) {
1038
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
1039
+ result.packetsReceived;
1040
+ }
1041
+
1042
+ if (!this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp) {
1043
+ this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp =
1044
+ result.lastPacketReceivedTimestamp;
922
1045
  }
923
1046
 
924
1047
  const bytes =
925
- result.bytesReceived - this.statsResults[mediaType][sendrecvType].totalBytesReceived;
1048
+ result.bytesReceived -
1049
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived;
1050
+
1051
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
926
1052
 
927
1053
  kilobytes = bytes / 1024;
928
1054
  this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
929
-
930
- let currentPacketsLost =
931
- result.packetsLost - this.statsResults[mediaType][sendrecvType].totalPacketsLost;
932
- if (currentPacketsLost < 0) {
933
- currentPacketsLost = 0;
1055
+ this.statsResults[mediaType].bytesReceived = kilobytes.toFixed(1);
1056
+
1057
+ this.statsResults[mediaType][sendrecvType].pliCount =
1058
+ result.pliCount - this.statsResults.internal[mediaType][sendrecvType].pliCount;
1059
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost =
1060
+ result.packetsLost - this.statsResults.internal[mediaType][sendrecvType].packetsLost;
1061
+ if (this.statsResults[mediaType][sendrecvType].currentPacketsLost < 0) {
1062
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost = 0;
934
1063
  }
935
1064
 
936
- const currentPacketsReceived =
937
- result.packetsReceived - this.statsResults[mediaType][sendrecvType].totalPacketsReceived;
938
- this.statsResults[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
1065
+ this.statsResults[mediaType][sendrecvType].packetsReceived =
1066
+ result.packetsReceived -
1067
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived;
1068
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
1069
+ result.packetsReceived;
939
1070
 
940
- if (currentPacketsReceived === 0) {
941
- if (receiveSlot) {
942
- LoggerProxy.logger.info(
943
- `StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot ${idAndCsi}`,
944
- currentPacketsReceived
945
- );
946
- }
1071
+ if (this.statsResults[mediaType][sendrecvType].packetsReceived === 0) {
1072
+ LoggerProxy.logger.info(
1073
+ `StatsAnalyzer:index#processInboundRTPResult --> No packets received for ${mediaType} `,
1074
+ this.statsResults[mediaType][sendrecvType].packetsReceived
1075
+ );
947
1076
  }
948
1077
 
949
1078
  // Check the over all packet Lost ratio
950
1079
  this.statsResults[mediaType][sendrecvType].currentPacketLossRatio =
951
- currentPacketsLost > 0
952
- ? currentPacketsLost / (currentPacketsReceived + currentPacketsLost)
1080
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost > 0
1081
+ ? this.statsResults[mediaType][sendrecvType].currentPacketsLost /
1082
+ (this.statsResults[mediaType][sendrecvType].packetsReceived +
1083
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost)
953
1084
  : 0;
954
1085
  if (this.statsResults[mediaType][sendrecvType].currentPacketLossRatio > 3) {
955
1086
  LoggerProxy.logger.info(
956
- `StatsAnalyzer:index#processInboundRTPResult --> Packets getting lost from the receiver with slot ${idAndCsi}`,
1087
+ 'StatsAnalyzer:index#processInboundRTPResult --> Packets getting lost from the receiver ',
957
1088
  this.statsResults[mediaType][sendrecvType].currentPacketLossRatio
958
1089
  );
959
1090
  }
@@ -999,48 +1130,6 @@ export class StatsAnalyzer extends EventsScope {
999
1130
  }
1000
1131
  }
1001
1132
 
1002
- /**
1003
- * extracts the local Ip address from the statsResult object by looking at stats results candidates
1004
- * and matches that ID with the successful candidate pair. It looks at the type of local candidate it is
1005
- * and then extracts the IP address from the relatedAddress or address property based on conditions known in webrtc
1006
- * note, there are known incompatibilities and it is possible for this to set undefined, or for the IP address to be the public IP address
1007
- * for example, firefox does not set the relayProtocol, and if the user is behind a NAT it might be the public IP
1008
- * @private
1009
- * @param {string} successfulCandidatePairId - The ID of the successful candidate pair.
1010
- * @param {Object} candidates - the stats result candidates
1011
- * @returns {void}
1012
- */
1013
- extractAndSetLocalIpAddressInfoForDiagnostics = (
1014
- successfulCandidatePairId: string,
1015
- candidates: {[key: string]: Record<string, unknown>}
1016
- ) => {
1017
- let newIpAddress = '';
1018
- if (successfulCandidatePairId && !isEmpty(candidates)) {
1019
- const localCandidate = candidates[successfulCandidatePairId];
1020
- if (localCandidate) {
1021
- if (localCandidate.candidateType === 'host') {
1022
- // if it's a host candidate, use the address property - it will be the local IP
1023
- newIpAddress = `${localCandidate.address}`;
1024
- } else if (localCandidate.candidateType === 'prflx') {
1025
- // if it's a peer reflexive candidate and we're not using a relay (there is no relayProtocol set)
1026
- // then look at the relatedAddress - it will be the local
1027
- //
1028
- // Firefox doesn't populate the relayProtocol property
1029
- if (!localCandidate.relayProtocol) {
1030
- newIpAddress = `${localCandidate.relatedAddress}`;
1031
- } else {
1032
- // if it's a peer reflexive candidate and we are using a relay -
1033
- // in that case the relatedAddress will be the IP of the TURN server (Linus),
1034
- // so we can only look at the address, but it might be local IP or public IP,
1035
- // depending on if the user is behind a NAT or not
1036
- newIpAddress = `${localCandidate.address}`;
1037
- }
1038
- }
1039
- }
1040
- }
1041
- this.localIpAddress = newIpAddress;
1042
- };
1043
-
1044
1133
  /**
1045
1134
  * Processes remote and local candidate result and stores
1046
1135
  * @private
@@ -1055,53 +1144,126 @@ export class StatsAnalyzer extends EventsScope {
1055
1144
  if (!result || !result.id) {
1056
1145
  return;
1057
1146
  }
1147
+ const RemoteCandidateType = {};
1148
+ const RemoteTransport = {};
1149
+ const RemoteIpAddress = {};
1150
+ const RemoteNetworkType = {};
1058
1151
 
1059
- // We only care about the successful local candidate
1060
- if (this.successfulCandidatePair?.localCandidateId !== result.id) {
1061
- return;
1152
+ if (!result.id) return;
1153
+
1154
+ const sendRecvType = isSender ? STATS.SEND_DIRECTION : STATS.RECEIVE_DIRECTION;
1155
+ const ipType = isRemote ? STATS.REMOTE : STATS.LOCAL;
1156
+
1157
+ if (!RemoteCandidateType[result.id]) {
1158
+ RemoteCandidateType[result.id] = [];
1062
1159
  }
1063
1160
 
1064
- let transport;
1065
- if (result.relayProtocol) {
1066
- transport = result.relayProtocol.toUpperCase();
1067
- } else if (result.protocol) {
1068
- transport = result.protocol.toUpperCase();
1161
+ if (!RemoteTransport[result.id]) {
1162
+ RemoteTransport[result.id] = [];
1069
1163
  }
1070
1164
 
1071
- const sendRecvType = isSender ? STATS.SEND_DIRECTION : STATS.RECEIVE_DIRECTION;
1072
- const ipType = isRemote ? STATS.REMOTE : STATS.LOCAL;
1165
+ if (!RemoteIpAddress[result.id]) {
1166
+ RemoteIpAddress[result.id] = [];
1167
+ }
1168
+ if (!RemoteNetworkType[result.id]) {
1169
+ RemoteNetworkType[result.id] = [];
1170
+ }
1073
1171
 
1074
- if (!this.statsResults.candidates) {
1075
- this.statsResults.candidates = {};
1172
+ if (
1173
+ result.candidateType &&
1174
+ RemoteCandidateType[result.id].indexOf(result.candidateType) === -1
1175
+ ) {
1176
+ RemoteCandidateType[result.id].push(result.candidateType);
1076
1177
  }
1077
1178
 
1078
- this.statsResults.candidates[result.id] = {
1079
- candidateType: result.candidateType,
1080
- ipAddress: result.ip, // TODO: add ports
1081
- relatedAddress: result.relatedAddress,
1082
- relatedPort: result.relatedPort,
1083
- relayProtocol: result.relayProtocol,
1084
- protocol: result.protocol,
1085
- address: result.address,
1179
+ if (result.protocol && RemoteTransport[result.id].indexOf(result.protocol) === -1) {
1180
+ RemoteTransport[result.id].push(result.protocol.toUpperCase());
1181
+ }
1182
+
1183
+ if (
1184
+ result.ip &&
1185
+ RemoteIpAddress[result.id].indexOf(`${result.ip}:${result.portNumber}`) === -1
1186
+ ) {
1187
+ RemoteIpAddress[result.id].push(`${result.ip}`); // TODO: Add ports
1188
+ }
1189
+
1190
+ if (result.networkType && RemoteNetworkType[result.id].indexOf(result.networkType) === -1) {
1191
+ RemoteNetworkType[result.id].push(result.networkType);
1192
+ }
1193
+
1194
+ this.statsResults.internal.candidates[result.id] = {
1195
+ candidateType: RemoteCandidateType[result.id],
1196
+ ipAddress: RemoteIpAddress[result.id],
1086
1197
  portNumber: result.port,
1087
- networkType: result.networkType,
1198
+ networkType: RemoteNetworkType[result.id],
1088
1199
  priority: result.priority,
1089
- transport,
1200
+ transport: RemoteTransport[result.id],
1090
1201
  timestamp: result.time,
1091
1202
  id: result.id,
1092
1203
  type: result.type,
1093
1204
  };
1094
1205
 
1095
- this.statsResults.connectionType[ipType].candidateType = result.candidateType;
1096
- this.statsResults.connectionType[ipType].ipAddress = result.ipAddress;
1206
+ this.statsResults.connectionType[ipType].candidateType = RemoteCandidateType[result.id];
1207
+ this.statsResults.connectionType[ipType].ipAddress = RemoteIpAddress[result.id];
1097
1208
 
1098
1209
  this.statsResults.connectionType[ipType].networkType =
1099
- result.networkType === NETWORK_TYPE.VPN ? NETWORK_TYPE.UNKNOWN : result.networkType;
1100
- this.statsResults.connectionType[ipType].transport = transport;
1210
+ RemoteNetworkType[result.id][0] === NETWORK_TYPE.VPN
1211
+ ? NETWORK_TYPE.UNKNOWN
1212
+ : RemoteNetworkType[result.id][0];
1213
+ this.statsResults.connectionType[ipType].transport = RemoteTransport[result.id];
1101
1214
 
1102
1215
  this.statsResults[type][sendRecvType].totalRoundTripTime = result.totalRoundTripTime;
1103
1216
  };
1104
1217
 
1218
+ /**
1219
+ * Process Track results
1220
+ *
1221
+ * @private
1222
+ * @param {*} result
1223
+ * @param {*} mediaType
1224
+ * @param {*} sendrecvType
1225
+ * @returns {void}
1226
+ * @memberof StatsAnalyzer
1227
+ */
1228
+ private processTrackResult(result: any, mediaType: any, sendrecvType: any) {
1229
+ if (!result || mediaType === STATS.AUDIO_CORRELATE) {
1230
+ return;
1231
+ }
1232
+ if (result.type !== 'inbound-rtp' && result.type !== 'outbound-rtp') {
1233
+ return;
1234
+ }
1235
+ if (result.frameWidth && result.frameHeight) {
1236
+ this.statsResults.resolutions[mediaType][sendrecvType].width = result.frameWidth;
1237
+ this.statsResults.resolutions[mediaType][sendrecvType].height = result.frameHeight;
1238
+ }
1239
+
1240
+ if (sendrecvType === STATS.RECEIVE_DIRECTION) {
1241
+ this.statsResults.resolutions[mediaType][sendrecvType].framesReceived = result.framesReceived;
1242
+ this.statsResults.resolutions[mediaType][sendrecvType].framesDecoded = result.framesDecoded;
1243
+ this.statsResults.resolutions[mediaType][sendrecvType].framesDropped = result.framesDropped;
1244
+ } else if (sendrecvType === STATS.SEND_DIRECTION) {
1245
+ this.statsResults.resolutions[mediaType][sendrecvType].framesSent = result.framesSent;
1246
+ this.statsResults.resolutions[mediaType][sendrecvType].hugeFramesSent = result.hugeFramesSent;
1247
+ }
1248
+
1249
+ if (result.trackIdentifier && mediaType !== STATS.AUDIO_CORRELATE) {
1250
+ this.statsResults.resolutions[mediaType][sendrecvType].trackIdentifier =
1251
+ result.trackIdentifier;
1252
+
1253
+ const jitterBufferDelay = result && result.jitterBufferDelay;
1254
+ const jitterBufferEmittedCount = result && result.jitterBufferEmittedCount;
1255
+
1256
+ this.statsResults.resolutions[mediaType][sendrecvType].avgJitterDelay =
1257
+ jitterBufferEmittedCount && +jitterBufferDelay / +jitterBufferEmittedCount;
1258
+
1259
+ // Used to calculate the jitter
1260
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay =
1261
+ result.jitterBufferDelay;
1262
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount =
1263
+ result.jitterBufferEmittedCount;
1264
+ }
1265
+ }
1266
+
1105
1267
  /**
1106
1268
  *
1107
1269
  * @private
@@ -1110,17 +1272,21 @@ export class StatsAnalyzer extends EventsScope {
1110
1272
  * @returns {void}
1111
1273
  * @memberof StatsAnalyzer
1112
1274
  */
1113
- compareSentAndReceived(result, type) {
1114
- // Don't compare on transceivers without a sender.
1115
- if (!type || !this.statsResults[type].send) {
1275
+ private compareSentAndReceived(result: any, type: any) {
1276
+ if (!type) {
1116
1277
  return;
1117
1278
  }
1118
1279
 
1119
1280
  const mediaType = type;
1120
1281
 
1282
+ if (!this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver) {
1283
+ this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
1284
+ }
1285
+
1121
1286
  const currentPacketLoss =
1122
- result.packetsLost - this.statsResults[mediaType].send.totalPacketsLostOnReceiver;
1287
+ result.packetsLost - this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver;
1123
1288
 
1289
+ this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
1124
1290
  this.statsResults[mediaType].send.packetsLostOnReceiver = currentPacketLoss;
1125
1291
  this.statsResults[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
1126
1292