@webex/plugin-meetings 3.0.0-beta.13 → 3.0.0-beta.131

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