@webex/plugin-meetings 3.0.0-beta.14 → 3.0.0-beta.141

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 +1012 -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 +204 -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 +300 -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 +398 -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 +89 -124
  101. package/dist/locus-info/parser.js.map +1 -1
  102. package/dist/locus-info/selfUtils.js +94 -92
  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 +2576 -2455
  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 +296 -342
  121. package/dist/meeting/request.js.map +1 -1
  122. package/dist/meeting/request.type.js +0 -1
  123. package/dist/meeting/request.type.js.map +1 -1
  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 +170 -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 +14 -40
  179. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  180. package/dist/multistream/remoteMediaManager.js +481 -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 -462
  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 +994 -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 +104 -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 +48 -0
  310. package/dist/types/multistream/remoteMediaManager.d.ts +267 -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 +888 -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 +22 -11
  362. package/src/common/logs/request.ts +11 -8
  363. package/src/config.ts +16 -12
  364. package/src/constants.ts +154 -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 +286 -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 +335 -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 +47 -69
  378. package/src/locus-info/selfUtils.ts +175 -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 +2809 -1589
  385. package/src/meeting/locusMediaRequest.ts +309 -0
  386. package/src/meeting/muteState.ts +290 -72
  387. package/src/meeting/request.ts +229 -182
  388. package/src/meeting/request.type.ts +10 -8
  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 +771 -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 +210 -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 +11 -3
  417. package/src/multistream/remoteMediaManager.ts +245 -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 -112
  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 -65
  433. package/src/roap/turnDiscovery.ts +101 -48
  434. package/src/statsAnalyzer/global.ts +8 -104
  435. package/src/statsAnalyzer/index.ts +624 -377
  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 +1685 -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 +518 -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 +615 -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 +221 -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 +3077 -923
  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 +408 -85
  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 +676 -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 +52 -5
  490. package/test/unit/spec/multistream/remoteMediaManager.ts +585 -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();
@@ -347,7 +300,6 @@ export class StatsAnalyzer extends EventsScope {
347
300
  this.mediaConnection = null;
348
301
  });
349
302
  }
350
- this.mediaConnection = null;
351
303
 
352
304
  return Promise.resolve();
353
305
  }
@@ -367,6 +319,37 @@ export class StatsAnalyzer extends EventsScope {
367
319
  return;
368
320
  }
369
321
 
322
+ // Generate empty stats results
323
+ if (!this.statsResults[type]) {
324
+ this.statsResults[type] = {};
325
+ }
326
+
327
+ if (isSender && !this.statsResults[type].send) {
328
+ this.statsResults[type].send = cloneDeep(emptySender);
329
+ } else if (!isSender && !this.statsResults[type].recv) {
330
+ this.statsResults[type].recv = cloneDeep(emptyReceiver);
331
+ }
332
+
333
+ if (!this.statsResults.resolutions[type]) {
334
+ this.statsResults.resolutions[type] = {};
335
+ }
336
+
337
+ if (isSender && !this.statsResults.resolutions[type].send) {
338
+ this.statsResults.resolutions[type].send = cloneDeep(emptySender);
339
+ } else if (!isSender && !this.statsResults.resolutions[type].recv) {
340
+ this.statsResults.resolutions[type].recv = cloneDeep(emptyReceiver);
341
+ }
342
+
343
+ if (!this.statsResults.internal[type]) {
344
+ this.statsResults.internal[type] = {};
345
+ }
346
+
347
+ if (isSender && !this.statsResults.internal[type].send) {
348
+ this.statsResults.internal[type].send = cloneDeep(emptySender);
349
+ } else if (!isSender && !this.statsResults.internal[type].recv) {
350
+ this.statsResults.internal[type].recv = cloneDeep(emptyReceiver);
351
+ }
352
+
370
353
  switch (getStatsResult.type) {
371
354
  case 'outbound-rtp':
372
355
  this.processOutboundRTPResult(getStatsResult, type);
@@ -401,19 +384,25 @@ export class StatsAnalyzer extends EventsScope {
401
384
  /**
402
385
  * Filters the get stats results for types
403
386
  * @private
404
- * @param {Array} getStatsResults
387
+ * @param {Array} statsItem
405
388
  * @param {String} type
406
389
  * @param {boolean} isSender
407
390
  * @returns {void}
408
391
  */
409
- private filterAndParseGetStatsResults(getStatsResults: Array<any>, type: string, isSender: boolean) {
392
+ filterAndParseGetStatsResults(statsItem: any, type: string, isSender: boolean) {
410
393
  const {types} = DEFAULT_GET_STATS_FILTER;
411
394
 
412
- getStatsResults.forEach((result) => {
395
+ statsItem.report.forEach((result) => {
413
396
  if (types.includes(result.type)) {
414
397
  this.parseGetStatsResult(result, type, isSender);
415
398
  }
416
399
  });
400
+
401
+ if (this.statsResults[type]) {
402
+ this.statsResults[type].direction = statsItem.currentDirection;
403
+ this.statsResults[type].trackLabel = statsItem.localTrackLabel;
404
+ this.statsResults[type].csi = statsItem.csi;
405
+ }
417
406
  }
418
407
 
419
408
  /**
@@ -427,7 +416,7 @@ export class StatsAnalyzer extends EventsScope {
427
416
  return;
428
417
  }
429
418
 
430
- if (type === STATS.AUDIO_CORRELATE) {
419
+ if (type.includes('audio-send')) {
431
420
  this.statsResults[type].send.audioLevel = result.audioLevel;
432
421
  this.statsResults[type].send.totalAudioEnergy = result.totalAudioEnergy;
433
422
  }
@@ -447,7 +436,12 @@ export class StatsAnalyzer extends EventsScope {
447
436
  * @memberof StatsAnalyzer
448
437
  * @returns {void}
449
438
  */
450
- emitStartStopEvents = (mediaType: string, previousValue: number, currentValue: number, isLocal: boolean) => {
439
+ emitStartStopEvents = (
440
+ mediaType: string,
441
+ previousValue: number,
442
+ currentValue: number,
443
+ isLocal: boolean
444
+ ) => {
451
445
  if (mediaType !== 'audio' && mediaType !== 'video' && mediaType !== 'share') {
452
446
  throw new Error(`Unsupported mediaType: ${mediaType}`);
453
447
  }
@@ -457,32 +451,36 @@ export class StatsAnalyzer extends EventsScope {
457
451
  // eslint-disable-next-line no-param-reassign
458
452
  if (currentValue === undefined) currentValue = 0;
459
453
 
460
- const lastEmittedEvent = isLocal ? this.lastEmittedStartStopEvent[mediaType].local : this.lastEmittedStartStopEvent[mediaType].remote;
454
+ if (!this.lastEmittedStartStopEvent[mediaType]) {
455
+ this.lastEmittedStartStopEvent[mediaType] = {};
456
+ }
457
+
458
+ const lastEmittedEvent = isLocal
459
+ ? this.lastEmittedStartStopEvent[mediaType].local
460
+ : this.lastEmittedStartStopEvent[mediaType].remote;
461
461
 
462
462
  let newEvent;
463
463
 
464
- if ((currentValue - previousValue) > 0) {
464
+ if (currentValue - previousValue > 0) {
465
465
  newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STARTED : EVENTS.REMOTE_MEDIA_STARTED;
466
- }
467
- else if ((currentValue === previousValue) && currentValue > 0) {
466
+ } else if (currentValue === previousValue && currentValue > 0) {
468
467
  newEvent = isLocal ? EVENTS.LOCAL_MEDIA_STOPPED : EVENTS.REMOTE_MEDIA_STOPPED;
469
468
  }
470
469
 
471
470
  if (newEvent && lastEmittedEvent !== newEvent) {
472
471
  if (isLocal) {
473
472
  this.lastEmittedStartStopEvent[mediaType].local = newEvent;
474
- }
475
- else {
473
+ } else {
476
474
  this.lastEmittedStartStopEvent[mediaType].remote = newEvent;
477
475
  }
478
476
  this.emit(
479
477
  {
480
478
  file: 'statsAnalyzer/index',
481
- function: 'compareLastStatsResult'
479
+ function: 'compareLastStatsResult',
482
480
  },
483
481
  newEvent,
484
482
  {
485
- type: mediaType
483
+ type: mediaType,
486
484
  }
487
485
  );
488
486
  }
@@ -497,145 +495,289 @@ export class StatsAnalyzer extends EventsScope {
497
495
  */
498
496
  private compareLastStatsResult() {
499
497
  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`);
498
+ const getCurrentStatsTotals = (keyPrefix: string, value: string): number =>
499
+ Object.keys(this.statsResults)
500
+ .filter((key) => key.startsWith(keyPrefix))
501
+ .reduce((prev, cur) => prev + (this.statsResults[cur]?.recv[value] || 0), 0);
502
+
503
+ const getPreviousStatsTotals = (keyPrefix: string, value: string): number =>
504
+ Object.keys(this.statsResults)
505
+ .filter((key) => key.startsWith(keyPrefix))
506
+ .reduce((prev, cur) => prev + (this.lastStatsResults[cur]?.recv[value] || 0), 0);
507
+
508
+ const getCurrentResolutionsStatsTotals = (keyPrefix: string, value: string): number =>
509
+ Object.keys(this.statsResults)
510
+ .filter((key) => key.startsWith(keyPrefix))
511
+ .reduce((prev, cur) => prev + (this.statsResults.resolutions[cur]?.recv[value] || 0), 0);
512
+
513
+ const getPreviousResolutionsStatsTotals = (keyPrefix: string, value: string): number =>
514
+ Object.keys(this.statsResults)
515
+ .filter((key) => key.startsWith(keyPrefix))
516
+ .reduce(
517
+ (prev, cur) => prev + (this.lastStatsResults.resolutions[cur]?.recv[value] || 0),
518
+ 0
519
+ );
520
+
521
+ if (this.meetingMediaStatus.expected.sendAudio && this.lastStatsResults['audio-send']) {
522
+ // compare audio stats sent
523
+ // NOTE: relies on there being only one sender.
524
+ const currentStats = this.statsResults['audio-send'].send;
525
+ const previousStats = this.lastStatsResults['audio-send'].send;
526
+
527
+ if (
528
+ currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
529
+ currentStats.totalPacketsSent === 0
530
+ ) {
531
+ LoggerProxy.logger.info(
532
+ `StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets sent`,
533
+ currentStats.totalPacketsSent
534
+ );
535
+ } else {
536
+ if (
537
+ currentStats.totalAudioEnergy === previousStats.totalAudioEnergy ||
538
+ currentStats.totalAudioEnergy === 0
539
+ ) {
540
+ LoggerProxy.logger.info(
541
+ `StatsAnalyzer:index#compareLastStatsResult --> No audio Energy present`,
542
+ currentStats.totalAudioEnergy
543
+ );
515
544
  }
516
545
 
517
546
  if (currentStats.audioLevel === 0) {
518
- LoggerProxy.logger.info(`StatsAnalyzer:index#compareLastStatsResult --> ${mediaType} level is 0 for the user`);
547
+ LoggerProxy.logger.info(
548
+ `StatsAnalyzer:index#compareLastStatsResult --> audio level is 0 for the user`
549
+ );
519
550
  }
520
551
  }
521
552
 
522
- this.emitStartStopEvents(mediaType, previousStats.totalPacketsSent, currentStats.totalPacketsSent, true);
553
+ this.emitStartStopEvents(
554
+ 'audio',
555
+ previousStats.totalPacketsSent,
556
+ currentStats.totalPacketsSent,
557
+ true
558
+ );
523
559
  }
524
560
 
525
561
  if (this.meetingMediaStatus.expected.receiveAudio) {
526
- // compare audio stats received
527
- currentStats = this.statsResults[mediaType].recv;
528
- previousStats = this.lastStatsResults[mediaType].recv;
562
+ // compare audio stats received
563
+ const currentPacketsReceived = getCurrentStatsTotals('audio-recv', 'totalPacketsReceived');
564
+ const previousPacketsReceived = getPreviousStatsTotals(
565
+ 'audio-recv',
566
+ 'totalPacketsReceived'
567
+ );
568
+ const currentSamplesReceived = getCurrentStatsTotals('audio-recv', 'totalSamplesReceived');
569
+ const previousSamplesReceived = getPreviousStatsTotals(
570
+ 'audio-recv',
571
+ 'totalSamplesReceived'
572
+ );
529
573
 
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`);
574
+ if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
575
+ LoggerProxy.logger.info(
576
+ `StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received`,
577
+ currentPacketsReceived
578
+ );
579
+ } else if (
580
+ currentSamplesReceived === previousSamplesReceived ||
581
+ currentSamplesReceived === 0
582
+ ) {
583
+ LoggerProxy.logger.info(
584
+ `StatsAnalyzer:index#compareLastStatsResult --> No audio samples received`,
585
+ currentSamplesReceived
586
+ );
536
587
  }
537
588
 
538
- this.emitStartStopEvents(mediaType, previousStats.totalPacketsReceived, currentStats.totalPacketsReceived, false);
589
+ this.emitStartStopEvents('audio', previousPacketsReceived, currentPacketsReceived, false);
539
590
  }
540
591
 
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`);
592
+ if (this.meetingMediaStatus.expected.sendVideo && this.lastStatsResults['video-send']) {
593
+ // compare video stats sent
594
+ const currentStats = this.statsResults['video-send'].send;
595
+ const previousStats = this.lastStatsResults['video-send'].send;
596
+
597
+ if (
598
+ currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
599
+ currentStats.totalPacketsSent === 0
600
+ ) {
601
+ LoggerProxy.logger.info(
602
+ `StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets sent`,
603
+ currentStats.totalPacketsSent
604
+ );
605
+ } else {
606
+ if (
607
+ currentStats.framesEncoded === previousStats.framesEncoded ||
608
+ currentStats.framesEncoded === 0
609
+ ) {
610
+ LoggerProxy.logger.info(
611
+ `StatsAnalyzer:index#compareLastStatsResult --> No video Frames Encoded`,
612
+ currentStats.framesEncoded
613
+ );
553
614
  }
554
615
 
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`);
616
+ if (
617
+ this.statsResults.resolutions['video-send'].send.framesSent ===
618
+ this.lastStatsResults.resolutions['video-send'].send.framesSent ||
619
+ this.statsResults.resolutions['video-send'].send.framesSent === 0
620
+ ) {
621
+ LoggerProxy.logger.info(
622
+ `StatsAnalyzer:index#compareLastStatsResult --> No video Frames sent`,
623
+ this.statsResults.resolutions['video-send'].send.framesSent
624
+ );
557
625
  }
558
626
  }
559
627
 
560
- this.emitStartStopEvents(
561
- mediaType,
562
- previousStats.framesSent,
563
- currentStats.framesSent,
564
- true
565
- );
628
+ this.emitStartStopEvents('video', previousStats.framesSent, currentStats.framesSent, true);
566
629
  }
567
630
 
568
-
569
631
  if (this.meetingMediaStatus.expected.receiveVideo) {
570
- // compare video stats reveived
571
-
572
- currentStats = this.statsResults[mediaType].recv;
573
- previousStats = this.lastStatsResults[mediaType].recv;
632
+ // compare video stats received
633
+ const currentPacketsReceived = getCurrentStatsTotals('video-recv', 'totalPacketsReceived');
634
+ const previousPacketsReceived = getPreviousStatsTotals(
635
+ 'video-recv',
636
+ 'totalPacketsReceived'
637
+ );
638
+ const currentFramesReceived = getCurrentResolutionsStatsTotals(
639
+ 'video-recv',
640
+ 'framesReceived'
641
+ );
642
+ const previousFramesReceived = getPreviousResolutionsStatsTotals(
643
+ 'video-recv',
644
+ 'framesReceived'
645
+ );
646
+ const currentFramesDecoded = getCurrentStatsTotals('video-recv', 'framesDecoded');
647
+ const previousFramesDecoded = getPreviousStatsTotals('video-recv', 'framesDecoded');
648
+ const currentFramesDropped = getCurrentResolutionsStatsTotals(
649
+ 'video-recv',
650
+ 'framesDropped'
651
+ );
652
+ const previousFramesDropped = getPreviousResolutionsStatsTotals(
653
+ 'video-recv',
654
+ 'framesDropped'
655
+ );
574
656
 
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`);
657
+ if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
658
+ LoggerProxy.logger.info(
659
+ `StatsAnalyzer:index#compareLastStatsResult --> No video RTP packets received`,
660
+ currentPacketsReceived
661
+ );
662
+ } else {
663
+ if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
664
+ LoggerProxy.logger.info(
665
+ `StatsAnalyzer:index#compareLastStatsResult --> No video frames received`,
666
+ currentFramesReceived
667
+ );
581
668
  }
582
669
 
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`);
670
+ if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
671
+ LoggerProxy.logger.info(
672
+ `StatsAnalyzer:index#compareLastStatsResult --> No video frames decoded`,
673
+ currentFramesDecoded
674
+ );
585
675
  }
586
676
 
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`);
677
+ if (currentFramesDropped - previousFramesDropped > 10) {
678
+ LoggerProxy.logger.info(
679
+ `StatsAnalyzer:index#compareLastStatsResult --> video frames are getting dropped`,
680
+ currentFramesDropped - previousFramesDropped
681
+ );
589
682
  }
590
683
  }
591
684
 
592
- this.emitStartStopEvents(
593
- mediaType,
594
- previousStats.framesDecoded,
595
- currentStats.framesDecoded,
596
- false
597
- );
685
+ this.emitStartStopEvents('video', previousFramesDecoded, currentFramesDecoded, false);
598
686
  }
599
687
 
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`);
688
+ if (this.meetingMediaStatus.expected.sendShare && this.lastStatsResults['video-share-send']) {
689
+ // compare share stats sent
690
+
691
+ const currentStats = this.statsResults['video-share-send'].send;
692
+ const previousStats = this.lastStatsResults['video-share-send'].send;
693
+
694
+ if (
695
+ currentStats.totalPacketsSent === previousStats.totalPacketsSent ||
696
+ currentStats.totalPacketsSent === 0
697
+ ) {
698
+ LoggerProxy.logger.info(
699
+ `StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets sent`,
700
+ currentStats.totalPacketsSent
701
+ );
702
+ } else {
703
+ if (
704
+ currentStats.framesEncoded === previousStats.framesEncoded ||
705
+ currentStats.framesEncoded === 0
706
+ ) {
707
+ LoggerProxy.logger.info(
708
+ `StatsAnalyzer:index#compareLastStatsResult --> No share frames getting encoded`,
709
+ currentStats.framesEncoded
710
+ );
613
711
  }
614
712
 
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`);
713
+ if (
714
+ this.statsResults.resolutions['video-share-send'].send.framesSent ===
715
+ this.lastStatsResults.resolutions['video-share-send'].send.framesSent ||
716
+ this.statsResults.resolutions['video-share-send'].send.framesSent === 0
717
+ ) {
718
+ LoggerProxy.logger.info(
719
+ `StatsAnalyzer:index#compareLastStatsResult --> No share frames sent`,
720
+ this.statsResults.resolutions['video-share-send'].send.framesSent
721
+ );
617
722
  }
618
723
  }
724
+ }
619
725
 
726
+ if (this.meetingMediaStatus.expected.sendShare) {
620
727
  // TODO:need to check receive share value
621
- // compare share stats reveived
622
- currentStats = this.statsResults[mediaType].recv;
623
- previousStats = this.lastStatsResults[mediaType].recv;
728
+ // compare share stats received
729
+ const currentPacketsReceived = getCurrentStatsTotals(
730
+ 'video-share-recv',
731
+ 'totalPacketsReceived'
732
+ );
733
+ const previousPacketsReceived = getPreviousStatsTotals(
734
+ 'video-share-recv',
735
+ 'totalPacketsReceived'
736
+ );
737
+ const currentFramesReceived = getCurrentResolutionsStatsTotals(
738
+ 'video-share-recv',
739
+ 'framesReceived'
740
+ );
741
+ const previousFramesReceived = getPreviousResolutionsStatsTotals(
742
+ 'video-share-recv',
743
+ 'framesReceived'
744
+ );
745
+ const currentFramesDecoded = getCurrentStatsTotals('video-share-recv', 'framesDecoded');
746
+ const previousFramesDecoded = getPreviousStatsTotals('video-share-recv', 'framesDecoded');
747
+ const currentFramesDropped = getCurrentResolutionsStatsTotals(
748
+ 'video-share-recv',
749
+ 'framesDropped'
750
+ );
751
+ const previousFramesDropped = getPreviousResolutionsStatsTotals(
752
+ 'video-share-recv',
753
+ 'framesDropped'
754
+ );
624
755
 
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`);
756
+ if (currentPacketsReceived === previousPacketsReceived || currentPacketsReceived === 0) {
757
+ LoggerProxy.logger.info(
758
+ `StatsAnalyzer:index#compareLastStatsResult --> No share RTP packets received`,
759
+ currentPacketsReceived
760
+ );
761
+ } else {
762
+ if (currentFramesReceived === previousFramesReceived || currentFramesReceived === 0) {
763
+ LoggerProxy.logger.info(
764
+ `StatsAnalyzer:index#compareLastStatsResult --> No share frames received`,
765
+ currentFramesReceived
766
+ );
631
767
  }
632
768
 
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`);
769
+ if (currentFramesDecoded === previousFramesDecoded || currentFramesDecoded === 0) {
770
+ LoggerProxy.logger.info(
771
+ `StatsAnalyzer:index#compareLastStatsResult --> No share frames decoded`,
772
+ currentFramesDecoded
773
+ );
635
774
  }
636
775
 
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`);
776
+ if (currentFramesDropped - previousFramesDropped > 10) {
777
+ LoggerProxy.logger.info(
778
+ `StatsAnalyzer:index#compareLastStatsResult --> share frames are getting dropped`,
779
+ currentFramesDropped - previousFramesDropped
780
+ );
639
781
  }
640
782
  }
641
783
 
@@ -658,8 +800,13 @@ export class StatsAnalyzer extends EventsScope {
658
800
  return Promise.resolve();
659
801
  }
660
802
 
661
- if (this.mediaConnection && this.mediaConnection.getConnectionState() === MC.ConnectionState.Failed) {
662
- LoggerProxy.logger.trace('StatsAnalyzer:index#getStatsAndParse --> media connection is in failed state');
803
+ if (
804
+ this.mediaConnection &&
805
+ this.mediaConnection.getConnectionState() === ConnectionState.Failed
806
+ ) {
807
+ LoggerProxy.logger.trace(
808
+ 'StatsAnalyzer:index#getStatsAndParse --> media connection is in failed state'
809
+ );
663
810
 
664
811
  return Promise.resolve();
665
812
  }
@@ -667,20 +814,43 @@ export class StatsAnalyzer extends EventsScope {
667
814
  LoggerProxy.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Collecting Stats');
668
815
 
669
816
  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;
817
+ transceiverStats.video.receivers.forEach((receiver, i) =>
818
+ this.filterAndParseGetStatsResults(receiver, `video-recv-${i}`, false)
819
+ );
820
+ transceiverStats.audio.receivers.forEach((receiver, i) =>
821
+ this.filterAndParseGetStatsResults(receiver, `audio-recv-${i}`, false)
822
+ );
823
+ transceiverStats.screenShareVideo.receivers.forEach((receiver, i) =>
824
+ this.filterAndParseGetStatsResults(receiver, `video-share-recv-${i}`, false)
825
+ );
826
+ transceiverStats.screenShareAudio.receivers.forEach((receiver, i) =>
827
+ this.filterAndParseGetStatsResults(receiver, `audio-share-recv-${i}`, false)
828
+ );
681
829
 
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;
830
+ transceiverStats.video.senders.forEach((sender, i) => {
831
+ if (i > 0) {
832
+ throw new Error('Stats Analyzer does not support multiple senders.');
833
+ }
834
+ this.filterAndParseGetStatsResults(sender, 'video-send', true);
835
+ });
836
+ transceiverStats.audio.senders.forEach((sender, i) => {
837
+ if (i > 0) {
838
+ throw new Error('Stats Analyzer does not support multiple senders.');
839
+ }
840
+ this.filterAndParseGetStatsResults(sender, 'audio-send', true);
841
+ });
842
+ transceiverStats.screenShareVideo.senders.forEach((sender, i) => {
843
+ if (i > 0) {
844
+ throw new Error('Stats Analyzer does not support multiple senders.');
845
+ }
846
+ this.filterAndParseGetStatsResults(sender, 'video-share-send', true);
847
+ });
848
+ transceiverStats.screenShareAudio.senders.forEach((sender, i) => {
849
+ if (i > 0) {
850
+ throw new Error('Stats Analyzer does not support multiple senders.');
851
+ }
852
+ this.filterAndParseGetStatsResults(sender, 'audio-share-send', true);
853
+ });
684
854
 
685
855
  this.compareLastStatsResult();
686
856
 
@@ -688,7 +858,9 @@ export class StatsAnalyzer extends EventsScope {
688
858
  // DO Deep copy, for some reason it takes the reference all the time rather then old value set
689
859
  this.lastStatsResults = JSON.parse(JSON.stringify(this.statsResults));
690
860
 
691
- LoggerProxy.logger.trace('StatsAnalyzer:index#getStatsAndParse --> Finished Collecting Stats');
861
+ LoggerProxy.logger.trace(
862
+ 'StatsAnalyzer:index#getStatsAndParse --> Finished Collecting Stats'
863
+ );
692
864
  });
693
865
  }
694
866
 
@@ -696,16 +868,23 @@ export class StatsAnalyzer extends EventsScope {
696
868
  * Processes OutboundRTP stats result and stores
697
869
  * @private
698
870
  * @param {*} result
699
- * @param {*} type
871
+ * @param {*} mediaType
700
872
  * @returns {void}
701
873
  */
702
- private processOutboundRTPResult(result: any, type: any) {
703
- const mediaType = type || STATS.AUDIO_CORRELATE;
874
+ private processOutboundRTPResult(result: any, mediaType: any) {
704
875
  const sendrecvType = STATS.SEND_DIRECTION;
705
876
 
706
877
  if (result.bytesSent) {
707
878
  let kilobytes = 0;
708
879
 
880
+ if (result.frameWidth && result.frameHeight) {
881
+ this.statsResults.resolutions[mediaType][sendrecvType].width = result.frameWidth;
882
+ this.statsResults.resolutions[mediaType][sendrecvType].height = result.frameHeight;
883
+ this.statsResults.resolutions[mediaType][sendrecvType].framesSent = result.framesSent;
884
+ this.statsResults.resolutions[mediaType][sendrecvType].hugeFramesSent =
885
+ result.hugeFramesSent;
886
+ }
887
+
709
888
  if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesSent) {
710
889
  this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
711
890
  }
@@ -713,10 +892,12 @@ export class StatsAnalyzer extends EventsScope {
713
892
  this.statsResults.internal[mediaType][sendrecvType].framesEncoded = result.framesEncoded;
714
893
  }
715
894
  if (!this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded) {
716
- this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded = result.keyFramesEncoded;
895
+ this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded =
896
+ result.keyFramesEncoded;
717
897
  }
718
898
 
719
- const bytes = result.bytesSent - this.statsResults.internal[mediaType][sendrecvType].prevBytesSent;
899
+ const bytes =
900
+ result.bytesSent - this.statsResults.internal[mediaType][sendrecvType].prevBytesSent;
720
901
 
721
902
  this.statsResults.internal[mediaType][sendrecvType].prevBytesSent = result.bytesSent;
722
903
 
@@ -725,15 +906,19 @@ export class StatsAnalyzer extends EventsScope {
725
906
  this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
726
907
  this.statsResults[mediaType].bytesSent = kilobytes;
727
908
 
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;
909
+ this.statsResults[mediaType][sendrecvType].framesEncoded =
910
+ result.framesEncoded - this.statsResults.internal[mediaType][sendrecvType].framesEncoded;
911
+ this.statsResults[mediaType][sendrecvType].keyFramesEncoded =
912
+ result.keyFramesEncoded -
913
+ this.statsResults.internal[mediaType][sendrecvType].keyFramesEncoded;
730
914
  this.statsResults.internal[mediaType].outboundRtpId = result.id;
731
915
 
732
916
  if (!this.statsResults.internal[mediaType][sendrecvType].packetsSent) {
733
917
  this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
734
918
  }
735
919
 
736
- this.statsResults[mediaType][sendrecvType].packetsSent = result.packetsSent - this.statsResults.internal[mediaType][sendrecvType].packetsSent;
920
+ this.statsResults[mediaType][sendrecvType].packetsSent =
921
+ result.packetsSent - this.statsResults.internal[mediaType][sendrecvType].packetsSent;
737
922
  this.statsResults.internal[mediaType][sendrecvType].packetsSent = result.packetsSent;
738
923
 
739
924
  // Data saved to send MQA metrics
@@ -745,33 +930,48 @@ export class StatsAnalyzer extends EventsScope {
745
930
  this.statsResults[mediaType][sendrecvType].totalFirCount = result.firCount;
746
931
  this.statsResults[mediaType][sendrecvType].framesSent = result.framesSent;
747
932
  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;
933
+ this.statsResults[mediaType][sendrecvType].encoderImplementation =
934
+ result.encoderImplementation;
935
+ this.statsResults[mediaType][sendrecvType].qualityLimitationReason =
936
+ result.qualityLimitationReason;
937
+ this.statsResults[mediaType][sendrecvType].qualityLimitationResolutionChanges =
938
+ result.qualityLimitationResolutionChanges;
939
+ this.statsResults[mediaType][sendrecvType].retransmittedPacketsSent =
940
+ result.retransmittedPacketsSent;
752
941
  this.statsResults[mediaType][sendrecvType].totalBytesSent = result.bytesSent;
753
942
  this.statsResults[mediaType][sendrecvType].headerBytesSent = result.headerBytesSent;
754
- this.statsResults[mediaType][sendrecvType].retransmittedBytesSent = result.retransmittedBytesSent;
943
+ this.statsResults[mediaType][sendrecvType].retransmittedBytesSent =
944
+ result.retransmittedBytesSent;
755
945
  }
756
946
  }
757
947
 
758
-
759
948
  /**
760
949
  * Processes InboundRTP stats result and stores
761
950
  * @private
762
951
  * @param {*} result
763
- * @param {*} type
952
+ * @param {*} mediaType
764
953
  * @returns {void}
765
954
  */
766
- private processInboundRTPResult(result: any, type: any) {
767
- const mediaType = type || STATS.AUDIO_CORRELATE;
955
+ private processInboundRTPResult(result: any, mediaType: any) {
768
956
  const sendrecvType = STATS.RECEIVE_DIRECTION;
769
957
 
770
958
  if (result.bytesReceived) {
771
959
  let kilobytes = 0;
960
+ const receiveSlot = this.receiveSlotCallback(result.ssrc);
961
+ const idAndCsi = receiveSlot
962
+ ? `id: "${receiveSlot.id || ''}"${receiveSlot.csi ? ` and csi: ${receiveSlot.csi}` : ''}`
963
+ : '';
964
+
965
+ if (result.frameWidth && result.frameHeight) {
966
+ this.statsResults.resolutions[mediaType][sendrecvType].width = result.frameWidth;
967
+ this.statsResults.resolutions[mediaType][sendrecvType].height = result.frameHeight;
968
+ this.statsResults.resolutions[mediaType][sendrecvType].framesReceived =
969
+ result.framesReceived;
970
+ }
772
971
 
773
972
  if (!this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived) {
774
- this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
973
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived =
974
+ result.bytesReceived;
775
975
  }
776
976
 
777
977
  if (!this.statsResults.internal[mediaType][sendrecvType].pliCount) {
@@ -783,14 +983,18 @@ export class StatsAnalyzer extends EventsScope {
783
983
  }
784
984
 
785
985
  if (!this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived) {
786
- this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
986
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
987
+ result.packetsReceived;
787
988
  }
788
989
 
789
990
  if (!this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp) {
790
- this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp = result.lastPacketReceivedTimestamp;
991
+ this.statsResults.internal[mediaType][sendrecvType].lastPacketReceivedTimestamp =
992
+ result.lastPacketReceivedTimestamp;
791
993
  }
792
994
 
793
- const bytes = result.bytesReceived - (this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived);
995
+ const bytes =
996
+ result.bytesReceived -
997
+ this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived;
794
998
 
795
999
  this.statsResults.internal[mediaType][sendrecvType].prevBytesReceived = result.bytesReceived;
796
1000
 
@@ -798,35 +1002,54 @@ export class StatsAnalyzer extends EventsScope {
798
1002
  this.statsResults[mediaType][sendrecvType].availableBandwidth = kilobytes.toFixed(1);
799
1003
  this.statsResults[mediaType].bytesReceived = kilobytes.toFixed(1);
800
1004
 
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;
1005
+ this.statsResults[mediaType][sendrecvType].pliCount =
1006
+ result.pliCount - this.statsResults.internal[mediaType][sendrecvType].pliCount;
1007
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost =
1008
+ result.packetsLost - this.statsResults.internal[mediaType][sendrecvType].packetsLost;
803
1009
  if (this.statsResults[mediaType][sendrecvType].currentPacketsLost < 0) {
804
1010
  this.statsResults[mediaType][sendrecvType].currentPacketsLost = 0;
805
1011
  }
806
1012
 
807
- this.statsResults[mediaType][sendrecvType].packetsReceived = result.packetsReceived - this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived;
808
- this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
1013
+ this.statsResults[mediaType][sendrecvType].packetsReceived =
1014
+ result.packetsReceived -
1015
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived;
1016
+ this.statsResults.internal[mediaType][sendrecvType].totalPacketsReceived =
1017
+ result.packetsReceived;
809
1018
 
810
1019
  if (this.statsResults[mediaType][sendrecvType].packetsReceived === 0) {
811
- LoggerProxy.logger.info(`StatsAnalyzer:index#processInboundRTPResult --> No packets received for ${mediaType} `, this.statsResults[mediaType][sendrecvType].packetsReceived);
1020
+ if (receiveSlot) {
1021
+ LoggerProxy.logger.info(
1022
+ `StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot ${idAndCsi}`,
1023
+ this.statsResults[mediaType][sendrecvType].packetsReceived
1024
+ );
1025
+ }
812
1026
  }
813
1027
 
814
1028
  // 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;
1029
+ this.statsResults[mediaType][sendrecvType].currentPacketLossRatio =
1030
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost > 0
1031
+ ? this.statsResults[mediaType][sendrecvType].currentPacketsLost /
1032
+ (this.statsResults[mediaType][sendrecvType].packetsReceived +
1033
+ this.statsResults[mediaType][sendrecvType].currentPacketsLost)
1034
+ : 0;
816
1035
  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);
1036
+ LoggerProxy.logger.info(
1037
+ `StatsAnalyzer:index#processInboundRTPResult --> Packets getting lost from the receiver with slot ${idAndCsi}`,
1038
+ this.statsResults[mediaType][sendrecvType].currentPacketLossRatio
1039
+ );
818
1040
  }
819
1041
 
820
1042
  // TODO: check the packet loss value is negative values here
821
1043
 
822
1044
  if (result.packetsLost) {
823
- this.statsResults[mediaType][sendrecvType].totalPacketsLost = result.packetsLost > 0 ? result.packetsLost : -result.packetsLost;
824
- }
825
- else {
1045
+ this.statsResults[mediaType][sendrecvType].totalPacketsLost =
1046
+ result.packetsLost > 0 ? result.packetsLost : -result.packetsLost;
1047
+ } else {
826
1048
  this.statsResults[mediaType][sendrecvType].totalPacketsLost = 0;
827
1049
  }
828
1050
 
829
- this.statsResults[mediaType][sendrecvType].lastPacketReceivedTimestamp = result.lastPacketReceivedTimestamp;
1051
+ this.statsResults[mediaType][sendrecvType].lastPacketReceivedTimestamp =
1052
+ result.lastPacketReceivedTimestamp;
830
1053
 
831
1054
  // From Thin
832
1055
  this.statsResults[mediaType][sendrecvType].totalNackCount = result.nackCount;
@@ -834,10 +1057,10 @@ export class StatsAnalyzer extends EventsScope {
834
1057
  this.statsResults[mediaType][sendrecvType].framesDecoded = result.framesDecoded;
835
1058
  this.statsResults[mediaType][sendrecvType].keyFramesDecoded = result.keyFramesDecoded;
836
1059
 
837
- this.statsResults[mediaType][sendrecvType].decoderImplementation = result.decoderImplementation;
1060
+ this.statsResults[mediaType][sendrecvType].decoderImplementation =
1061
+ result.decoderImplementation;
838
1062
  this.statsResults[mediaType][sendrecvType].totalPacketsReceived = result.packetsReceived;
839
1063
 
840
-
841
1064
  this.statsResults[mediaType][sendrecvType].fecPacketsDiscarded = result.fecPacketsDiscarded;
842
1065
  this.statsResults[mediaType][sendrecvType].fecPacketsReceived = result.fecPacketsReceived;
843
1066
  this.statsResults[mediaType][sendrecvType].totalBytesReceived = result.bytesReceived;
@@ -849,8 +1072,10 @@ export class StatsAnalyzer extends EventsScope {
849
1072
 
850
1073
  this.statsResults[mediaType][sendrecvType].audioLevel = result.audioLevel;
851
1074
  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;
1075
+ this.statsResults[mediaType][sendrecvType].totalSamplesReceived =
1076
+ result.totalSamplesReceived || 0;
1077
+ this.statsResults[mediaType][sendrecvType].totalSamplesDecoded =
1078
+ result.totalSamplesDecoded || 0;
854
1079
  this.statsResults[mediaType][sendrecvType].concealedSamples = result.concealedSamples || 0;
855
1080
  }
856
1081
  }
@@ -894,7 +1119,10 @@ export class StatsAnalyzer extends EventsScope {
894
1119
  RemoteNetworkType[result.id] = [];
895
1120
  }
896
1121
 
897
- if (result.candidateType && RemoteCandidateType[result.id].indexOf(result.candidateType) === -1) {
1122
+ if (
1123
+ result.candidateType &&
1124
+ RemoteCandidateType[result.id].indexOf(result.candidateType) === -1
1125
+ ) {
898
1126
  RemoteCandidateType[result.id].push(result.candidateType);
899
1127
  }
900
1128
 
@@ -902,7 +1130,10 @@ export class StatsAnalyzer extends EventsScope {
902
1130
  RemoteTransport[result.id].push(result.protocol.toUpperCase());
903
1131
  }
904
1132
 
905
- if (result.ip && RemoteIpAddress[result.id].indexOf(`${result.ip}:${result.portNumber}`) === -1) {
1133
+ if (
1134
+ result.ip &&
1135
+ RemoteIpAddress[result.id].indexOf(`${result.ip}:${result.portNumber}`) === -1
1136
+ ) {
906
1137
  RemoteIpAddress[result.id].push(`${result.ip}`); // TODO: Add ports
907
1138
  }
908
1139
 
@@ -919,13 +1150,16 @@ export class StatsAnalyzer extends EventsScope {
919
1150
  transport: RemoteTransport[result.id],
920
1151
  timestamp: result.time,
921
1152
  id: result.id,
922
- type: result.type
1153
+ type: result.type,
923
1154
  };
924
1155
 
925
1156
  this.statsResults.connectionType[ipType].candidateType = RemoteCandidateType[result.id];
926
1157
  this.statsResults.connectionType[ipType].ipAddress = RemoteIpAddress[result.id];
927
1158
 
928
- this.statsResults.connectionType[ipType].networkType = RemoteNetworkType[result.id][0] === NETWORK_TYPE.VPN ? NETWORK_TYPE.UNKNOWN : RemoteNetworkType[result.id][0];
1159
+ this.statsResults.connectionType[ipType].networkType =
1160
+ RemoteNetworkType[result.id][0] === NETWORK_TYPE.VPN
1161
+ ? NETWORK_TYPE.UNKNOWN
1162
+ : RemoteNetworkType[result.id][0];
929
1163
  this.statsResults.connectionType[ipType].transport = RemoteTransport[result.id];
930
1164
 
931
1165
  this.statsResults[type][sendRecvType].totalRoundTripTime = result.totalRoundTripTime;
@@ -944,16 +1178,9 @@ export class StatsAnalyzer extends EventsScope {
944
1178
  if (!result || result.type !== 'track') {
945
1179
  return;
946
1180
  }
947
- if (result.type !== 'track') return;
948
1181
 
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
- }
1182
+ const sendrecvType =
1183
+ result.remoteSource === true ? STATS.RECEIVE_DIRECTION : STATS.SEND_DIRECTION;
957
1184
 
958
1185
  if (sendrecvType === STATS.RECEIVE_DIRECTION) {
959
1186
  this.statsResults.resolutions[mediaType][sendrecvType].framesReceived = result.framesReceived;
@@ -961,18 +1188,21 @@ export class StatsAnalyzer extends EventsScope {
961
1188
  this.statsResults.resolutions[mediaType][sendrecvType].framesDropped = result.framesDropped;
962
1189
  }
963
1190
 
964
-
965
- if (result.trackIdentifier && mediaType !== STATS.AUDIO_CORRELATE) {
966
- this.statsResults.resolutions[mediaType][sendrecvType].trackIdentifier = result.trackIdentifier;
1191
+ if (result.trackIdentifier && !mediaType.includes('audio')) {
1192
+ this.statsResults.resolutions[mediaType][sendrecvType].trackIdentifier =
1193
+ result.trackIdentifier;
967
1194
 
968
1195
  const jitterBufferDelay = result && result.jitterBufferDelay;
969
1196
  const jitterBufferEmittedCount = result && result.jitterBufferEmittedCount;
970
1197
 
971
- this.statsResults.resolutions[mediaType][sendrecvType].avgJitterDelay = jitterBufferEmittedCount && (+jitterBufferDelay / +jitterBufferEmittedCount);
1198
+ this.statsResults.resolutions[mediaType][sendrecvType].avgJitterDelay =
1199
+ jitterBufferEmittedCount && +jitterBufferDelay / +jitterBufferEmittedCount;
972
1200
 
973
1201
  // Used to calculate the jitter
974
- this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay = result.jitterBufferDelay;
975
- this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount = result.jitterBufferEmittedCount;
1202
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferDelay =
1203
+ result.jitterBufferDelay;
1204
+ this.statsResults.resolutions[mediaType][sendrecvType].jitterBufferEmittedCount =
1205
+ result.jitterBufferEmittedCount;
976
1206
  }
977
1207
  }
978
1208
 
@@ -984,16 +1214,20 @@ export class StatsAnalyzer extends EventsScope {
984
1214
  * @returns {void}
985
1215
  * @memberof StatsAnalyzer
986
1216
  */
987
- private compareSentAndReceived(result: any, type: any) {
988
- if (!type) {
1217
+ compareSentAndReceived(result, type) {
1218
+ // Don't compare on transceivers without a sender.
1219
+ if (!type || !this.statsResults.internal[type].send) {
989
1220
  return;
990
1221
  }
991
1222
 
992
1223
  const mediaType = type;
993
1224
 
994
- if (!this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver) { this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost; }
1225
+ if (!this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver) {
1226
+ this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
1227
+ }
995
1228
 
996
- const currentPacketLoss = result.packetsLost - this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver;
1229
+ const currentPacketLoss =
1230
+ result.packetsLost - this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver;
997
1231
 
998
1232
  this.statsResults.internal[mediaType].send.totalPacketsLostOnReceiver = result.packetsLost;
999
1233
  this.statsResults[mediaType].send.packetsLostOnReceiver = currentPacketLoss;
@@ -1007,18 +1241,31 @@ export class StatsAnalyzer extends EventsScope {
1007
1241
  this.statsResults[mediaType].send.reportsReceived = result.reportsReceived;
1008
1242
 
1009
1243
  // 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;
1244
+ this.statsResults[mediaType].send.overAllPacketLossRatio =
1245
+ this.statsResults[mediaType].send.totalPacketsLostOnReceiver > 0
1246
+ ? this.statsResults[mediaType].send.totalPacketsLostOnReceiver /
1247
+ this.statsResults[mediaType].send.totalPacketsSent
1248
+ : 0;
1249
+ this.statsResults[mediaType].send.currentPacketLossRatio =
1250
+ this.statsResults[mediaType].send.packetsLostOnReceiver > 0
1251
+ ? (this.statsResults[mediaType].send.packetsLostOnReceiver * 100) /
1252
+ (this.statsResults[mediaType].send.packetsSent +
1253
+ this.statsResults[mediaType].send.packetsLostOnReceiver)
1254
+ : 0;
1255
+
1256
+ if (
1257
+ this.statsResults[mediaType].send.maxPacketLossRatio <
1258
+ this.statsResults[mediaType].send.currentPacketLossRatio
1259
+ ) {
1260
+ this.statsResults[mediaType].send.maxPacketLossRatio =
1261
+ this.statsResults[mediaType].send.currentPacketLossRatio;
1015
1262
  }
1016
1263
 
1017
1264
  if (result.type === 'remote-inbound-rtp') {
1018
1265
  this.networkQualityMonitor.determineUplinkNetworkQuality({
1019
1266
  mediaType,
1020
1267
  remoteRtpResults: result,
1021
- statsAnalyzerCurrentStats: this.statsResults
1268
+ statsAnalyzerCurrentStats: this.statsResults,
1022
1269
  });
1023
1270
  }
1024
1271
  }