@webex/plugin-meetings 3.0.0-beta.39 → 3.0.0-beta.391

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 (393) hide show
  1. package/README.md +58 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/events.js +45 -0
  11. package/dist/breakouts/events.js.map +1 -0
  12. package/dist/breakouts/index.js +671 -81
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +45 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/errors/no-meeting-info.js +51 -0
  17. package/dist/common/errors/no-meeting-info.js.map +1 -0
  18. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  19. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +48 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/logs/request.js +5 -1
  25. package/dist/common/logs/request.js.map +1 -1
  26. package/dist/common/queue.js +24 -9
  27. package/dist/common/queue.js.map +1 -1
  28. package/dist/config.js +5 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +242 -33
  31. package/dist/constants.js.map +1 -1
  32. package/dist/controls-options-manager/enums.js +14 -2
  33. package/dist/controls-options-manager/enums.js.map +1 -1
  34. package/dist/controls-options-manager/index.js +109 -15
  35. package/dist/controls-options-manager/index.js.map +1 -1
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +309 -18
  39. package/dist/controls-options-manager/util.js.map +1 -1
  40. package/dist/index.js +110 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/interceptors/index.js +15 -0
  43. package/dist/interceptors/index.js.map +1 -0
  44. package/dist/interceptors/locusRetry.js +93 -0
  45. package/dist/interceptors/locusRetry.js.map +1 -0
  46. package/dist/interpretation/collection.js +23 -0
  47. package/dist/interpretation/collection.js.map +1 -0
  48. package/dist/interpretation/index.js +380 -0
  49. package/dist/interpretation/index.js.map +1 -0
  50. package/dist/interpretation/siLanguage.js +25 -0
  51. package/dist/interpretation/siLanguage.js.map +1 -0
  52. package/dist/locus-info/controlsUtils.js +91 -2
  53. package/dist/locus-info/controlsUtils.js.map +1 -1
  54. package/dist/locus-info/index.js +386 -62
  55. package/dist/locus-info/index.js.map +1 -1
  56. package/dist/locus-info/infoUtils.js +7 -1
  57. package/dist/locus-info/infoUtils.js.map +1 -1
  58. package/dist/locus-info/mediaSharesUtils.js +71 -1
  59. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  60. package/dist/locus-info/parser.js +249 -72
  61. package/dist/locus-info/parser.js.map +1 -1
  62. package/dist/locus-info/selfUtils.js +89 -14
  63. package/dist/locus-info/selfUtils.js.map +1 -1
  64. package/dist/media/index.js +65 -102
  65. package/dist/media/index.js.map +1 -1
  66. package/dist/media/properties.js +73 -124
  67. package/dist/media/properties.js.map +1 -1
  68. package/dist/mediaQualityMetrics/config.js +135 -330
  69. package/dist/mediaQualityMetrics/config.js.map +1 -1
  70. package/dist/meeting/in-meeting-actions.js +86 -2
  71. package/dist/meeting/in-meeting-actions.js.map +1 -1
  72. package/dist/meeting/index.js +4075 -2827
  73. package/dist/meeting/index.js.map +1 -1
  74. package/dist/meeting/locusMediaRequest.js +292 -0
  75. package/dist/meeting/locusMediaRequest.js.map +1 -0
  76. package/dist/meeting/muteState.js +224 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +177 -152
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +672 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting-info/index.js +73 -7
  83. package/dist/meeting-info/index.js.map +1 -1
  84. package/dist/meeting-info/meeting-info-v2.js +192 -51
  85. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  86. package/dist/meeting-info/util.js +1 -1
  87. package/dist/meeting-info/util.js.map +1 -1
  88. package/dist/meeting-info/utilv2.js +36 -36
  89. package/dist/meeting-info/utilv2.js.map +1 -1
  90. package/dist/meetings/collection.js +39 -0
  91. package/dist/meetings/collection.js.map +1 -1
  92. package/dist/meetings/index.js +484 -119
  93. package/dist/meetings/index.js.map +1 -1
  94. package/dist/meetings/meetings.types.js +7 -0
  95. package/dist/meetings/meetings.types.js.map +1 -0
  96. package/dist/meetings/request.js +2 -0
  97. package/dist/meetings/request.js.map +1 -1
  98. package/dist/meetings/util.js +73 -7
  99. package/dist/meetings/util.js.map +1 -1
  100. package/dist/member/index.js +58 -0
  101. package/dist/member/index.js.map +1 -1
  102. package/dist/member/types.js +25 -0
  103. package/dist/member/types.js.map +1 -0
  104. package/dist/member/util.js +132 -25
  105. package/dist/member/util.js.map +1 -1
  106. package/dist/members/collection.js +10 -0
  107. package/dist/members/collection.js.map +1 -1
  108. package/dist/members/index.js +102 -6
  109. package/dist/members/index.js.map +1 -1
  110. package/dist/members/request.js +106 -38
  111. package/dist/members/request.js.map +1 -1
  112. package/dist/members/types.js +15 -0
  113. package/dist/members/types.js.map +1 -0
  114. package/dist/members/util.js +326 -232
  115. package/dist/members/util.js.map +1 -1
  116. package/dist/metrics/constants.js +18 -1
  117. package/dist/metrics/constants.js.map +1 -1
  118. package/dist/metrics/index.js +1 -446
  119. package/dist/metrics/index.js.map +1 -1
  120. package/dist/multistream/mediaRequestManager.js +223 -32
  121. package/dist/multistream/mediaRequestManager.js.map +1 -1
  122. package/dist/multistream/receiveSlot.js +10 -0
  123. package/dist/multistream/receiveSlot.js.map +1 -1
  124. package/dist/multistream/receiveSlotManager.js +39 -36
  125. package/dist/multistream/receiveSlotManager.js.map +1 -1
  126. package/dist/multistream/remoteMedia.js +3 -1
  127. package/dist/multistream/remoteMedia.js.map +1 -1
  128. package/dist/multistream/remoteMediaGroup.js +76 -5
  129. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  130. package/dist/multistream/remoteMediaManager.js +366 -104
  131. package/dist/multistream/remoteMediaManager.js.map +1 -1
  132. package/dist/multistream/sendSlotManager.js +255 -0
  133. package/dist/multistream/sendSlotManager.js.map +1 -0
  134. package/dist/reachability/clusterReachability.js +356 -0
  135. package/dist/reachability/clusterReachability.js.map +1 -0
  136. package/dist/reachability/index.js +263 -390
  137. package/dist/reachability/index.js.map +1 -1
  138. package/dist/reachability/request.js +6 -4
  139. package/dist/reachability/request.js.map +1 -1
  140. package/dist/reachability/util.js +29 -0
  141. package/dist/reachability/util.js.map +1 -0
  142. package/dist/reconnection-manager/index.js +266 -202
  143. package/dist/reconnection-manager/index.js.map +1 -1
  144. package/dist/recording-controller/index.js +21 -2
  145. package/dist/recording-controller/index.js.map +1 -1
  146. package/dist/recording-controller/util.js +9 -8
  147. package/dist/recording-controller/util.js.map +1 -1
  148. package/dist/roap/index.js +51 -28
  149. package/dist/roap/index.js.map +1 -1
  150. package/dist/roap/request.js +48 -64
  151. package/dist/roap/request.js.map +1 -1
  152. package/dist/roap/turnDiscovery.js +220 -70
  153. package/dist/roap/turnDiscovery.js.map +1 -1
  154. package/dist/rtcMetrics/constants.js +12 -0
  155. package/dist/rtcMetrics/constants.js.map +1 -0
  156. package/dist/rtcMetrics/index.js +179 -0
  157. package/dist/rtcMetrics/index.js.map +1 -0
  158. package/dist/statsAnalyzer/index.js +357 -295
  159. package/dist/statsAnalyzer/index.js.map +1 -1
  160. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  161. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  162. package/dist/types/annotation/annotation.types.d.ts +42 -0
  163. package/dist/types/annotation/constants.d.ts +31 -0
  164. package/dist/types/annotation/index.d.ts +117 -0
  165. package/dist/types/breakouts/events.d.ts +8 -0
  166. package/dist/types/breakouts/utils.d.ts +14 -0
  167. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  168. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  169. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  170. package/dist/types/common/logs/request.d.ts +2 -0
  171. package/dist/types/common/queue.d.ts +9 -7
  172. package/dist/types/config.d.ts +2 -7
  173. package/dist/types/constants.d.ts +203 -31
  174. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  175. package/dist/types/controls-options-manager/index.d.ts +17 -1
  176. package/dist/types/controls-options-manager/types.d.ts +43 -0
  177. package/dist/types/controls-options-manager/util.d.ts +1 -7
  178. package/dist/types/index.d.ts +6 -5
  179. package/dist/types/interceptors/index.d.ts +2 -0
  180. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  181. package/dist/types/interpretation/collection.d.ts +5 -0
  182. package/dist/types/interpretation/index.d.ts +5 -0
  183. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  184. package/dist/types/locus-info/index.d.ts +57 -4
  185. package/dist/types/locus-info/parser.d.ts +66 -6
  186. package/dist/types/media/index.d.ts +2 -0
  187. package/dist/types/media/properties.d.ts +34 -49
  188. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  189. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  190. package/dist/types/meeting/index.d.ts +567 -496
  191. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  192. package/dist/types/meeting/muteState.d.ts +93 -25
  193. package/dist/types/meeting/request.d.ts +64 -43
  194. package/dist/types/meeting/util.d.ts +117 -1
  195. package/dist/types/meeting-info/index.d.ts +13 -1
  196. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  197. package/dist/types/meetings/collection.d.ts +17 -0
  198. package/dist/types/meetings/index.d.ts +113 -21
  199. package/dist/types/meetings/meetings.types.d.ts +4 -0
  200. package/dist/types/member/index.d.ts +14 -0
  201. package/dist/types/member/types.d.ts +32 -0
  202. package/dist/types/members/collection.d.ts +5 -0
  203. package/dist/types/members/index.d.ts +35 -2
  204. package/dist/types/members/request.d.ts +73 -9
  205. package/dist/types/members/types.d.ts +25 -0
  206. package/dist/types/members/util.d.ts +214 -1
  207. package/dist/types/metrics/constants.d.ts +17 -0
  208. package/dist/types/metrics/index.d.ts +4 -111
  209. package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
  210. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  211. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  212. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  213. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  214. package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
  215. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  216. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  217. package/dist/types/reachability/index.d.ts +60 -95
  218. package/dist/types/reachability/request.d.ts +3 -1
  219. package/dist/types/reachability/util.d.ts +8 -0
  220. package/dist/types/reconnection-manager/index.d.ts +19 -0
  221. package/dist/types/recording-controller/index.d.ts +15 -1
  222. package/dist/types/recording-controller/util.d.ts +5 -4
  223. package/dist/types/roap/index.d.ts +2 -1
  224. package/dist/types/roap/request.d.ts +9 -8
  225. package/dist/types/roap/turnDiscovery.d.ts +39 -5
  226. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  227. package/dist/types/rtcMetrics/index.d.ts +61 -0
  228. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  229. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  230. package/dist/types/webinar/collection.d.ts +16 -0
  231. package/dist/types/webinar/index.d.ts +5 -0
  232. package/dist/webinar/collection.js +44 -0
  233. package/dist/webinar/collection.js.map +1 -0
  234. package/dist/webinar/index.js +69 -0
  235. package/dist/webinar/index.js.map +1 -0
  236. package/package.json +22 -19
  237. package/src/annotation/annotation.types.ts +50 -0
  238. package/src/annotation/constants.ts +36 -0
  239. package/src/annotation/index.ts +328 -0
  240. package/src/breakouts/README.md +35 -11
  241. package/src/breakouts/breakout.ts +67 -9
  242. package/src/breakouts/events.ts +56 -0
  243. package/src/breakouts/index.ts +558 -59
  244. package/src/breakouts/utils.ts +42 -0
  245. package/src/common/errors/no-meeting-info.ts +24 -0
  246. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  247. package/src/common/errors/webex-errors.ts +44 -2
  248. package/src/common/logs/logger-proxy.ts +1 -1
  249. package/src/common/logs/request.ts +5 -1
  250. package/src/common/queue.ts +22 -8
  251. package/src/config.ts +4 -9
  252. package/src/constants.ts +229 -21
  253. package/src/controls-options-manager/enums.ts +12 -0
  254. package/src/controls-options-manager/index.ts +116 -21
  255. package/src/controls-options-manager/types.ts +59 -0
  256. package/src/controls-options-manager/util.ts +294 -14
  257. package/src/index.ts +44 -0
  258. package/src/interceptors/index.ts +3 -0
  259. package/src/interceptors/locusRetry.ts +67 -0
  260. package/src/interpretation/README.md +60 -0
  261. package/src/interpretation/collection.ts +19 -0
  262. package/src/interpretation/index.ts +349 -0
  263. package/src/interpretation/siLanguage.ts +18 -0
  264. package/src/locus-info/controlsUtils.ts +108 -0
  265. package/src/locus-info/index.ts +417 -59
  266. package/src/locus-info/infoUtils.ts +10 -2
  267. package/src/locus-info/mediaSharesUtils.ts +80 -0
  268. package/src/locus-info/parser.ts +258 -47
  269. package/src/locus-info/selfUtils.ts +81 -5
  270. package/src/media/index.ts +100 -108
  271. package/src/media/properties.ts +88 -117
  272. package/src/mediaQualityMetrics/config.ts +103 -238
  273. package/src/meeting/in-meeting-actions.ts +171 -3
  274. package/src/meeting/index.ts +3411 -2435
  275. package/src/meeting/locusMediaRequest.ts +313 -0
  276. package/src/meeting/muteState.ts +223 -136
  277. package/src/meeting/request.ts +155 -120
  278. package/src/meeting/util.ts +685 -395
  279. package/src/meeting-info/index.ts +81 -8
  280. package/src/meeting-info/meeting-info-v2.ts +170 -14
  281. package/src/meeting-info/util.ts +1 -1
  282. package/src/meeting-info/utilv2.ts +23 -23
  283. package/src/meetings/collection.ts +33 -0
  284. package/src/meetings/index.ts +507 -127
  285. package/src/meetings/meetings.types.ts +12 -0
  286. package/src/meetings/request.ts +2 -0
  287. package/src/meetings/util.ts +81 -12
  288. package/src/member/index.ts +58 -0
  289. package/src/member/types.ts +38 -0
  290. package/src/member/util.ts +141 -25
  291. package/src/members/collection.ts +8 -0
  292. package/src/members/index.ts +134 -8
  293. package/src/members/request.ts +97 -17
  294. package/src/members/types.ts +29 -0
  295. package/src/members/util.ts +333 -240
  296. package/src/metrics/constants.ts +17 -0
  297. package/src/metrics/index.ts +1 -469
  298. package/src/multistream/mediaRequestManager.ts +271 -56
  299. package/src/multistream/receiveSlot.ts +11 -4
  300. package/src/multistream/receiveSlotManager.ts +34 -24
  301. package/src/multistream/remoteMedia.ts +5 -3
  302. package/src/multistream/remoteMediaGroup.ts +78 -0
  303. package/src/multistream/remoteMediaManager.ts +248 -44
  304. package/src/multistream/sendSlotManager.ts +199 -0
  305. package/src/reachability/clusterReachability.ts +320 -0
  306. package/src/reachability/index.ts +229 -346
  307. package/src/reachability/request.ts +8 -4
  308. package/src/reachability/util.ts +24 -0
  309. package/src/reconnection-manager/index.ts +128 -97
  310. package/src/recording-controller/index.ts +20 -3
  311. package/src/recording-controller/util.ts +26 -9
  312. package/src/roap/index.ts +52 -23
  313. package/src/roap/request.ts +48 -67
  314. package/src/roap/turnDiscovery.ts +147 -49
  315. package/src/rtcMetrics/constants.ts +3 -0
  316. package/src/rtcMetrics/index.ts +166 -0
  317. package/src/statsAnalyzer/index.ts +457 -416
  318. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  319. package/src/webinar/collection.ts +31 -0
  320. package/src/webinar/index.ts +62 -0
  321. package/test/integration/spec/converged-space-meetings.js +60 -3
  322. package/test/integration/spec/journey.js +320 -261
  323. package/test/integration/spec/space-meeting.js +76 -3
  324. package/test/unit/spec/annotation/index.ts +418 -0
  325. package/test/unit/spec/breakouts/breakout.ts +118 -28
  326. package/test/unit/spec/breakouts/events.ts +89 -0
  327. package/test/unit/spec/breakouts/index.ts +1349 -114
  328. package/test/unit/spec/breakouts/utils.js +52 -1
  329. package/test/unit/spec/common/queue.js +31 -2
  330. package/test/unit/spec/controls-options-manager/index.js +163 -0
  331. package/test/unit/spec/controls-options-manager/util.js +576 -60
  332. package/test/unit/spec/fixture/locus.js +1 -0
  333. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  334. package/test/unit/spec/interpretation/collection.ts +15 -0
  335. package/test/unit/spec/interpretation/index.ts +625 -0
  336. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  337. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  338. package/test/unit/spec/locus-info/index.js +1363 -37
  339. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  340. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  341. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  342. package/test/unit/spec/locus-info/parser.js +116 -35
  343. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  344. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  345. package/test/unit/spec/media/index.ts +173 -81
  346. package/test/unit/spec/media/properties.ts +2 -2
  347. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  348. package/test/unit/spec/meeting/index.js +6821 -2172
  349. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  350. package/test/unit/spec/meeting/muteState.js +402 -212
  351. package/test/unit/spec/meeting/request.js +473 -54
  352. package/test/unit/spec/meeting/utils.js +773 -67
  353. package/test/unit/spec/meeting-info/index.js +300 -0
  354. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  355. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  356. package/test/unit/spec/meetings/collection.js +26 -0
  357. package/test/unit/spec/meetings/index.js +1415 -213
  358. package/test/unit/spec/meetings/utils.js +229 -2
  359. package/test/unit/spec/member/index.js +61 -6
  360. package/test/unit/spec/member/util.js +510 -34
  361. package/test/unit/spec/members/index.js +432 -1
  362. package/test/unit/spec/members/request.js +206 -27
  363. package/test/unit/spec/members/utils.js +210 -0
  364. package/test/unit/spec/metrics/index.js +1 -50
  365. package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
  366. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  367. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  368. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  369. package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
  370. package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
  371. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  372. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  373. package/test/unit/spec/reachability/index.ts +551 -14
  374. package/test/unit/spec/reachability/request.js +3 -1
  375. package/test/unit/spec/reachability/util.ts +40 -0
  376. package/test/unit/spec/reconnection-manager/index.js +171 -11
  377. package/test/unit/spec/recording-controller/index.js +294 -218
  378. package/test/unit/spec/recording-controller/util.js +223 -96
  379. package/test/unit/spec/roap/index.ts +180 -83
  380. package/test/unit/spec/roap/request.ts +100 -62
  381. package/test/unit/spec/roap/turnDiscovery.ts +388 -96
  382. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  383. package/test/unit/spec/stats-analyzer/index.js +1252 -12
  384. package/test/unit/spec/webinar/collection.ts +13 -0
  385. package/test/unit/spec/webinar/index.ts +60 -0
  386. package/test/utils/integrationTestUtils.js +46 -0
  387. package/test/utils/testUtils.js +0 -57
  388. package/test/utils/webex-test-users.js +12 -4
  389. package/dist/metrics/config.js +0 -289
  390. package/dist/metrics/config.js.map +0 -1
  391. package/dist/types/metrics/config.d.ts +0 -169
  392. package/src/index.js +0 -18
  393. package/src/metrics/config.ts +0 -485
@@ -0,0 +1,199 @@
1
+ import {
2
+ SendSlot,
3
+ MediaType,
4
+ LocalStream,
5
+ MultistreamRoapMediaConnection,
6
+ } from '@webex/internal-media-core';
7
+
8
+ import {NamedMediaGroup} from '@webex/json-multistream';
9
+
10
+ export default class SendSlotManager {
11
+ private readonly slots: Map<MediaType, SendSlot> = new Map();
12
+ private readonly LoggerProxy: any;
13
+
14
+ constructor(LoggerProxy: any) {
15
+ this.LoggerProxy = LoggerProxy;
16
+ }
17
+
18
+ /**
19
+ * This method is used to create a sendSlot for the given mediaType and returns the created sendSlot
20
+ * @param {MultistreamRoapMediaConnection} mediaConnection MultistreamRoapMediaConnection for which a sendSlot needs to be created
21
+ * @param {MediaType} mediaType MediaType for which a sendSlot needs to be created (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
22
+ * @param {boolean} active This is optional boolean to set the active state of the sendSlot. Default is true
23
+ * @returns {SendSlot} slot The created sendSlot
24
+ */
25
+ public createSlot(
26
+ mediaConnection: MultistreamRoapMediaConnection,
27
+ mediaType: MediaType,
28
+ active = true
29
+ ): SendSlot {
30
+ if (this.slots.has(mediaType)) {
31
+ throw new Error(`Slot for ${mediaType} already exists`);
32
+ }
33
+
34
+ const slot: SendSlot = mediaConnection.createSendSlot(mediaType, active);
35
+
36
+ this.slots.set(mediaType, slot);
37
+
38
+ this.LoggerProxy.logger.info(
39
+ `SendSlotsManager->createSlot#Created slot for ${mediaType} with active ${active}`
40
+ );
41
+
42
+ return slot;
43
+ }
44
+
45
+ /**
46
+ * This method is used to retrieve the sendSlot for the given mediaType
47
+ * @param {MediaType} mediaType of which the slot needs to be retrieved
48
+ * @returns {SendSlot}
49
+ */
50
+ public getSlot(mediaType: MediaType): SendSlot {
51
+ const slot = this.slots.get(mediaType);
52
+
53
+ if (!slot) {
54
+ throw new Error(`Slot for ${mediaType} does not exist`);
55
+ }
56
+
57
+ return slot;
58
+ }
59
+
60
+ /**
61
+ * Allow users to specify 'namedMediaGroups' to indicate which named media group its audio should be sent to.
62
+ * @param {MediaType} mediaType MediaType of the sendSlot to which the audio stream needs to be send to the media group
63
+ * @param {[]}namedMediaGroups - Allow users to specify 'namedMediaGroups'.If the value of 'namedMediaGroups' is zero,
64
+ * named media group will be canceled and the audio stream will be sent to the floor.
65
+ * @returns {void}
66
+ */
67
+ public setNamedMediaGroups(mediaType: MediaType, namedMediaGroups: NamedMediaGroup[]) {
68
+ if (mediaType !== MediaType.AudioMain) {
69
+ throw new Error(
70
+ `sendSlotManager cannot set named media group which media type is ${mediaType}`
71
+ );
72
+ }
73
+
74
+ const slot = this.slots.get(mediaType);
75
+
76
+ if (!slot) {
77
+ throw new Error(`Slot for ${mediaType} does not exist`);
78
+ }
79
+
80
+ slot.setNamedMediaGroups(namedMediaGroups);
81
+
82
+ this.LoggerProxy.logger.info(
83
+ `SendSlotsManager->setNamedMediaGroups#set named media group ${namedMediaGroups}`
84
+ );
85
+ }
86
+
87
+ /**
88
+ * This method publishes the given stream to the sendSlot for the given mediaType
89
+ * @param {MediaType} mediaType MediaType of the sendSlot to which a stream needs to be published (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
90
+ * @param {LocalStream} stream LocalStream to be published
91
+ * @returns {Promise<void>}
92
+ */
93
+ public async publishStream(mediaType: MediaType, stream: LocalStream): Promise<void> {
94
+ const slot = this.slots.get(mediaType);
95
+
96
+ if (!slot) {
97
+ throw new Error(`Slot for ${mediaType} does not exist`);
98
+ }
99
+
100
+ await slot.publishStream(stream);
101
+
102
+ this.LoggerProxy.logger.info(
103
+ `SendSlotsManager->publishStream#Published stream for ${mediaType} and stream with label ${stream.label} and muted ${stream.muted}`
104
+ );
105
+ }
106
+
107
+ /**
108
+ * This method unpublishes the stream from the sendSlot of the given mediaType
109
+ * @param {MediaType} mediaType MediaType of the sendSlot from which a stream needs to be unpublished (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
110
+ * @returns {Promise<void>}
111
+ */
112
+ public async unpublishStream(mediaType: MediaType): Promise<void> {
113
+ const slot = this.slots.get(mediaType);
114
+
115
+ if (!slot) {
116
+ throw new Error(`Slot for ${mediaType} does not exist`);
117
+ }
118
+
119
+ await slot.unpublishStream();
120
+
121
+ this.LoggerProxy.logger.info(
122
+ `SendSlotsManager->unpublishStream#Unpublished stream for ${mediaType}`
123
+ );
124
+ }
125
+
126
+ /**
127
+ * This method is used to set the active state of the sendSlot for the given mediaType
128
+ * @param {MediaType} mediaType The MediaType of the sendSlot for which the active state needs to be set (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
129
+ * @param {boolean} active The boolean to set the active state of the sendSlot. Default is true
130
+ * @returns {void}
131
+ */
132
+ public setActive(mediaType: MediaType, active = true): void {
133
+ const slot = this.slots.get(mediaType);
134
+
135
+ if (!slot) {
136
+ throw new Error(`Slot for ${mediaType} does not exist`);
137
+ }
138
+
139
+ slot.active = active;
140
+
141
+ this.LoggerProxy.logger.info(
142
+ `SendSlotsManager->setActive#Set active for ${mediaType} to ${active}`
143
+ );
144
+ }
145
+
146
+ /**
147
+ * This method is used to set the codec parameters for the sendSlot of the given mediaType
148
+ * @param {MediaType} mediaType MediaType of the sendSlot for which the codec parameters needs to be set (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
149
+ * @param {Object} codecParameters
150
+ * @returns {Promise<void>}
151
+ */
152
+ public async setCodecParameters(
153
+ mediaType: MediaType,
154
+ codecParameters: {
155
+ [key: string]: string | undefined; // As per ts-sdp undefined is considered as a valid value to be used for codec parameters
156
+ }
157
+ ): Promise<void> {
158
+ // These codec parameter changes underneath are SDP value changes that are taken care by WCME automatically. So no need for any change in streams from the web sdk side
159
+ const slot = this.slots.get(mediaType);
160
+
161
+ if (!slot) {
162
+ throw new Error(`Slot for ${mediaType} does not exist`);
163
+ }
164
+
165
+ await slot.setCodecParameters(codecParameters);
166
+
167
+ this.LoggerProxy.logger.info(
168
+ `SendSlotsManager->setCodecParameters#Set codec parameters for ${mediaType} to ${codecParameters}`
169
+ );
170
+ }
171
+
172
+ /**
173
+ * This method is used to delete the codec parameters for the sendSlot of the given mediaType
174
+ * @param {MediaType} mediaType MediaType of the sendSlot for which the codec parameters needs to be deleted (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
175
+ * @param {Array<String>} parameters Array of keys of the codec parameters to be deleted
176
+ * @returns {Promise<void>}
177
+ */
178
+ public async deleteCodecParameters(mediaType: MediaType, parameters: string[]): Promise<void> {
179
+ const slot = this.slots.get(mediaType);
180
+
181
+ if (!slot) {
182
+ throw new Error(`Slot for ${mediaType} does not exist`);
183
+ }
184
+
185
+ await slot.deleteCodecParameters(parameters);
186
+
187
+ this.LoggerProxy.logger.info(
188
+ `SendSlotsManager->deleteCodecParameters#Deleted the following codec parameters -> ${parameters} for ${mediaType}`
189
+ );
190
+ }
191
+
192
+ /**
193
+ * This method is used to reset the SendSlotsManager by deleting all the sendSlots
194
+ * @returns {undefined}
195
+ */
196
+ public reset(): void {
197
+ this.slots.clear();
198
+ }
199
+ }
@@ -0,0 +1,320 @@
1
+ import {Defer} from '@webex/common';
2
+
3
+ import LoggerProxy from '../common/logs/logger-proxy';
4
+ import {ClusterNode} from './request';
5
+ import {convertStunUrlToTurn} from './util';
6
+
7
+ import {ICE_GATHERING_STATE, CONNECTION_STATE} from '../constants';
8
+
9
+ const DEFAULT_TIMEOUT = 3000;
10
+ const VIDEO_MESH_TIMEOUT = 1000;
11
+
12
+ // result for a specific transport protocol (like udp or tcp)
13
+ export type TransportResult = {
14
+ result: 'reachable' | 'unreachable' | 'untested';
15
+ latencyInMilliseconds?: number; // amount of time it took to get the first ICE candidate
16
+ clientMediaIPs?: string[];
17
+ };
18
+
19
+ // reachability result for a specific media cluster
20
+ export type ClusterReachabilityResult = {
21
+ udp: TransportResult;
22
+ tcp: TransportResult;
23
+ xtls: TransportResult;
24
+ };
25
+
26
+ /**
27
+ * A class that handles reachability checks for a single cluster.
28
+ */
29
+ export class ClusterReachability {
30
+ private numUdpUrls: number;
31
+ private numTcpUrls: number;
32
+ private result: ClusterReachabilityResult;
33
+ private pc?: RTCPeerConnection;
34
+ private defer: Defer; // this defer is resolved once reachability checks for this cluster are completed
35
+ private startTimestamp: number;
36
+ public readonly isVideoMesh: boolean;
37
+ public readonly name;
38
+
39
+ /**
40
+ * Constructor for ClusterReachability
41
+ * @param {string} name cluster name
42
+ * @param {ClusterNode} clusterInfo information about the media cluster
43
+ */
44
+ constructor(name: string, clusterInfo: ClusterNode) {
45
+ this.name = name;
46
+ this.isVideoMesh = clusterInfo.isVideoMesh;
47
+ this.numUdpUrls = clusterInfo.udp.length;
48
+ this.numTcpUrls = clusterInfo.tcp.length;
49
+
50
+ this.pc = this.createPeerConnection(clusterInfo);
51
+
52
+ this.defer = new Defer();
53
+ this.result = {
54
+ udp: {
55
+ result: 'untested',
56
+ },
57
+ tcp: {
58
+ result: 'untested',
59
+ },
60
+ xtls: {
61
+ result: 'untested',
62
+ },
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Gets total elapsed time, can be called only after start() is called
68
+ * @returns {Number} Milliseconds
69
+ */
70
+ private getElapsedTime() {
71
+ return Math.round(performance.now() - this.startTimestamp);
72
+ }
73
+
74
+ /**
75
+ * Generate peerConnection config settings
76
+ * @param {ClusterNode} cluster
77
+ * @returns {RTCConfiguration} peerConnectionConfig
78
+ */
79
+ private buildPeerConnectionConfig(cluster: ClusterNode): RTCConfiguration {
80
+ const udpIceServers = cluster.udp.map((url) => ({
81
+ username: '',
82
+ credential: '',
83
+ urls: [url],
84
+ }));
85
+
86
+ // STUN servers are contacted only using UDP, so in order to test TCP reachability
87
+ // we pretend that Linus is a TURN server, because we can explicitly say "transport=tcp" in TURN urls.
88
+ // We then check for relay candidates to know if TURN-TCP worked (see registerIceCandidateListener()).
89
+ const tcpIceServers = cluster.tcp.map((urlString: string) => {
90
+ return {
91
+ username: 'webexturnreachuser',
92
+ credential: 'webexturnreachpwd',
93
+ urls: [convertStunUrlToTurn(urlString, 'tcp')],
94
+ };
95
+ });
96
+
97
+ return {
98
+ iceServers: [...udpIceServers, ...tcpIceServers],
99
+ iceCandidatePoolSize: 0,
100
+ iceTransportPolicy: 'all',
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Creates an RTCPeerConnection
106
+ * @param {ClusterNode} clusterInfo information about the media cluster
107
+ * @returns {RTCPeerConnection} peerConnection
108
+ */
109
+ private createPeerConnection(clusterInfo: ClusterNode) {
110
+ try {
111
+ const config = this.buildPeerConnectionConfig(clusterInfo);
112
+
113
+ const peerConnection = new RTCPeerConnection(config);
114
+
115
+ return peerConnection;
116
+ } catch (peerConnectionError) {
117
+ LoggerProxy.logger.warn(
118
+ `Reachability:index#createPeerConnection --> Error creating peerConnection:`,
119
+ peerConnectionError
120
+ );
121
+
122
+ return undefined;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * @returns {ClusterReachabilityResult} reachability result for this cluster
128
+ */
129
+ getResult() {
130
+ return this.result;
131
+ }
132
+
133
+ /**
134
+ * Closes the peerConnection
135
+ *
136
+ * @returns {void}
137
+ */
138
+ private closePeerConnection() {
139
+ if (this.pc) {
140
+ this.pc.onicecandidate = null;
141
+ this.pc.onicegatheringstatechange = null;
142
+ this.pc.close();
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Resolves the defer, indicating that reachability checks for this cluster are completed
148
+ *
149
+ * @returns {void}
150
+ */
151
+ private finishReachabilityCheck() {
152
+ this.defer.resolve();
153
+ }
154
+
155
+ /**
156
+ * Adds public IP (client media IPs)
157
+ * @param {string} protocol
158
+ * @param {string} publicIP
159
+ * @returns {void}
160
+ */
161
+ private addPublicIP(protocol: 'udp' | 'tcp', publicIP?: string | null) {
162
+ const result = this.result[protocol];
163
+
164
+ if (publicIP) {
165
+ if (result.clientMediaIPs) {
166
+ if (!result.clientMediaIPs.includes(publicIP)) {
167
+ result.clientMediaIPs.push(publicIP);
168
+ }
169
+ } else {
170
+ result.clientMediaIPs = [publicIP];
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Registers a listener for the iceGatheringStateChange event
177
+ *
178
+ * @returns {void}
179
+ */
180
+ private registerIceGatheringStateChangeListener() {
181
+ this.pc.onicegatheringstatechange = () => {
182
+ const {COMPLETE} = ICE_GATHERING_STATE;
183
+
184
+ if (this.pc.iceConnectionState === COMPLETE) {
185
+ this.closePeerConnection();
186
+ this.finishReachabilityCheck();
187
+ }
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Checks if we have the results for all the protocols (UDP and TCP)
193
+ *
194
+ * @returns {boolean} true if we have all results, false otherwise
195
+ */
196
+ private haveWeGotAllResults(): boolean {
197
+ return ['udp', 'tcp'].every(
198
+ (protocol) =>
199
+ this.result[protocol].result === 'reachable' || this.result[protocol].result === 'untested'
200
+ );
201
+ }
202
+
203
+ /**
204
+ * Stores the latency in the result for the given protocol and marks it as reachable
205
+ *
206
+ * @param {string} protocol
207
+ * @param {number} latency
208
+ * @returns {void}
209
+ */
210
+ private storeLatencyResult(protocol: 'udp' | 'tcp', latency: number) {
211
+ const result = this.result[protocol];
212
+
213
+ if (result.latencyInMilliseconds === undefined) {
214
+ LoggerProxy.logger.log(
215
+ // @ts-ignore
216
+ `Reachability:index#storeLatencyResult --> Successfully reached ${this.name} over ${protocol}: ${latency}ms`
217
+ );
218
+ result.latencyInMilliseconds = latency;
219
+ result.result = 'reachable';
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Registers a listener for the icecandidate event
225
+ *
226
+ * @returns {void}
227
+ */
228
+ private registerIceCandidateListener() {
229
+ this.pc.onicecandidate = (e) => {
230
+ const CANDIDATE_TYPES = {
231
+ SERVER_REFLEXIVE: 'srflx',
232
+ RELAY: 'relay',
233
+ };
234
+
235
+ if (e.candidate) {
236
+ if (e.candidate.type === CANDIDATE_TYPES.SERVER_REFLEXIVE) {
237
+ this.storeLatencyResult('udp', this.getElapsedTime());
238
+ this.addPublicIP('udp', e.candidate.address);
239
+ }
240
+
241
+ if (e.candidate.type === CANDIDATE_TYPES.RELAY) {
242
+ this.storeLatencyResult('tcp', this.getElapsedTime());
243
+ // we don't add public IP for TCP, because in the case of relay candidates
244
+ // e.candidate.address is the TURN server address, not the client's public IP
245
+ }
246
+
247
+ if (this.haveWeGotAllResults()) {
248
+ this.closePeerConnection();
249
+ this.finishReachabilityCheck();
250
+ }
251
+ }
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Starts the process of doing UDP and TCP reachability checks on the media cluster.
257
+ * XTLS reachability checking is not supported.
258
+ *
259
+ * @returns {Promise}
260
+ */
261
+ async start(): Promise<ClusterReachabilityResult> {
262
+ if (!this.pc) {
263
+ LoggerProxy.logger.warn(
264
+ `Reachability:ClusterReachability#start --> Error: peerConnection is undefined`
265
+ );
266
+
267
+ return this.result;
268
+ }
269
+
270
+ // Initialize this.result as saying that nothing is reachable.
271
+ // It will get updated as we go along and successfully gather ICE candidates.
272
+ this.result.udp = {
273
+ result: this.numUdpUrls > 0 ? 'unreachable' : 'untested',
274
+ };
275
+ this.result.tcp = {
276
+ result: this.numTcpUrls > 0 ? 'unreachable' : 'untested',
277
+ };
278
+
279
+ try {
280
+ const offer = await this.pc.createOffer({offerToReceiveAudio: true});
281
+
282
+ this.startTimestamp = performance.now();
283
+
284
+ // not awaiting the next call on purpose, because we're not sending the offer anywhere and there won't be any answer
285
+ // we just need to make this call to trigger the ICE gathering process
286
+ this.pc.setLocalDescription(offer);
287
+
288
+ await this.gatherIceCandidates();
289
+ } catch (error) {
290
+ LoggerProxy.logger.warn(`Reachability:ClusterReachability#start --> Error: `, error);
291
+ }
292
+
293
+ return this.result;
294
+ }
295
+
296
+ /**
297
+ * Starts the process of gathering ICE candidates
298
+ *
299
+ * @returns {Promise} promise that's resolved once reachability checks for this cluster are completed or timeout is reached
300
+ */
301
+ private gatherIceCandidates() {
302
+ const timeout = this.isVideoMesh ? VIDEO_MESH_TIMEOUT : DEFAULT_TIMEOUT;
303
+
304
+ this.registerIceGatheringStateChangeListener();
305
+ this.registerIceCandidateListener();
306
+
307
+ // Set maximum timeout
308
+ setTimeout(() => {
309
+ const {CLOSED} = CONNECTION_STATE;
310
+
311
+ // Close any open peerConnections
312
+ if (this.pc.connectionState !== CLOSED) {
313
+ this.closePeerConnection();
314
+ this.finishReachabilityCheck();
315
+ }
316
+ }, timeout);
317
+
318
+ return this.defer.promise;
319
+ }
320
+ }