@webex/plugin-meetings 2.59.8 → 2.60.0-next.1

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