@webex/plugin-meetings 3.0.0-beta.9 → 3.0.0-beta.91

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 (507) hide show
  1. package/UPGRADING.md +9 -9
  2. package/browsers.js +19 -24
  3. package/dist/annotation/annotation.types.js +7 -0
  4. package/dist/annotation/annotation.types.js.map +1 -0
  5. package/dist/annotation/constants.js +48 -0
  6. package/dist/annotation/constants.js.map +1 -0
  7. package/dist/annotation/index.js +325 -0
  8. package/dist/annotation/index.js.map +1 -0
  9. package/dist/breakouts/breakout.js +180 -0
  10. package/dist/breakouts/breakout.js.map +1 -0
  11. package/dist/breakouts/collection.js +23 -0
  12. package/dist/breakouts/collection.js.map +1 -0
  13. package/dist/breakouts/edit-lock-error.js +52 -0
  14. package/dist/breakouts/edit-lock-error.js.map +1 -0
  15. package/dist/breakouts/index.js +868 -0
  16. package/dist/breakouts/index.js.map +1 -0
  17. package/dist/breakouts/request.js +78 -0
  18. package/dist/breakouts/request.js.map +1 -0
  19. package/dist/breakouts/utils.js +67 -0
  20. package/dist/breakouts/utils.js.map +1 -0
  21. package/dist/common/browser-detection.js +1 -20
  22. package/dist/common/browser-detection.js.map +1 -1
  23. package/dist/common/collection.js +5 -20
  24. package/dist/common/collection.js.map +1 -1
  25. package/dist/common/config.js +0 -7
  26. package/dist/common/config.js.map +1 -1
  27. package/dist/common/errors/captcha-error.js +5 -26
  28. package/dist/common/errors/captcha-error.js.map +1 -1
  29. package/dist/common/errors/intent-to-join.js +5 -26
  30. package/dist/common/errors/intent-to-join.js.map +1 -1
  31. package/dist/common/errors/join-meeting.js +6 -27
  32. package/dist/common/errors/join-meeting.js.map +1 -1
  33. package/dist/common/errors/media.js +5 -26
  34. package/dist/common/errors/media.js.map +1 -1
  35. package/dist/common/errors/parameter.js +5 -33
  36. package/dist/common/errors/parameter.js.map +1 -1
  37. package/dist/common/errors/password-error.js +5 -26
  38. package/dist/common/errors/password-error.js.map +1 -1
  39. package/dist/common/errors/permission.js +4 -25
  40. package/dist/common/errors/permission.js.map +1 -1
  41. package/dist/common/errors/reconnection-in-progress.js +0 -17
  42. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  43. package/dist/common/errors/reconnection.js +5 -26
  44. package/dist/common/errors/reconnection.js.map +1 -1
  45. package/dist/common/errors/stats.js +5 -26
  46. package/dist/common/errors/stats.js.map +1 -1
  47. package/dist/common/errors/webex-errors.js +6 -41
  48. package/dist/common/errors/webex-errors.js.map +1 -1
  49. package/dist/common/errors/webex-meetings-error.js +1 -24
  50. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  51. package/dist/common/events/events-scope.js +0 -22
  52. package/dist/common/events/events-scope.js.map +1 -1
  53. package/dist/common/events/events.js +0 -23
  54. package/dist/common/events/events.js.map +1 -1
  55. package/dist/common/events/trigger-proxy.js +0 -12
  56. package/dist/common/events/trigger-proxy.js.map +1 -1
  57. package/dist/common/events/util.js +0 -15
  58. package/dist/common/events/util.js.map +1 -1
  59. package/dist/common/logs/logger-config.js +0 -4
  60. package/dist/common/logs/logger-config.js.map +1 -1
  61. package/dist/common/logs/logger-proxy.js +1 -8
  62. package/dist/common/logs/logger-proxy.js.map +1 -1
  63. package/dist/common/logs/request.js +35 -61
  64. package/dist/common/logs/request.js.map +1 -1
  65. package/dist/common/queue.js +4 -14
  66. package/dist/common/queue.js.map +1 -1
  67. package/dist/config.js +7 -6
  68. package/dist/config.js.map +1 -1
  69. package/dist/constants.js +169 -52
  70. package/dist/constants.js.map +1 -1
  71. package/dist/controls-options-manager/constants.js +14 -0
  72. package/dist/controls-options-manager/constants.js.map +1 -0
  73. package/dist/controls-options-manager/enums.js +25 -0
  74. package/dist/controls-options-manager/enums.js.map +1 -0
  75. package/dist/controls-options-manager/index.js +292 -0
  76. package/dist/controls-options-manager/index.js.map +1 -0
  77. package/dist/controls-options-manager/types.js +7 -0
  78. package/dist/controls-options-manager/types.js.map +1 -0
  79. package/dist/controls-options-manager/util.js +250 -0
  80. package/dist/controls-options-manager/util.js.map +1 -0
  81. package/dist/index.js +72 -17
  82. package/dist/index.js.map +1 -1
  83. package/dist/locus-info/controlsUtils.js +56 -29
  84. package/dist/locus-info/controlsUtils.js.map +1 -1
  85. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  86. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  87. package/dist/locus-info/fullState.js +0 -15
  88. package/dist/locus-info/fullState.js.map +1 -1
  89. package/dist/locus-info/hostUtils.js +4 -12
  90. package/dist/locus-info/hostUtils.js.map +1 -1
  91. package/dist/locus-info/index.js +325 -208
  92. package/dist/locus-info/index.js.map +1 -1
  93. package/dist/locus-info/infoUtils.js +3 -37
  94. package/dist/locus-info/infoUtils.js.map +1 -1
  95. package/dist/locus-info/mediaSharesUtils.js +12 -38
  96. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  97. package/dist/locus-info/parser.js +88 -123
  98. package/dist/locus-info/parser.js.map +1 -1
  99. package/dist/locus-info/selfUtils.js +87 -91
  100. package/dist/locus-info/selfUtils.js.map +1 -1
  101. package/dist/media/index.js +62 -147
  102. package/dist/media/index.js.map +1 -1
  103. package/dist/media/properties.js +71 -117
  104. package/dist/media/properties.js.map +1 -1
  105. package/dist/media/util.js +2 -9
  106. package/dist/media/util.js.map +1 -1
  107. package/dist/mediaQualityMetrics/config.js +505 -495
  108. package/dist/mediaQualityMetrics/config.js.map +1 -1
  109. package/dist/meeting/in-meeting-actions.js +35 -14
  110. package/dist/meeting/in-meeting-actions.js.map +1 -1
  111. package/dist/meeting/index.js +2261 -2269
  112. package/dist/meeting/index.js.map +1 -1
  113. package/dist/meeting/muteState.js +252 -113
  114. package/dist/meeting/muteState.js.map +1 -1
  115. package/dist/meeting/request.js +318 -283
  116. package/dist/meeting/request.js.map +1 -1
  117. package/dist/meeting/request.type.js +7 -0
  118. package/dist/meeting/request.type.js.map +1 -0
  119. package/dist/meeting/state.js +21 -31
  120. package/dist/meeting/state.js.map +1 -1
  121. package/dist/meeting/util.js +69 -217
  122. package/dist/meeting/util.js.map +1 -1
  123. package/dist/meeting-info/collection.js +3 -25
  124. package/dist/meeting-info/collection.js.map +1 -1
  125. package/dist/meeting-info/index.js +10 -33
  126. package/dist/meeting-info/index.js.map +1 -1
  127. package/dist/meeting-info/meeting-info-v2.js +258 -281
  128. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  129. package/dist/meeting-info/request.js +1 -16
  130. package/dist/meeting-info/request.js.map +1 -1
  131. package/dist/meeting-info/util.js +98 -183
  132. package/dist/meeting-info/util.js.map +1 -1
  133. package/dist/meeting-info/utilv2.js +154 -232
  134. package/dist/meeting-info/utilv2.js.map +1 -1
  135. package/dist/meetings/collection.js +24 -20
  136. package/dist/meetings/collection.js.map +1 -1
  137. package/dist/meetings/index.js +573 -587
  138. package/dist/meetings/index.js.map +1 -1
  139. package/dist/meetings/request.js +23 -42
  140. package/dist/meetings/request.js.map +1 -1
  141. package/dist/meetings/util.js +164 -155
  142. package/dist/meetings/util.js.map +1 -1
  143. package/dist/member/index.js +80 -88
  144. package/dist/member/index.js.map +1 -1
  145. package/dist/member/types.js +15 -0
  146. package/dist/member/types.js.map +1 -0
  147. package/dist/member/util.js +90 -69
  148. package/dist/member/util.js.map +1 -1
  149. package/dist/members/collection.js +12 -12
  150. package/dist/members/collection.js.map +1 -1
  151. package/dist/members/index.js +162 -204
  152. package/dist/members/index.js.map +1 -1
  153. package/dist/members/request.js +58 -53
  154. package/dist/members/request.js.map +1 -1
  155. package/dist/members/types.js +15 -0
  156. package/dist/members/types.js.map +1 -0
  157. package/dist/members/util.js +107 -44
  158. package/dist/members/util.js.map +1 -1
  159. package/dist/metrics/config.js +4 -14
  160. package/dist/metrics/config.js.map +1 -1
  161. package/dist/metrics/constants.js +3 -7
  162. package/dist/metrics/constants.js.map +1 -1
  163. package/dist/metrics/index.js +56 -159
  164. package/dist/metrics/index.js.map +1 -1
  165. package/dist/multistream/mediaRequestManager.js +167 -50
  166. package/dist/multistream/mediaRequestManager.js.map +1 -1
  167. package/dist/multistream/receiveSlot.js +58 -65
  168. package/dist/multistream/receiveSlot.js.map +1 -1
  169. package/dist/multistream/receiveSlotManager.js +74 -93
  170. package/dist/multistream/receiveSlotManager.js.map +1 -1
  171. package/dist/multistream/remoteMedia.js +55 -74
  172. package/dist/multistream/remoteMedia.js.map +1 -1
  173. package/dist/multistream/remoteMediaGroup.js +6 -40
  174. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  175. package/dist/multistream/remoteMediaManager.js +466 -442
  176. package/dist/multistream/remoteMediaManager.js.map +1 -1
  177. package/dist/networkQualityMonitor/index.js +32 -59
  178. package/dist/networkQualityMonitor/index.js.map +1 -1
  179. package/dist/personal-meeting-room/index.js +10 -45
  180. package/dist/personal-meeting-room/index.js.map +1 -1
  181. package/dist/personal-meeting-room/request.js +2 -33
  182. package/dist/personal-meeting-room/request.js.map +1 -1
  183. package/dist/personal-meeting-room/util.js +0 -13
  184. package/dist/personal-meeting-room/util.js.map +1 -1
  185. package/dist/reachability/index.js +190 -199
  186. package/dist/reachability/index.js.map +1 -1
  187. package/dist/reachability/request.js +14 -23
  188. package/dist/reachability/request.js.map +1 -1
  189. package/dist/reactions/constants.js +13 -0
  190. package/dist/reactions/constants.js.map +1 -0
  191. package/dist/reactions/reactions.js +109 -0
  192. package/dist/reactions/reactions.js.map +1 -0
  193. package/dist/reactions/reactions.type.js +36 -0
  194. package/dist/reactions/reactions.type.js.map +1 -0
  195. package/dist/reconnection-manager/index.js +326 -465
  196. package/dist/reconnection-manager/index.js.map +1 -1
  197. package/dist/recording-controller/enums.js +17 -0
  198. package/dist/recording-controller/enums.js.map +1 -0
  199. package/dist/recording-controller/index.js +343 -0
  200. package/dist/recording-controller/index.js.map +1 -0
  201. package/dist/recording-controller/util.js +63 -0
  202. package/dist/recording-controller/util.js.map +1 -0
  203. package/dist/roap/index.js +38 -67
  204. package/dist/roap/index.js.map +1 -1
  205. package/dist/roap/request.js +143 -134
  206. package/dist/roap/request.js.map +1 -1
  207. package/dist/roap/turnDiscovery.js +149 -101
  208. package/dist/roap/turnDiscovery.js.map +1 -1
  209. package/dist/statsAnalyzer/global.js +1 -95
  210. package/dist/statsAnalyzer/global.js.map +1 -1
  211. package/dist/statsAnalyzer/index.js +369 -461
  212. package/dist/statsAnalyzer/index.js.map +1 -1
  213. package/dist/statsAnalyzer/mqaUtil.js +144 -94
  214. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  215. package/dist/transcription/index.js +13 -45
  216. package/dist/transcription/index.js.map +1 -1
  217. package/dist/types/annotation/annotation.types.d.ts +33 -0
  218. package/dist/types/annotation/constants.d.ts +31 -0
  219. package/dist/types/annotation/index.d.ts +117 -0
  220. package/dist/types/breakouts/breakout.d.ts +8 -0
  221. package/dist/types/breakouts/collection.d.ts +5 -0
  222. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  223. package/dist/types/breakouts/index.d.ts +5 -0
  224. package/dist/types/breakouts/request.d.ts +22 -0
  225. package/dist/types/breakouts/utils.d.ts +15 -0
  226. package/dist/types/common/browser-detection.d.ts +9 -0
  227. package/dist/types/common/collection.d.ts +48 -0
  228. package/dist/types/common/config.d.ts +2 -0
  229. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  230. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  231. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  232. package/dist/types/common/errors/media.d.ts +15 -0
  233. package/dist/types/common/errors/parameter.d.ts +15 -0
  234. package/dist/types/common/errors/password-error.d.ts +15 -0
  235. package/dist/types/common/errors/permission.d.ts +14 -0
  236. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  237. package/dist/types/common/errors/reconnection.d.ts +15 -0
  238. package/dist/types/common/errors/stats.d.ts +15 -0
  239. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  240. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  241. package/dist/types/common/events/events-scope.d.ts +17 -0
  242. package/dist/types/common/events/events.d.ts +12 -0
  243. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  244. package/dist/types/common/events/util.d.ts +2 -0
  245. package/dist/types/common/logs/logger-config.d.ts +2 -0
  246. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  247. package/dist/types/common/logs/request.d.ts +34 -0
  248. package/dist/types/common/queue.d.ts +32 -0
  249. package/dist/types/config.d.ts +78 -0
  250. package/dist/types/constants.d.ts +965 -0
  251. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  252. package/dist/types/controls-options-manager/enums.d.ts +13 -0
  253. package/dist/types/controls-options-manager/index.d.ts +136 -0
  254. package/dist/types/controls-options-manager/types.d.ts +37 -0
  255. package/dist/types/controls-options-manager/util.d.ts +1 -0
  256. package/dist/types/index.d.ts +7 -0
  257. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  258. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  259. package/dist/types/locus-info/fullState.d.ts +2 -0
  260. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  261. package/dist/types/locus-info/index.d.ts +314 -0
  262. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  263. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  264. package/dist/types/locus-info/parser.d.ts +212 -0
  265. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  266. package/dist/types/media/index.d.ts +34 -0
  267. package/dist/types/media/properties.d.ts +108 -0
  268. package/dist/types/media/util.d.ts +2 -0
  269. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  270. package/dist/types/meeting/in-meeting-actions.d.ts +105 -0
  271. package/dist/types/meeting/index.d.ts +1727 -0
  272. package/dist/types/meeting/muteState.d.ts +185 -0
  273. package/dist/types/meeting/request.d.ts +275 -0
  274. package/dist/types/meeting/request.type.d.ts +11 -0
  275. package/dist/types/meeting/state.d.ts +9 -0
  276. package/dist/types/meeting/util.d.ts +2 -0
  277. package/dist/types/meeting-info/collection.d.ts +20 -0
  278. package/dist/types/meeting-info/index.d.ts +57 -0
  279. package/dist/types/meeting-info/meeting-info-v2.d.ts +111 -0
  280. package/dist/types/meeting-info/request.d.ts +22 -0
  281. package/dist/types/meeting-info/util.d.ts +2 -0
  282. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  283. package/dist/types/meetings/collection.d.ts +31 -0
  284. package/dist/types/meetings/index.d.ts +316 -0
  285. package/dist/types/meetings/request.d.ts +27 -0
  286. package/dist/types/meetings/util.d.ts +18 -0
  287. package/dist/types/member/index.d.ts +156 -0
  288. package/dist/types/member/types.d.ts +21 -0
  289. package/dist/types/member/util.d.ts +2 -0
  290. package/dist/types/members/collection.d.ts +29 -0
  291. package/dist/types/members/index.d.ts +353 -0
  292. package/dist/types/members/request.d.ts +69 -0
  293. package/dist/types/members/types.d.ts +24 -0
  294. package/dist/types/members/util.d.ts +2 -0
  295. package/dist/types/metrics/config.d.ts +171 -0
  296. package/dist/types/metrics/constants.d.ts +54 -0
  297. package/dist/types/metrics/index.d.ts +152 -0
  298. package/dist/types/multistream/mediaRequestManager.d.ts +101 -0
  299. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  300. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  301. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  302. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  303. package/dist/types/multistream/remoteMediaManager.d.ts +263 -0
  304. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  305. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  306. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  307. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  308. package/dist/types/reachability/index.d.ts +152 -0
  309. package/dist/types/reachability/request.d.ts +37 -0
  310. package/dist/types/reactions/constants.d.ts +3 -0
  311. package/dist/types/reactions/reactions.d.ts +4 -0
  312. package/dist/types/reactions/reactions.type.d.ts +52 -0
  313. package/dist/types/reconnection-manager/index.d.ts +126 -0
  314. package/dist/types/recording-controller/enums.d.ts +7 -0
  315. package/dist/types/recording-controller/index.d.ts +193 -0
  316. package/dist/types/recording-controller/util.d.ts +13 -0
  317. package/dist/types/roap/index.d.ts +77 -0
  318. package/dist/types/roap/request.d.ts +38 -0
  319. package/dist/types/roap/turnDiscovery.d.ts +88 -0
  320. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  321. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  322. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  323. package/dist/types/transcription/index.d.ts +64 -0
  324. package/internal-README.md +7 -6
  325. package/package.json +28 -20
  326. package/src/annotation/annotation.types.ts +37 -0
  327. package/src/annotation/constants.ts +36 -0
  328. package/src/annotation/index.ts +314 -0
  329. package/src/breakouts/README.md +219 -0
  330. package/src/breakouts/breakout.ts +154 -0
  331. package/src/breakouts/collection.ts +19 -0
  332. package/src/breakouts/edit-lock-error.ts +25 -0
  333. package/src/breakouts/index.ts +776 -0
  334. package/src/breakouts/request.ts +55 -0
  335. package/src/breakouts/utils.ts +57 -0
  336. package/src/common/browser-detection.ts +9 -6
  337. package/src/common/collection.ts +3 -1
  338. package/src/common/errors/captcha-error.ts +6 -6
  339. package/src/common/errors/intent-to-join.ts +6 -6
  340. package/src/common/errors/join-meeting.ts +12 -8
  341. package/src/common/errors/media.ts +6 -6
  342. package/src/common/errors/parameter.ts +9 -6
  343. package/src/common/errors/password-error.ts +6 -6
  344. package/src/common/errors/permission.ts +5 -5
  345. package/src/common/errors/reconnection.ts +6 -6
  346. package/src/common/errors/stats.ts +6 -6
  347. package/src/common/errors/webex-errors.ts +7 -5
  348. package/src/common/errors/webex-meetings-error.ts +1 -1
  349. package/src/common/events/events-scope.ts +5 -1
  350. package/src/common/events/events.ts +5 -1
  351. package/src/common/events/trigger-proxy.ts +8 -3
  352. package/src/common/events/util.ts +1 -2
  353. package/src/common/logs/logger-proxy.ts +21 -10
  354. package/src/common/logs/request.ts +11 -8
  355. package/src/config.ts +17 -12
  356. package/src/constants.ts +116 -6
  357. package/src/controls-options-manager/constants.ts +5 -0
  358. package/src/controls-options-manager/enums.ts +16 -0
  359. package/src/controls-options-manager/index.ts +275 -0
  360. package/src/controls-options-manager/types.ts +49 -0
  361. package/src/controls-options-manager/util.ts +229 -0
  362. package/src/index.ts +33 -0
  363. package/src/locus-info/controlsUtils.ts +91 -24
  364. package/src/locus-info/fullState.ts +15 -11
  365. package/src/locus-info/hostUtils.ts +4 -3
  366. package/src/locus-info/index.ts +265 -51
  367. package/src/locus-info/infoUtils.ts +16 -4
  368. package/src/locus-info/mediaSharesUtils.ts +4 -4
  369. package/src/locus-info/parser.ts +46 -68
  370. package/src/locus-info/selfUtils.ts +178 -57
  371. package/src/media/index.ts +142 -172
  372. package/src/media/properties.ts +43 -36
  373. package/src/media/util.ts +1 -1
  374. package/src/mediaQualityMetrics/config.ts +380 -378
  375. package/src/meeting/in-meeting-actions.ts +75 -3
  376. package/src/meeting/index.ts +2504 -1522
  377. package/src/meeting/muteState.ts +271 -68
  378. package/src/meeting/request.ts +251 -132
  379. package/src/meeting/request.type.ts +13 -0
  380. package/src/meeting/state.ts +45 -30
  381. package/src/meeting/util.ts +132 -111
  382. package/src/meeting-info/collection.ts +2 -1
  383. package/src/meeting-info/index.ts +32 -30
  384. package/src/meeting-info/meeting-info-v2.ts +178 -109
  385. package/src/meeting-info/request.ts +9 -3
  386. package/src/meeting-info/util.ts +54 -46
  387. package/src/meeting-info/utilv2.ts +69 -57
  388. package/src/meetings/collection.ts +21 -1
  389. package/src/meetings/index.ts +687 -467
  390. package/src/meetings/request.ts +29 -25
  391. package/src/meetings/util.ts +108 -33
  392. package/src/member/index.ts +86 -49
  393. package/src/member/types.ts +24 -0
  394. package/src/member/util.ts +92 -13
  395. package/src/members/collection.ts +8 -1
  396. package/src/members/index.ts +281 -129
  397. package/src/members/request.ts +87 -14
  398. package/src/members/types.ts +28 -0
  399. package/src/members/util.ts +140 -49
  400. package/src/metrics/config.ts +255 -90
  401. package/src/metrics/constants.ts +1 -6
  402. package/src/metrics/index.ts +91 -94
  403. package/src/multistream/mediaRequestManager.ts +201 -43
  404. package/src/multistream/receiveSlot.ts +69 -26
  405. package/src/multistream/receiveSlotManager.ts +62 -38
  406. package/src/multistream/remoteMedia.ts +30 -4
  407. package/src/multistream/remoteMediaGroup.ts +4 -3
  408. package/src/multistream/remoteMediaManager.ts +230 -66
  409. package/src/networkQualityMonitor/index.ts +24 -27
  410. package/src/personal-meeting-room/index.ts +12 -16
  411. package/src/personal-meeting-room/request.ts +10 -3
  412. package/src/personal-meeting-room/util.ts +3 -3
  413. package/src/reachability/index.ts +131 -79
  414. package/src/reachability/request.ts +43 -34
  415. package/src/reactions/constants.ts +4 -0
  416. package/src/reactions/reactions.ts +104 -0
  417. package/src/reactions/reactions.type.ts +62 -0
  418. package/src/reconnection-manager/index.ts +193 -111
  419. package/src/recording-controller/enums.ts +8 -0
  420. package/src/recording-controller/index.ts +315 -0
  421. package/src/recording-controller/util.ts +58 -0
  422. package/src/roap/index.ts +63 -51
  423. package/src/roap/request.ts +86 -53
  424. package/src/roap/turnDiscovery.ts +105 -46
  425. package/src/statsAnalyzer/global.ts +8 -104
  426. package/src/statsAnalyzer/index.ts +624 -376
  427. package/src/statsAnalyzer/mqaUtil.ts +203 -90
  428. package/src/transcription/index.ts +34 -32
  429. package/test/integration/spec/converged-space-meetings.js +177 -0
  430. package/test/integration/spec/journey.js +666 -464
  431. package/test/integration/spec/space-meeting.js +320 -204
  432. package/test/integration/spec/transcription.js +7 -8
  433. package/test/unit/spec/annotation/index.ts +420 -0
  434. package/test/unit/spec/breakouts/breakout.ts +178 -0
  435. package/test/unit/spec/breakouts/collection.ts +15 -0
  436. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  437. package/test/unit/spec/breakouts/index.ts +1416 -0
  438. package/test/unit/spec/breakouts/request.ts +104 -0
  439. package/test/unit/spec/breakouts/utils.js +72 -0
  440. package/test/unit/spec/common/browser-detection.js +9 -28
  441. package/test/unit/spec/controls-options-manager/index.js +280 -0
  442. package/test/unit/spec/controls-options-manager/util.js +403 -0
  443. package/test/unit/spec/fixture/locus.js +92 -90
  444. package/test/unit/spec/locus-info/controlsUtils.js +177 -32
  445. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  446. package/test/unit/spec/locus-info/index.js +484 -3
  447. package/test/unit/spec/locus-info/infoUtils.js +41 -32
  448. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  449. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  450. package/test/unit/spec/locus-info/parser.js +3 -9
  451. package/test/unit/spec/locus-info/selfConstant.js +101 -103
  452. package/test/unit/spec/locus-info/selfUtils.js +191 -12
  453. package/test/unit/spec/media/index.ts +104 -8
  454. package/test/unit/spec/media/properties.ts +9 -9
  455. package/test/unit/spec/meeting/in-meeting-actions.ts +34 -3
  456. package/test/unit/spec/meeting/index.js +2672 -828
  457. package/test/unit/spec/meeting/muteState.js +368 -70
  458. package/test/unit/spec/meeting/request.js +217 -43
  459. package/test/unit/spec/meeting/utils.js +167 -163
  460. package/test/unit/spec/meeting-info/meetinginfov2.js +241 -74
  461. package/test/unit/spec/meeting-info/request.js +7 -9
  462. package/test/unit/spec/meeting-info/util.js +11 -12
  463. package/test/unit/spec/meeting-info/utilv2.js +110 -74
  464. package/test/unit/spec/meetings/collection.js +15 -1
  465. package/test/unit/spec/meetings/index.js +701 -273
  466. package/test/unit/spec/meetings/utils.js +105 -14
  467. package/test/unit/spec/member/index.js +24 -1
  468. package/test/unit/spec/member/util.js +359 -32
  469. package/test/unit/spec/members/index.js +402 -54
  470. package/test/unit/spec/members/request.js +76 -20
  471. package/test/unit/spec/members/utils.js +191 -4
  472. package/test/unit/spec/metrics/index.js +46 -20
  473. package/test/unit/spec/multistream/mediaRequestManager.ts +650 -105
  474. package/test/unit/spec/multistream/receiveSlot.ts +76 -17
  475. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  476. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  477. package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
  478. package/test/unit/spec/multistream/remoteMediaManager.ts +549 -65
  479. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  480. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  481. package/test/unit/spec/reachability/index.ts +176 -27
  482. package/test/unit/spec/reachability/request.js +66 -0
  483. package/test/unit/spec/reconnection-manager/index.js +62 -31
  484. package/test/unit/spec/recording-controller/index.js +231 -0
  485. package/test/unit/spec/recording-controller/util.js +102 -0
  486. package/test/unit/spec/roap/index.ts +21 -16
  487. package/test/unit/spec/roap/request.ts +217 -0
  488. package/test/unit/spec/roap/turnDiscovery.ts +93 -49
  489. package/test/unit/spec/stats-analyzer/index.js +116 -60
  490. package/test/utils/cmr.js +44 -42
  491. package/test/utils/constants.js +9 -0
  492. package/test/utils/integrationTestUtils.js +64 -0
  493. package/test/utils/testUtils.js +63 -99
  494. package/test/utils/webex-config.js +22 -18
  495. package/test/utils/webex-test-users.js +57 -50
  496. package/tsconfig.json +6 -0
  497. package/dist/media/internal-media-core-wrapper.js +0 -22
  498. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  499. package/dist/meeting/effectsState.js +0 -334
  500. package/dist/meeting/effectsState.js.map +0 -1
  501. package/dist/multistream/multistreamMedia.js +0 -116
  502. package/dist/multistream/multistreamMedia.js.map +0 -1
  503. package/src/index.js +0 -15
  504. package/src/media/internal-media-core-wrapper.ts +0 -9
  505. package/src/meeting/effectsState.ts +0 -211
  506. package/src/multistream/multistreamMedia.ts +0 -92
  507. package/test/unit/spec/meeting/effectsState.js +0 -291
@@ -8,31 +8,21 @@ import uuid from 'uuid';
8
8
  import window from 'global/window';
9
9
  import anonymize from 'ip-anonymize';
10
10
 
11
+ import {getOSNameInternal} from '@webex/internal-plugin-metrics';
11
12
  import LoggerProxy from '../common/logs/logger-proxy';
12
13
  import {MEETING_ERRORS} from '../constants';
13
14
  import BrowserDetection from '../common/browser-detection';
14
15
 
15
16
  import {
16
- error, eventType, errorCodes as ERROR_CODE, OS_NAME, UNKNOWN, CLIENT_NAME,
17
- mediaType
17
+ error,
18
+ eventType,
19
+ errorCodes as ERROR_CODE,
20
+ UNKNOWN,
21
+ CLIENT_NAME,
22
+ mediaType,
18
23
  } from './config';
19
24
 
20
- const OSMap = {
21
- // @ts-ignore
22
- 'Chrome OS': OS_NAME.chrome,
23
- macOS: OS_NAME.MAC,
24
- Windows: OS_NAME.WINDOWS,
25
- iOS: OS_NAME.IOS,
26
- Android: OS_NAME.ANDROID,
27
- Linux: OS_NAME.LINUX
28
- };
29
-
30
- const {
31
- getOSName,
32
- getOSVersion,
33
- getBrowserName,
34
- getBrowserVersion
35
- } = BrowserDetection();
25
+ const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
36
26
 
37
27
  // Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses
38
28
  // For reference : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
@@ -85,33 +75,33 @@ class Metrics {
85
75
  webex: any;
86
76
 
87
77
  /**
88
- * Create Metrics Object
89
- * @constructor
90
- * @public
91
- * @memberof Meetings
92
- */
78
+ * Create Metrics Object
79
+ * @constructor
80
+ * @public
81
+ * @memberof Meetings
82
+ */
93
83
  constructor() {
94
84
  if (!Metrics.instance) {
95
- /**
96
- * @instance
97
- * @type {Array}
98
- * @private
99
- * @memberof Metrics
100
- */
85
+ /**
86
+ * @instance
87
+ * @type {Array}
88
+ * @private
89
+ * @memberof Metrics
90
+ */
101
91
  this._events = [];
102
92
  /**
103
- * @instance
104
- * @type {MeetingCollection}
105
- * @private
106
- * @memberof Metrics
107
- */
93
+ * @instance
94
+ * @type {MeetingCollection}
95
+ * @private
96
+ * @memberof Metrics
97
+ */
108
98
  this.meetingCollection = null;
109
99
  /**
110
- * @instance
111
- * @type {MeetingCollection}
112
- * @private
113
- * @memberof Metrics
114
- */
100
+ * @instance
101
+ * @type {MeetingCollection}
102
+ * @private
103
+ * @memberof Metrics
104
+ */
115
105
  this.keys = Object.values(eventType);
116
106
  /**
117
107
  * @instance
@@ -122,6 +112,7 @@ class Metrics {
122
112
  Metrics.instance = this;
123
113
  }
124
114
 
115
+ // eslint-disable-next-line no-constructor-return
125
116
  return Metrics.instance;
126
117
  }
127
118
 
@@ -147,12 +138,14 @@ class Metrics {
147
138
  * @param {object} options.event
148
139
  * @returns {object} null
149
140
  */
150
- postEvent(options: { meeting?: any; meetingId?: string; data?: object; event?: any } | any) {
141
+ postEvent(options: {meeting?: any; meetingId?: string; data?: object; event?: any} | any) {
151
142
  const {meetingId, data = {}, event} = options;
152
143
  let {meeting} = options;
153
144
 
154
145
  if (this.keys.indexOf(event) === -1) {
155
- LoggerProxy.logger.error(`Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`);
146
+ LoggerProxy.logger.error(
147
+ `Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`
148
+ );
156
149
  }
157
150
 
158
151
  if (!meeting && meetingId) {
@@ -169,25 +162,25 @@ class Metrics {
169
162
  if (event === eventType.MEDIA_QUALITY) {
170
163
  data.event = event;
171
164
  meeting.sendMediaQualityAnalyzerMetrics(data);
172
- }
173
- else {
165
+ } else {
174
166
  meeting.callEvents.push(event);
175
167
  data.event = event;
176
168
  meeting.sendCallAnalyzerMetrics(data);
177
169
  }
178
- }
179
-
180
- else {
181
- LoggerProxy.logger.info(`Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`);
170
+ } else {
171
+ LoggerProxy.logger.info(
172
+ `Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`
173
+ );
182
174
  }
183
175
  }
184
176
 
185
177
  /**
186
178
  * Docs for Call analyzer metrics
187
- * https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki
188
- * https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml
189
- */
179
+ * https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki
180
+ * https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml
181
+ */
190
182
 
183
+ // eslint-disable-next-line @typescript-eslint/no-shadow
191
184
  initPayload(eventType, identifiers, options) {
192
185
  const payload: any = {
193
186
  eventId: uuid.v4(),
@@ -202,21 +195,21 @@ class Metrics {
202
195
  localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
203
196
  osVersion: getOSVersion() || 'unknown',
204
197
  subClientType: options.subClientType,
205
- os: this.getOsName(),
198
+ os: getOSNameInternal(),
206
199
  browser: getBrowserName(),
207
- browserVersion: getBrowserVersion()
208
- }
200
+ browserVersion: getBrowserVersion(),
201
+ },
209
202
  },
210
203
  originTime: {
211
- triggered: new Date().toISOString()
204
+ triggered: new Date().toISOString(),
212
205
  },
213
206
  senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,
214
207
  event: {
215
208
  name: eventType,
216
209
  canProceed: true,
217
210
  identifiers,
218
- eventData: {webClientDomain: window.location.hostname}
219
- }
211
+ eventData: {webClientDomain: window.location.hostname},
212
+ },
220
213
  };
221
214
 
222
215
  // TODO: more options should be checked and some of them should be mandatory in certain conditions
@@ -248,22 +241,16 @@ class Metrics {
248
241
  if (options.isRoapCallEnabled) {
249
242
  payload.event.isRoapCallEnabled = options.isRoapCallEnabled;
250
243
  }
244
+ ['breakoutMoveId', 'breakoutSessionId', 'breakoutGroupId'].forEach((item) => {
245
+ if (options[item]) {
246
+ payload.event.identifiers[item] = options[item];
247
+ }
248
+ });
251
249
  }
252
250
 
253
251
  return payload;
254
252
  }
255
253
 
256
- /**
257
- * returns metrics friendly OS versions
258
- * @param {String} osName Os name
259
- * @returns {String}
260
- * @private
261
- * @memberof Metrics
262
- */
263
- private getOsName() {
264
- return OSMap[getOSName()] ?? OS_NAME.OTHERS;
265
- }
266
-
267
254
  /**
268
255
  * get the payload specific for a media quality event through call analyzer
269
256
  * @param {String} eventType the event name
@@ -279,16 +266,19 @@ class Metrics {
279
266
  * @memberof Metrics
280
267
  */
281
268
  public initMediaPayload(
269
+ // eslint-disable-next-line @typescript-eslint/no-shadow
282
270
  eventType: string,
283
271
  identifiers: {
284
272
  correlationId: string;
285
273
  locusUrl: string;
286
274
  locusId: string;
287
275
  },
288
- options: {
289
- intervalData: object;
290
- clientType: string;
291
- } | any = {}
276
+ options:
277
+ | {
278
+ intervalData: object;
279
+ clientType: string;
280
+ }
281
+ | any = {}
292
282
  ) {
293
283
  const {audioSetupDelay, videoSetupDelay, joinTimes} = options;
294
284
 
@@ -305,15 +295,15 @@ class Metrics {
305
295
  clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted
306
296
  clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
307
297
  localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
308
- os: this.getOsName(),
298
+ os: getOSNameInternal(),
309
299
  osVersion: getOSVersion() || UNKNOWN,
310
300
  subClientType: options.subClientType,
311
301
  browser: getBrowserName(),
312
- browserVersion: getBrowserVersion()
313
- }
302
+ browserVersion: getBrowserVersion(),
303
+ },
314
304
  },
315
305
  originTime: {
316
- triggered: new Date().toISOString()
306
+ triggered: new Date().toISOString(),
317
307
  },
318
308
  senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,
319
309
  event: {
@@ -323,16 +313,16 @@ class Metrics {
323
313
  intervals: [options.intervalData],
324
314
  joinTimes,
325
315
  eventData: {
326
- webClientDomain: window.location.hostname
316
+ webClientDomain: window.location.hostname,
327
317
  },
328
318
  sourceMetadata: {
329
319
  applicationSoftwareType: CLIENT_NAME,
330
320
  applicationSoftwareVersion: this.webex.version,
331
321
  mediaEngineSoftwareType: getBrowserName() || 'browser',
332
322
  mediaEngineSoftwareVersion: getOSVersion() || UNKNOWN,
333
- startTime: new Date().toISOString()
334
- }
335
- }
323
+ startTime: new Date().toISOString(),
324
+ },
325
+ },
336
326
  };
337
327
 
338
328
  return payload;
@@ -353,8 +343,7 @@ class Metrics {
353
343
 
354
344
  if (err && err.statusCode && err.statusCode >= 500) {
355
345
  errorCode = 1003;
356
- }
357
- else if (err && err.body && err.body.errorCode) {
346
+ } else if (err && err.body && err.body.errorCode) {
358
347
  // locus error codes: https://sqbu-github.cisco.com/WebExSquared/locus/blob/master/server/src/main/resources/locus-error-codes.properties
359
348
  switch (ERROR_CODE[err.body.errorCode]) {
360
349
  case MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:
@@ -453,17 +442,13 @@ class Metrics {
453
442
  default:
454
443
  errorCode = 4008;
455
444
  }
456
- }
457
- else {
445
+ } else {
458
446
  errorCode = 4008;
459
447
  }
460
448
 
461
- return this.generateErrorPayload(
462
- errorCode, showToUser, error.name.LOCUS_RESPONSE, err
463
- );
449
+ return this.generateErrorPayload(errorCode, showToUser, error.name.LOCUS_RESPONSE, err);
464
450
  }
465
451
 
466
-
467
452
  generateErrorPayload(errorCode, shownToUser, name, err) {
468
453
  if (error.errors[errorCode]) {
469
454
  const errorPayload: any = {
@@ -472,11 +457,11 @@ class Metrics {
472
457
  errorDescription: error.errors[errorCode][0],
473
458
  errorCode,
474
459
  fatal: !includes(error.notFatalErrorList, errorCode),
475
- name: name || error.name.OTHER
460
+ name: name || error.name.OTHER,
476
461
  };
477
462
 
478
463
  if (err && err.body) {
479
- errorPayload.errorData = err.body;
464
+ errorPayload.errorData = {error: err.body};
480
465
  }
481
466
 
482
467
  if (err && err.statusCode) {
@@ -499,8 +484,14 @@ class Metrics {
499
484
  let browserInfo;
500
485
  const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);
501
486
 
502
- if (['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1) {
503
- browserInfo = util.format('browser=%s', `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`);
487
+ if (
488
+ ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !==
489
+ -1
490
+ ) {
491
+ browserInfo = util.format(
492
+ 'browser=%s',
493
+ `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`
494
+ );
504
495
  }
505
496
  const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);
506
497
 
@@ -508,12 +499,18 @@ class Metrics {
508
499
  userAgentOption = `(${browserInfo}`;
509
500
  }
510
501
  if (osInfo) {
511
- userAgentOption = userAgentOption ? `${userAgentOption}; ${clientInfo}; ${osInfo}` : `${clientInfo}; (${osInfo}`;
502
+ userAgentOption = userAgentOption
503
+ ? `${userAgentOption}; ${clientInfo}; ${osInfo}`
504
+ : `${clientInfo}; (${osInfo}`;
512
505
  }
513
506
  if (userAgentOption) {
514
507
  userAgentOption += ')';
515
508
 
516
- return util.format('webex-js-sdk/%s %s', `${process.env.NODE_ENV}-${this.webex.version}`, userAgentOption);
509
+ return util.format(
510
+ 'webex-js-sdk/%s %s',
511
+ `${process.env.NODE_ENV}-${this.webex.version}`,
512
+ userAgentOption
513
+ );
517
514
  }
518
515
 
519
516
  return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${this.webex.version}`);
@@ -538,7 +535,7 @@ class Metrics {
538
535
  this.webex.internal.metrics.submitClientMetrics(metricName, {
539
536
  type: this.webex.config.metrics.type,
540
537
  fields: metricFields,
541
- tags: metricTags
538
+ tags: metricTags,
542
539
  });
543
540
  }
544
541
  }
@@ -1,9 +1,20 @@
1
1
  /* eslint-disable require-jsdoc */
2
- import {MediaConnection as MC} from '@webex/internal-media-core';
2
+ import {
3
+ MediaRequest as WcmeMediaRequest,
4
+ Policy,
5
+ ActiveSpeakerInfo,
6
+ ReceiverSelectedInfo,
7
+ CodecInfo as WcmeCodecInfo,
8
+ H264Codec,
9
+ getRecommendedMaxBitrateForFrameSize,
10
+ RecommendedOpusBitrates,
11
+ } from '@webex/internal-media-core';
12
+ import {cloneDeep, debounce, isEmpty} from 'lodash';
3
13
 
4
14
  import LoggerProxy from '../common/logs/logger-proxy';
5
15
 
6
- import {ReceiveSlot, ReceiveSlotId} from './receiveSlot';
16
+ import {ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';
17
+ import {getMaxFs} from './remoteMedia';
7
18
 
8
19
  export interface ActiveSpeakerPolicyInfo {
9
20
  policy: 'active-speaker';
@@ -35,6 +46,7 @@ export interface MediaRequest {
35
46
  policyInfo: PolicyInfo;
36
47
  receiveSlots: Array<ReceiveSlot>;
37
48
  codecInfo?: CodecInfo;
49
+ preferredMaxFs?: number;
38
50
  }
39
51
 
40
52
  export type MediaRequestId = string;
@@ -47,79 +59,206 @@ const CODEC_DEFAULTS = {
47
59
  },
48
60
  };
49
61
 
50
- type SendMediaRequestsCallback = (mediaRequests: MC.MediaRequest[]) => void;
62
+ const DEBOUNCED_SOURCE_UPDATE_TIME = 1000;
51
63
 
64
+ type DegradationPreferences = {
65
+ maxMacroblocksLimit: number;
66
+ };
67
+
68
+ type SendMediaRequestsCallback = (mediaRequests: WcmeMediaRequest[]) => void;
69
+ type Kind = 'audio' | 'video';
70
+
71
+ type Options = {
72
+ degradationPreferences: DegradationPreferences;
73
+ kind: Kind;
74
+ };
52
75
  export class MediaRequestManager {
53
76
  private sendMediaRequestsCallback: SendMediaRequestsCallback;
54
77
 
55
- private counter;
78
+ private kind: Kind;
79
+
80
+ private counter: number;
56
81
 
57
82
  private clientRequests: {[key: MediaRequestId]: MediaRequest};
58
83
 
59
- private slotsActiveInLastMediaRequest: {[key: ReceiveSlotId]: ReceiveSlot};
84
+ private degradationPreferences: DegradationPreferences;
60
85
 
61
- constructor(sendMediaRequestsCallback: SendMediaRequestsCallback) {
86
+ private sourceUpdateListener: () => void;
87
+
88
+ private debouncedSourceUpdateListener: () => void;
89
+
90
+ private previousWCMEMediaRequests: Array<WcmeMediaRequest> = [];
91
+
92
+ constructor(sendMediaRequestsCallback: SendMediaRequestsCallback, options: Options) {
62
93
  this.sendMediaRequestsCallback = sendMediaRequestsCallback;
63
94
  this.counter = 0;
64
95
  this.clientRequests = {};
65
- this.slotsActiveInLastMediaRequest = {};
96
+ this.degradationPreferences = options.degradationPreferences;
97
+ this.kind = options.kind;
98
+ this.sourceUpdateListener = this.commit.bind(this);
99
+ this.debouncedSourceUpdateListener = debounce(
100
+ this.sourceUpdateListener,
101
+ DEBOUNCED_SOURCE_UPDATE_TIME
102
+ );
66
103
  }
67
104
 
68
- private resetInactiveReceiveSlots() {
69
- const activeSlots: {[key: ReceiveSlotId]: ReceiveSlot} = {};
70
-
71
- // create a map of all currently used slot ids
72
- Object.values(this.clientRequests).forEach((request) =>
73
- request.receiveSlots.forEach((slot) => {
74
- activeSlots[slot.id] = slot;
75
- })
76
- );
105
+ public setDegradationPreferences(degradationPreferences: DegradationPreferences) {
106
+ this.degradationPreferences = degradationPreferences;
107
+ this.sendRequests(); // re-send requests after preferences are set
108
+ }
77
109
 
78
- // when we stop using some receive slots and they are not included in the new media request,
79
- // we will never get a 'no source' notification for them, so we reset their state,
80
- // so that the client doesn't try to display their video anymore
81
- for (const [slotId, slot] of Object.entries(this.slotsActiveInLastMediaRequest)) {
82
- if (!(slotId in activeSlots)) {
83
- LoggerProxy.logger.info(
84
- `multistream:mediaRequestManager --> resetting sourceState to "no source" for slot ${slot.id}`
110
+ private getDegradedClientRequests() {
111
+ const clientRequests = cloneDeep(this.clientRequests);
112
+ const maxFsLimits = [
113
+ getMaxFs('best'),
114
+ getMaxFs('large'),
115
+ getMaxFs('medium'),
116
+ getMaxFs('small'),
117
+ getMaxFs('very small'),
118
+ getMaxFs('thumbnail'),
119
+ ];
120
+
121
+ // reduce max-fs until total macroblocks is below limit
122
+ for (let i = 0; i < maxFsLimits.length; i += 1) {
123
+ let totalMacroblocksRequested = 0;
124
+ Object.entries(clientRequests).forEach(([id, mr]) => {
125
+ if (mr.codecInfo) {
126
+ mr.codecInfo.maxFs = Math.min(
127
+ mr.preferredMaxFs || CODEC_DEFAULTS.h264.maxFs,
128
+ mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,
129
+ maxFsLimits[i]
130
+ );
131
+ // we only consider sources with "live" state
132
+ const slotsWithLiveSource = this.clientRequests[id].receiveSlots.filter(
133
+ (rs) => rs.sourceState === 'live'
134
+ );
135
+ totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;
136
+ }
137
+ });
138
+ if (totalMacroblocksRequested <= this.degradationPreferences.maxMacroblocksLimit) {
139
+ if (i !== 0) {
140
+ LoggerProxy.logger.warn(
141
+ `multistream:mediaRequestManager --> too many streams with high max-fs, frame size will be limited to ${maxFsLimits[i]}`
142
+ );
143
+ }
144
+ break;
145
+ } else if (i === maxFsLimits.length - 1) {
146
+ LoggerProxy.logger.warn(
147
+ `multistream:mediaRequestManager --> even with frame size limited to ${maxFsLimits[i]} you are still requesting too many streams, consider reducing the number of requests`
85
148
  );
86
- slot.resetSourceState();
87
149
  }
88
150
  }
89
151
 
90
- this.slotsActiveInLastMediaRequest = activeSlots;
152
+ return clientRequests;
153
+ }
154
+
155
+ /**
156
+ * Returns true if two media requests are the same, false otherwise.
157
+ *
158
+ * @param {WcmeMediaRequest} mediaRequestA - Media request A for comparison.
159
+ * @param {WcmeMediaRequest} mediaRequestB - Media request B for comparison.
160
+ * @returns {boolean} - Whether they are equal.
161
+ */
162
+ // eslint-disable-next-line class-methods-use-this
163
+ public isEqual(mediaRequestA: WcmeMediaRequest, mediaRequestB: WcmeMediaRequest) {
164
+ return (
165
+ JSON.stringify(mediaRequestA._toJmpScrRequest()) ===
166
+ JSON.stringify(mediaRequestB._toJmpScrRequest())
167
+ );
168
+ }
169
+
170
+ /**
171
+ * Compares new media requests to previous ones and determines
172
+ * if they are the same.
173
+ *
174
+ * @param {WcmeMediaRequest[]} newRequests - Array with new requests.
175
+ * @returns {boolean} - True if they are equal, false otherwise.
176
+ */
177
+ private checkIsNewRequestsEqualToPrev(newRequests: WcmeMediaRequest[]) {
178
+ return (
179
+ !isEmpty(this.previousWCMEMediaRequests) &&
180
+ this.previousWCMEMediaRequests.length === newRequests.length &&
181
+ this.previousWCMEMediaRequests.every((req, idx) => this.isEqual(req, newRequests[idx]))
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Returns the maxPayloadBitsPerSecond per Stream
187
+ *
188
+ * If MediaRequestManager kind is "audio", a constant bitrate will be returned.
189
+ * If MediaRequestManager kind is "video", the bitrate will be calculated based
190
+ * on maxFs (default h264 maxFs as fallback if maxFs is not defined)
191
+ *
192
+ * @param {MediaRequest} mediaRequest - mediaRequest to take data from
193
+ * @returns {number} maxPayloadBitsPerSecond
194
+ */
195
+ private getMaxPayloadBitsPerSecond(mediaRequest: MediaRequest): number {
196
+ if (this.kind === 'audio') {
197
+ // return mono_music bitrate default if the kind of mediarequest manager is audio:
198
+ return RecommendedOpusBitrates.FB_MONO_MUSIC;
199
+ }
200
+
201
+ return getRecommendedMaxBitrateForFrameSize(
202
+ mediaRequest.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs
203
+ );
204
+ }
205
+
206
+ /**
207
+ * Returns the max Macro Blocks per second (maxMbps) per H264 Stream
208
+ *
209
+ * The maxMbps will be calculated based on maxFs and maxFps
210
+ * (default h264 maxFps as fallback if maxFps is not defined)
211
+ *
212
+ * @param {MediaRequest} mediaRequest - mediaRequest to take data from
213
+ * @returns {number} maxMbps
214
+ */
215
+ // eslint-disable-next-line class-methods-use-this
216
+ private getH264MaxMbps(mediaRequest: MediaRequest): number {
217
+ // fallback for maxFps (not needed for maxFs, since there is a fallback already in getDegradedClientRequests)
218
+ const maxFps = mediaRequest.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps;
219
+
220
+ // divided by 100 since maxFps is 3000 (for 30 frames per seconds)
221
+ return (mediaRequest.codecInfo.maxFs * maxFps) / 100;
222
+ }
223
+
224
+ /**
225
+ * Clears the previous media requests.
226
+ *
227
+ * @returns {void}
228
+ */
229
+ public clearPreviousRequests(): void {
230
+ this.previousWCMEMediaRequests = [];
91
231
  }
92
232
 
93
233
  private sendRequests() {
94
- const wcmeMediaRequests: MC.MediaRequest[] = [];
234
+ const wcmeMediaRequests: WcmeMediaRequest[] = [];
95
235
 
96
- // todo: check how many streams we're asking for and what resolution and introduce some limits (spark-377701)
97
- const maxPayloadBitsPerSecond = 10 * 1000 * 1000;
236
+ const clientRequests = this.getDegradedClientRequests();
98
237
 
99
238
  // map all the client media requests to wcme media requests
100
- Object.values(this.clientRequests).forEach((mr) => {
239
+ Object.values(clientRequests).forEach((mr) => {
101
240
  wcmeMediaRequests.push(
102
- new MC.MediaRequest(
241
+ new WcmeMediaRequest(
103
242
  mr.policyInfo.policy === 'active-speaker'
104
- ? MC.Policy.ActiveSpeaker
105
- : MC.Policy.ReceiverSelected,
243
+ ? Policy.ActiveSpeaker
244
+ : Policy.ReceiverSelected,
106
245
  mr.policyInfo.policy === 'active-speaker'
107
- ? new MC.ActiveSpeakerInfo(
246
+ ? new ActiveSpeakerInfo(
108
247
  mr.policyInfo.priority,
109
248
  mr.policyInfo.crossPriorityDuplication,
110
249
  mr.policyInfo.crossPolicyDuplication,
111
250
  mr.policyInfo.preferLiveVideo
112
251
  )
113
- : new MC.ReceiverSelectedInfo(mr.policyInfo.csi),
252
+ : new ReceiverSelectedInfo(mr.policyInfo.csi),
114
253
  mr.receiveSlots.map((receiveSlot) => receiveSlot.wcmeReceiveSlot),
115
- maxPayloadBitsPerSecond,
254
+ this.getMaxPayloadBitsPerSecond(mr),
116
255
  mr.codecInfo && [
117
- new MC.CodecInfo(
256
+ new WcmeCodecInfo(
118
257
  0x80,
119
- new MC.H264Codec(
120
- mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,
258
+ new H264Codec(
259
+ mr.codecInfo.maxFs,
121
260
  mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps,
122
- mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps,
261
+ this.getH264MaxMbps(mr),
123
262
  mr.codecInfo.maxWidth,
124
263
  mr.codecInfo.maxHeight
125
264
  )
@@ -129,9 +268,17 @@ export class MediaRequestManager {
129
268
  );
130
269
  });
131
270
 
132
- this.sendMediaRequestsCallback(wcmeMediaRequests);
133
-
134
- this.resetInactiveReceiveSlots();
271
+ //! IMPORTANT: this is only a temporary fix. This will soon be done in the jmp layer (@webex/json-multistream)
272
+ // https://jira-eng-gpk2.cisco.com/jira/browse/WEBEX-326713
273
+ if (!this.checkIsNewRequestsEqualToPrev(wcmeMediaRequests)) {
274
+ this.sendMediaRequestsCallback(wcmeMediaRequests);
275
+ this.previousWCMEMediaRequests = wcmeMediaRequests;
276
+ LoggerProxy.logger.info(`multistream:sendRequests --> media requests sent. `);
277
+ } else {
278
+ LoggerProxy.logger.info(
279
+ `multistream:sendRequests --> detected duplicate WCME requests, skipping them... `
280
+ );
281
+ }
135
282
  }
136
283
 
137
284
  public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {
@@ -140,6 +287,14 @@ export class MediaRequestManager {
140
287
 
141
288
  this.clientRequests[newId] = mediaRequest;
142
289
 
290
+ mediaRequest.receiveSlots.forEach((rs) => {
291
+ rs.on(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);
292
+ rs.on(ReceiveSlotEvents.MaxFsUpdate, ({maxFs}) => {
293
+ mediaRequest.preferredMaxFs = maxFs;
294
+ this.debouncedSourceUpdateListener();
295
+ });
296
+ });
297
+
143
298
  if (commit) {
144
299
  this.commit();
145
300
  }
@@ -148,6 +303,10 @@ export class MediaRequestManager {
148
303
  }
149
304
 
150
305
  public cancelRequest(requestId: MediaRequestId, commit = true) {
306
+ this.clientRequests[requestId]?.receiveSlots.forEach((rs) => {
307
+ rs.off(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);
308
+ });
309
+
151
310
  delete this.clientRequests[requestId];
152
311
 
153
312
  if (commit) {
@@ -161,6 +320,5 @@ export class MediaRequestManager {
161
320
 
162
321
  public reset() {
163
322
  this.clientRequests = {};
164
- this.slotsActiveInLastMediaRequest = {};
165
323
  }
166
324
  }