@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
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","triggerTimers","event","meeting","data","eventType","CALL_INITIATED","setStartCallInitiateJoinReq","LOCUS_JOIN_REQUEST","setEndCallInitiateJoinReq","setStartJoinReqResp","LOCUS_JOIN_RESPONSE","setEndJoinReqResp","setStartSetupDelay","mediaType","AUDIO","VIDEO","setStartSendingMediaDelay","RECEIVING_MEDIA_START","setEndSetupDelay","SENDING_MEDIA_START","setEndSendingMediaDelay","LOCAL_SDP_GENERATED","setStartLocalSDPGenRemoteSDPRecvDelay","REMOTE_SDP_RECEIVED","setEndLocalSDPGenRemoteSDPRecvDelay","Metrics","instance","_events","meetingCollection","keys","webex","options","meetingId","indexOf","LoggerProxy","logger","error","get","callEvents","MEDIA_QUALITY","sendMediaQualityAnalyzerMetrics","push","sendCallAnalyzerMetrics","info","identifiers","payload","eventId","uuid","v4","version","origin","name","networkType","userAgent","userAgentToString","clientInfo","clientType","clientVersion","CLIENT_NAME","localNetworkPrefix","meetings","geoHintInfo","clientAddress","osVersion","subClientType","os","getOSNameInternal","browser","browserVersion","originTime","triggered","Date","toISOString","senderCountryCode","countryCode","canProceed","eventData","webClientDomain","window","location","hostname","Object","prototype","hasOwnProperty","call","errors","trigger","pstnAudioType","mediaCapabilities","recoveredBy","joinTimes","isRoapCallEnabled","audioSetupDelay","videoSetupDelay","UNKNOWN","intervals","intervalData","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","err","showToUser","errorCode","statusCode","body","ERROR_CODE","MEETING_ERRORS","FREE_USER_MAX_PARTICIPANTS_EXCEEDED","PAID_USER_MAX_PARTICIPANTS_EXCEEDED","SERVICE_MAX_PARTICIPANTS_EXCEEDED","INACTIVE","EXCEEDED_MAX_JOINED_PARTICIPANTS","EXCEEDED_SERVICE_MAX_PARTICIPANTS","MEETING_IS_LOCKED","MEETING_IS_TERMINATING","MEETING_REQUIRE_MODERATOR_PIN_INTENT","MEETING_REQUIRE_MODERATOR_PIN","MEETING_REQUIRE_MODERATOR_ROLE","JOIN_RESTRICTED_USER","GET_RESTRICTED_USER","CREATE_MEDIA_RESTRICTED_USER","JOIN_RESTRICTED_USER_NOT_IN_ROOM","MEETING_NOT_FOUND","NOT_WEBEX_SITE","INVALID_JOIN_TIME","PHONE_NUMBER_NOT_A_NUMBER","PHONE_NUMBER_TOO_LONG","INVALID_DIALABLE_KEY","ONE_ON_ONE_TO_SELF_NOT_ALLOWED","REMOVED_PARTICIPANT","MEETING_LINK_NOT_FOUND","PHONE_NUMBER_TOO_SHORT_AFTER_IDD","INVALID_INVITEE_ADDRESS","PMR_ACCOUNT_LOCKED","RESOURCE_GUEST_FORBIDDEN","PMR_ACCOUNT_SUSPENDED","EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE","INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST","CONVERSATION_NOT_FOUND","RECORDING_CONTROL_NOT_SUPPORTED","RECORDING_NOT_STARTED","RECORDING_NOT_ENABLED","generateErrorPayload","LOCUS_RESPONSE","shownToUser","errorPayload","category","errorDescription","fatal","notFatalErrorList","OTHER","errorData","httpCode","userAgentOption","browserInfo","util","format","metrics","clientName","toLowerCase","split","osInfo","process","env","NODE_ENV","metricName","metricFields","metricTags","internal","submitClientMetrics","type","config","fields","tags"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\nimport util from 'util';\n\nimport {includes} from 'lodash';\nimport uuid from 'uuid';\nimport window from 'global/window';\nimport anonymize from 'ip-anonymize';\n\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {MEETING_ERRORS} from '../constants';\nimport BrowserDetection from '../common/browser-detection';\n\nimport {\n error,\n eventType,\n errorCodes as ERROR_CODE,\n UNKNOWN,\n CLIENT_NAME,\n mediaType,\n} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\n// Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses\n// For reference : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing\nconst anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\nconst triggerTimers = ({event, meeting, data}) => {\n switch (event) {\n case eventType.CALL_INITIATED:\n meeting.setStartCallInitiateJoinReq();\n break;\n case eventType.LOCUS_JOIN_REQUEST:\n meeting.setEndCallInitiateJoinReq();\n meeting.setStartJoinReqResp();\n break;\n case eventType.LOCUS_JOIN_RESPONSE:\n meeting.setEndJoinReqResp();\n meeting.setStartSetupDelay(mediaType.AUDIO);\n meeting.setStartSetupDelay(mediaType.VIDEO);\n meeting.setStartSendingMediaDelay(mediaType.AUDIO);\n meeting.setStartSendingMediaDelay(mediaType.VIDEO);\n break;\n case eventType.RECEIVING_MEDIA_START:\n meeting.setEndSetupDelay(data.mediaType);\n break;\n case eventType.SENDING_MEDIA_START:\n meeting.setEndSendingMediaDelay(data.mediaType);\n break;\n case eventType.LOCAL_SDP_GENERATED:\n meeting.setStartLocalSDPGenRemoteSDPRecvDelay();\n break;\n case eventType.REMOTE_SDP_RECEIVED:\n meeting.setEndLocalSDPGenRemoteSDPRecvDelay();\n break;\n default:\n break;\n }\n};\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n\n _events: any;\n keys: any;\n meetingCollection: any;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Array}\n * @private\n * @memberof Metrics\n */\n this._events = [];\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.meetingCollection = null;\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.keys = Object.values(eventType);\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} meetingCollection meetings object\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(meetingCollection: object, webex: object) {\n this.meetingCollection = meetingCollection;\n this.webex = webex;\n }\n\n /**\n * poste Meeting event metrics\n * @param {object} options {meetingId/meeting} as a json object\n * @param {Meeting} options.meeting Meeting object\n * @param {String} options.meetingId\n * @param {object} options.data\n * @param {object} options.event\n * @returns {object} null\n */\n postEvent(options: {meeting?: any; meetingId?: string; data?: object; event?: any} | any) {\n const {meetingId, data = {}, event} = options;\n let {meeting} = options;\n\n if (this.keys.indexOf(event) === -1) {\n LoggerProxy.logger.error(\n `Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`\n );\n }\n\n if (!meeting && meetingId) {\n meeting = this.meetingCollection.get(meetingId);\n options.meeting = meeting;\n }\n\n if (meeting) {\n triggerTimers(options);\n\n if (!meeting.callEvents) {\n meeting.callEvents = [];\n }\n if (event === eventType.MEDIA_QUALITY) {\n data.event = event;\n meeting.sendMediaQualityAnalyzerMetrics(data);\n } else {\n meeting.callEvents.push(event);\n data.event = event;\n meeting.sendCallAnalyzerMetrics(data);\n }\n } else {\n LoggerProxy.logger.info(\n `Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`\n );\n }\n }\n\n /**\n * Docs for Call analyzer metrics\n * https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki\n * https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml\n */\n\n // eslint-disable-next-line @typescript-eslint/no-shadow\n initPayload(eventType, identifiers, options) {\n const payload: any = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n name: 'endpoint',\n networkType: 'unknown',\n userAgent: this.userAgentToString(),\n clientInfo: {\n clientType: options.clientType,\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n osVersion: getOSVersion() || 'unknown',\n subClientType: options.subClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n eventData: {webClientDomain: window.location.hostname},\n },\n };\n\n // TODO: more options should be checked and some of them should be mandatory in certain conditions\n if (options) {\n if (Object.prototype.hasOwnProperty.call(options, 'canProceed')) {\n payload.event.canProceed = options.canProceed;\n }\n if (options.errors) {\n payload.event.errors = options.errors;\n }\n if (options.mediaType) {\n payload.event.mediaType = options.mediaType;\n }\n if (options.trigger) {\n payload.event.trigger = options.trigger;\n }\n if (options.pstnAudioType) {\n payload.event.pstnAudioType = options.pstnAudioType;\n }\n if (options.mediaCapabilities) {\n payload.event.mediaCapabilities = options.mediaCapabilities;\n }\n if (options.recoveredBy) {\n payload.event.recoveredBy = options.recoveredBy;\n }\n if (options.joinTimes) {\n payload.event.joinTimes = options.joinTimes;\n }\n if (options.isRoapCallEnabled) {\n payload.event.isRoapCallEnabled = options.isRoapCallEnabled;\n }\n }\n\n return payload;\n }\n\n /**\n * get the payload specific for a media quality event through call analyzer\n * @param {String} eventType the event name\n * @param {Object} identifiers contains the identifiers needed for CA\n * @param {String} identifiers.correlationId\n * @param {String} identifiers.locusUrl\n * @param {String} identifiers.locusId\n * @param {Object} options\n * @param {Object} options.intervalData\n * @param {String} options.clientType\n * @returns {Object}\n * @public\n * @memberof Metrics\n */\n public initMediaPayload(\n // eslint-disable-next-line @typescript-eslint/no-shadow\n eventType: string,\n identifiers: {\n correlationId: string;\n locusUrl: string;\n locusId: string;\n },\n options:\n | {\n intervalData: object;\n clientType: string;\n }\n | any = {}\n ) {\n const {audioSetupDelay, videoSetupDelay, joinTimes} = options;\n\n const payload = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n audioSetupDelay,\n videoSetupDelay,\n name: 'endpoint',\n networkType: options.networkType || UNKNOWN,\n userAgent: this.userAgentToString(),\n clientInfo: {\n clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n os: getOSNameInternal(),\n osVersion: getOSVersion() || UNKNOWN,\n subClientType: options.subClientType,\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n intervals: [options.intervalData],\n joinTimes,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || UNKNOWN,\n startTime: new Date().toISOString(),\n },\n },\n };\n\n return payload;\n }\n\n /**\n * This function Parses a Locus error and returns a diagnostic event payload.\n * It should keep updating from:\n * https://sqbu-github.cisco.com/WebExSquared/spark-client-framework/blob/master/spark-client-framework/Adapters/TelephonyAdapter/TelephonyAdapter.cpp#L920\n *\n * @param {Object} err the error Object from Locus response\n * @param {boolean} showToUser true if a toast is shown to user\n * @returns {{showToUser: boolean, category: string, errorDescription: string,\n * errorCode: number, errorData: *, fatal: boolean, name: string}}\n */\n parseLocusError(err: any, showToUser: boolean) {\n let errorCode;\n\n if (err && err.statusCode && err.statusCode >= 500) {\n errorCode = 1003;\n } else if (err && err.body && err.body.errorCode) {\n // locus error codes: https://sqbu-github.cisco.com/WebExSquared/locus/blob/master/server/src/main/resources/locus-error-codes.properties\n switch (ERROR_CODE[err.body.errorCode]) {\n case MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3007;\n break;\n case MEETING_ERRORS.PAID_USER_MAX_PARTICIPANTS_EXCEEDED:\n case MEETING_ERRORS.SERVICE_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3002;\n break;\n case MEETING_ERRORS.INACTIVE:\n errorCode = 4001;\n break;\n case MEETING_ERRORS.EXCEEDED_MAX_JOINED_PARTICIPANTS:\n case MEETING_ERRORS.EXCEEDED_SERVICE_MAX_PARTICIPANTS:\n errorCode = 3001;\n break;\n case MEETING_ERRORS.MEETING_IS_LOCKED:\n errorCode = 4002;\n break;\n case MEETING_ERRORS.MEETING_IS_TERMINATING:\n errorCode = 4003;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN_INTENT:\n errorCode = 4004;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN:\n errorCode = 4005;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_ROLE:\n errorCode = 4006;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER:\n case MEETING_ERRORS.GET_RESTRICTED_USER:\n case MEETING_ERRORS.CREATE_MEDIA_RESTRICTED_USER:\n errorCode = 3005;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER_NOT_IN_ROOM:\n errorCode = 4007;\n break;\n case MEETING_ERRORS.MEETING_NOT_FOUND:\n errorCode = 4011;\n break;\n case MEETING_ERRORS.NOT_WEBEX_SITE:\n errorCode = 4012;\n break;\n case MEETING_ERRORS.INVALID_JOIN_TIME:\n errorCode = 4013;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_NOT_A_NUMBER:\n errorCode = 4016;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_LONG:\n errorCode = 4017;\n break;\n case MEETING_ERRORS.INVALID_DIALABLE_KEY:\n errorCode = 4018;\n break;\n case MEETING_ERRORS.ONE_ON_ONE_TO_SELF_NOT_ALLOWED:\n errorCode = 4019;\n break;\n case MEETING_ERRORS.REMOVED_PARTICIPANT:\n errorCode = 4020;\n break;\n case MEETING_ERRORS.MEETING_LINK_NOT_FOUND:\n errorCode = 4021;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_SHORT_AFTER_IDD:\n errorCode = 4022;\n break;\n case MEETING_ERRORS.INVALID_INVITEE_ADDRESS:\n errorCode = 4023;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_LOCKED:\n errorCode = 4024;\n break;\n case MEETING_ERRORS.RESOURCE_GUEST_FORBIDDEN:\n errorCode = 4025;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_SUSPENDED:\n errorCode = 4026;\n break;\n case MEETING_ERRORS.EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE:\n errorCode = 4027;\n break;\n case MEETING_ERRORS.INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST:\n errorCode = 1006;\n break;\n case MEETING_ERRORS.CONVERSATION_NOT_FOUND:\n errorCode = 4028;\n break;\n case MEETING_ERRORS.RECORDING_CONTROL_NOT_SUPPORTED:\n case MEETING_ERRORS.RECORDING_NOT_STARTED:\n case MEETING_ERRORS.RECORDING_NOT_ENABLED:\n errorCode = 4029;\n break;\n default:\n errorCode = 4008;\n }\n } else {\n errorCode = 4008;\n }\n\n return this.generateErrorPayload(errorCode, showToUser, error.name.LOCUS_RESPONSE, err);\n }\n\n generateErrorPayload(errorCode, shownToUser, name, err) {\n if (error.errors[errorCode]) {\n const errorPayload: any = {\n shownToUser: shownToUser || false,\n category: error.errors[errorCode][2],\n errorDescription: error.errors[errorCode][0],\n errorCode,\n fatal: !includes(error.notFatalErrorList, errorCode),\n name: name || error.name.OTHER,\n };\n\n if (err && err.body) {\n errorPayload.errorData = err.body;\n }\n\n if (err && err.statusCode) {\n errorPayload.httpCode = err.statusCode;\n }\n\n return errorPayload;\n }\n\n return null;\n }\n\n /**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\n userAgentToString() {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !==\n -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${this.webex.version}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${this.webex.version}`);\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":"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"}
1
+ {"version":3,"names":["Metrics","instance","webex","metricName","metricFields","metricTags","internal","metrics","submitClientMetrics","type","config","fields","tags"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(webex: object) {\n this.webex = webex;\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":";;;;;;;;;;;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA,IAKMA,OAAO;EAIX;AACF;AACA;AACA;AACA;AACA;EACE,mBAAc;IAAA;IAAA;IACZ,IAAI,CAACA,OAAO,CAACC,QAAQ,EAAE;MACrB;AACN;AACA;AACA;AACA;AACA;MACMD,OAAO,CAACC,QAAQ,GAAG,IAAI;IACzB;;IAEA;IACA,OAAOD,OAAO,CAACC,QAAQ;EACzB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,sBAAaC,KAAa,EAAE;MAC1B,IAAI,CAACA,KAAK,GAAGA,KAAK;IACpB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EAdE;IAAA;IAAA,OAeA,8BAAqBC,UAAkB,EAAsD;MAAA,IAApDC,YAAoB,uEAAG,CAAC,CAAC;MAAA,IAAEC,UAAkB,uEAAG,CAAC,CAAC;MACzF,IAAI,CAACH,KAAK,CAACI,QAAQ,CAACC,OAAO,CAACC,mBAAmB,CAACL,UAAU,EAAE;QAC1DM,IAAI,EAAE,IAAI,CAACP,KAAK,CAACQ,MAAM,CAACH,OAAO,CAACE,IAAI;QACpCE,MAAM,EAAEP,YAAY;QACpBQ,IAAI,EAAEP;MACR,CAAC,CAAC;IACJ;EAAC;EAAA;AAAA,KAGH;AAAA,8BA5DML,OAAO;AA6Db,IAAMC,QAAQ,GAAG,IAAID,OAAO,EAAE;AAAC,eAEhBC,QAAQ;AAAA"}
@@ -6,14 +6,15 @@ _Object$defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.MediaRequestManager = void 0;
9
- var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
10
9
  var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
11
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
10
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
11
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
12
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
13
13
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
14
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
15
+ var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
15
16
  var _debounce2 = _interopRequireDefault(require("lodash/debounce"));
16
- var _cloneDeep2 = _interopRequireDefault(require("lodash/cloneDeep"));
17
+ var _cloneDeepWith2 = _interopRequireDefault(require("lodash/cloneDeepWith"));
17
18
  var _internalMediaCore = require("@webex/internal-media-core");
18
19
  var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
19
20
  var _receiveSlot = require("./receiveSlot");
@@ -29,18 +30,27 @@ var CODEC_DEFAULTS = {
29
30
  };
30
31
  var DEBOUNCED_SOURCE_UPDATE_TIME = 1000;
31
32
  var MediaRequestManager = /*#__PURE__*/function () {
32
- function MediaRequestManager(degradationPreferences, sendMediaRequestsCallback) {
33
+ function MediaRequestManager(sendMediaRequestsCallback, options) {
33
34
  (0, _classCallCheck2.default)(this, MediaRequestManager);
34
35
  (0, _defineProperty2.default)(this, "sendMediaRequestsCallback", void 0);
36
+ (0, _defineProperty2.default)(this, "kind", void 0);
35
37
  (0, _defineProperty2.default)(this, "counter", void 0);
36
38
  (0, _defineProperty2.default)(this, "clientRequests", void 0);
37
39
  (0, _defineProperty2.default)(this, "degradationPreferences", void 0);
38
40
  (0, _defineProperty2.default)(this, "sourceUpdateListener", void 0);
39
41
  (0, _defineProperty2.default)(this, "debouncedSourceUpdateListener", void 0);
42
+ (0, _defineProperty2.default)(this, "previousStreamRequests", []);
43
+ (0, _defineProperty2.default)(this, "trimRequestsToNumOfSources", void 0);
44
+ (0, _defineProperty2.default)(this, "numTotalSources", void 0);
45
+ (0, _defineProperty2.default)(this, "numLiveSources", void 0);
40
46
  this.sendMediaRequestsCallback = sendMediaRequestsCallback;
41
47
  this.counter = 0;
48
+ this.numLiveSources = 0;
49
+ this.numTotalSources = 0;
42
50
  this.clientRequests = {};
43
- this.degradationPreferences = degradationPreferences;
51
+ this.degradationPreferences = options.degradationPreferences;
52
+ this.kind = options.kind;
53
+ this.trimRequestsToNumOfSources = options.trimRequestsToNumOfSources;
44
54
  this.sourceUpdateListener = this.commit.bind(this);
45
55
  this.debouncedSourceUpdateListener = (0, _debounce2.default)(this.sourceUpdateListener, DEBOUNCED_SOURCE_UPDATE_TIME);
46
56
  }
@@ -52,22 +62,18 @@ var MediaRequestManager = /*#__PURE__*/function () {
52
62
  }
53
63
  }, {
54
64
  key: "getDegradedClientRequests",
55
- value: function getDegradedClientRequests() {
65
+ value: function getDegradedClientRequests(clientRequests) {
56
66
  var _this = this;
57
- var clientRequests = (0, _cloneDeep2.default)(this.clientRequests);
58
67
  var maxFsLimits = [(0, _remoteMedia.getMaxFs)('best'), (0, _remoteMedia.getMaxFs)('large'), (0, _remoteMedia.getMaxFs)('medium'), (0, _remoteMedia.getMaxFs)('small'), (0, _remoteMedia.getMaxFs)('very small'), (0, _remoteMedia.getMaxFs)('thumbnail')];
59
68
 
60
69
  // reduce max-fs until total macroblocks is below limit
61
70
  var _loop = function _loop(i) {
62
71
  var totalMacroblocksRequested = 0;
63
- (0, _entries.default)(clientRequests).forEach(function (_ref) {
64
- var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
65
- id = _ref2[0],
66
- mr = _ref2[1];
72
+ (0, _values.default)(clientRequests).forEach(function (mr) {
67
73
  if (mr.codecInfo) {
68
74
  mr.codecInfo.maxFs = Math.min(mr.preferredMaxFs || CODEC_DEFAULTS.h264.maxFs, mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs, maxFsLimits[i]);
69
75
  // we only consider sources with "live" state
70
- var slotsWithLiveSource = _this.clientRequests[id].receiveSlots.filter(function (rs) {
76
+ var slotsWithLiveSource = mr.receiveSlots.filter(function (rs) {
71
77
  return rs.sourceState === 'live';
72
78
  });
73
79
  totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;
@@ -86,38 +92,213 @@ var MediaRequestManager = /*#__PURE__*/function () {
86
92
  var _ret = _loop(i);
87
93
  if (_ret === "break") break;
88
94
  }
89
- return clientRequests;
95
+ }
96
+
97
+ /**
98
+ * Returns true if two stream requests are the same, false otherwise.
99
+ *
100
+ * @param {StreamRequest} streamRequestA - Stream request A for comparison.
101
+ * @param {StreamRequest} streamRequestB - Stream request B for comparison.
102
+ * @returns {boolean} - Whether they are equal.
103
+ */
104
+ // eslint-disable-next-line class-methods-use-this
105
+ }, {
106
+ key: "isEqual",
107
+ value: function isEqual(streamRequestA, streamRequestB) {
108
+ return (0, _stringify.default)(streamRequestA._toJmpStreamRequest()) === (0, _stringify.default)(streamRequestB._toJmpStreamRequest());
109
+ }
110
+
111
+ /**
112
+ * Compares new stream requests to previous ones and determines
113
+ * if they are the same.
114
+ *
115
+ * @param {StreamRequest[]} newRequests - Array with new requests.
116
+ * @returns {boolean} - True if they are equal, false otherwise.
117
+ */
118
+ }, {
119
+ key: "checkIsNewRequestsEqualToPrev",
120
+ value: function checkIsNewRequestsEqualToPrev(newRequests) {
121
+ var _this2 = this;
122
+ return !(0, _isEmpty2.default)(this.previousStreamRequests) && this.previousStreamRequests.length === newRequests.length && this.previousStreamRequests.every(function (req, idx) {
123
+ return _this2.isEqual(req, newRequests[idx]);
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Returns the maxPayloadBitsPerSecond per Stream
129
+ *
130
+ * If MediaRequestManager kind is "audio", a constant bitrate will be returned.
131
+ * If MediaRequestManager kind is "video", the bitrate will be calculated based
132
+ * on maxFs (default h264 maxFs as fallback if maxFs is not defined)
133
+ *
134
+ * @param {MediaRequest} mediaRequest - mediaRequest to take data from
135
+ * @returns {number} maxPayloadBitsPerSecond
136
+ */
137
+ }, {
138
+ key: "getMaxPayloadBitsPerSecond",
139
+ value: function getMaxPayloadBitsPerSecond(mediaRequest) {
140
+ if (this.kind === 'audio') {
141
+ // return mono_music bitrate default if the kind of mediarequest manager is audio:
142
+ return _internalMediaCore.RecommendedOpusBitrates.FB_MONO_MUSIC;
143
+ }
144
+ return (0, _internalMediaCore.getRecommendedMaxBitrateForFrameSize)(mediaRequest.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs);
145
+ }
146
+
147
+ /**
148
+ * Returns the max Macro Blocks per second (maxMbps) per H264 Stream
149
+ *
150
+ * The maxMbps will be calculated based on maxFs and maxFps
151
+ * (default h264 maxFps as fallback if maxFps is not defined)
152
+ *
153
+ * @param {MediaRequest} mediaRequest - mediaRequest to take data from
154
+ * @returns {number} maxMbps
155
+ */
156
+ // eslint-disable-next-line class-methods-use-this
157
+ }, {
158
+ key: "getH264MaxMbps",
159
+ value: function getH264MaxMbps(mediaRequest) {
160
+ // fallback for maxFps (not needed for maxFs, since there is a fallback already in getDegradedClientRequests)
161
+ var maxFps = mediaRequest.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps;
162
+
163
+ // divided by 100 since maxFps is 3000 (for 30 frames per seconds)
164
+ return mediaRequest.codecInfo.maxFs * maxFps / 100;
165
+ }
166
+
167
+ /**
168
+ * Clears the previous stream requests.
169
+ *
170
+ * @returns {void}
171
+ */
172
+ }, {
173
+ key: "clearPreviousRequests",
174
+ value: function clearPreviousRequests() {
175
+ this.previousStreamRequests = [];
176
+ }
177
+
178
+ /** Modifies the passed in clientRequests and makes sure that in total they don't ask
179
+ * for more streams than there are available.
180
+ *
181
+ * @param {Object} clientRequests
182
+ * @returns {void}
183
+ */
184
+ }, {
185
+ key: "trimRequests",
186
+ value: function trimRequests(clientRequests) {
187
+ var preferLiveVideo = this.getPreferLiveVideo();
188
+ if (!this.trimRequestsToNumOfSources) {
189
+ return;
190
+ }
191
+
192
+ // preferLiveVideo being undefined means that there are no active-speaker requests so we don't need to do any trimming
193
+ if (preferLiveVideo === undefined) {
194
+ return;
195
+ }
196
+ var numStreamsAvailable = preferLiveVideo ? this.numLiveSources : this.numTotalSources;
197
+ (0, _values.default)(clientRequests).sort(function (a, b) {
198
+ // we have to count how many streams we're asking for
199
+ // and should not ask for more than numStreamsAvailable in total,
200
+ // so we might need to trim active-speaker requests and first ones to trim should be
201
+ // the ones with lowest priority
202
+
203
+ // receiver-selected requests have priority over active-speakers
204
+ if (a.policyInfo.policy === 'receiver-selected') {
205
+ return -1;
206
+ }
207
+ if (b.policyInfo.policy === 'receiver-selected') {
208
+ return 1;
209
+ }
210
+
211
+ // and active-speakers are sorted by descending priority
212
+ return b.policyInfo.priority - a.policyInfo.priority;
213
+ }).forEach(function (request) {
214
+ // we only trim active-speaker requests
215
+ if (request.policyInfo.policy === 'active-speaker') {
216
+ var trimmedCount = Math.min(numStreamsAvailable, request.receiveSlots.length);
217
+ request.receiveSlots.length = trimmedCount;
218
+ numStreamsAvailable -= trimmedCount;
219
+ } else {
220
+ numStreamsAvailable -= request.receiveSlots.length;
221
+ }
222
+ if (numStreamsAvailable < 0) {
223
+ numStreamsAvailable = 0;
224
+ }
225
+ });
226
+ }
227
+ }, {
228
+ key: "getPreferLiveVideo",
229
+ value: function getPreferLiveVideo() {
230
+ var preferLiveVideo;
231
+ (0, _values.default)(this.clientRequests).forEach(function (mr) {
232
+ if (mr.policyInfo.policy === 'active-speaker') {
233
+ // take the value from first encountered active speaker request
234
+ if (preferLiveVideo === undefined) {
235
+ preferLiveVideo = mr.policyInfo.preferLiveVideo;
236
+ }
237
+ if (mr.policyInfo.preferLiveVideo !== preferLiveVideo) {
238
+ throw new Error('a mix of active-speaker groups with different values for preferLiveVideo is not supported');
239
+ }
240
+ }
241
+ });
242
+ return preferLiveVideo;
243
+ }
244
+ }, {
245
+ key: "cloneClientRequests",
246
+ value: function cloneClientRequests() {
247
+ // we clone the client requests but without cloning the ReceiveSlots that they reference
248
+ return (0, _cloneDeepWith2.default)(this.clientRequests, function (value, key) {
249
+ if (key === 'receiveSlots') {
250
+ return (0, _toConsumableArray2.default)(value);
251
+ }
252
+ return undefined;
253
+ });
90
254
  }
91
255
  }, {
92
256
  key: "sendRequests",
93
257
  value: function sendRequests() {
94
- var wcmeMediaRequests = [];
95
- var clientRequests = this.getDegradedClientRequests();
96
- var maxPayloadBitsPerSecond = 10 * 1000 * 1000;
258
+ var _this3 = this;
259
+ var streamRequests = [];
97
260
 
98
- // map all the client media requests to wcme media requests
261
+ // clone the requests so that any modifications we do to them don't affect the original ones
262
+ var clientRequests = this.cloneClientRequests();
263
+ this.trimRequests(clientRequests);
264
+ this.getDegradedClientRequests(clientRequests);
265
+
266
+ // map all the client media requests to wcme stream requests
99
267
  (0, _values.default)(clientRequests).forEach(function (mr) {
100
- wcmeMediaRequests.push(new _internalMediaCore.MediaRequest(mr.policyInfo.policy === 'active-speaker' ? _internalMediaCore.Policy.ActiveSpeaker : _internalMediaCore.Policy.ReceiverSelected, mr.policyInfo.policy === 'active-speaker' ? new _internalMediaCore.ActiveSpeakerInfo(mr.policyInfo.priority, mr.policyInfo.crossPriorityDuplication, mr.policyInfo.crossPolicyDuplication, mr.policyInfo.preferLiveVideo) : new _internalMediaCore.ReceiverSelectedInfo(mr.policyInfo.csi), mr.receiveSlots.map(function (receiveSlot) {
101
- return receiveSlot.wcmeReceiveSlot;
102
- }), maxPayloadBitsPerSecond, mr.codecInfo && [new _internalMediaCore.CodecInfo(0x80, new _internalMediaCore.H264Codec(mr.codecInfo.maxFs, mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps, mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps, mr.codecInfo.maxWidth, mr.codecInfo.maxHeight))]));
268
+ if (mr.receiveSlots.length > 0) {
269
+ streamRequests.push(new _internalMediaCore.StreamRequest(mr.policyInfo.policy === 'active-speaker' ? _internalMediaCore.Policy.ActiveSpeaker : _internalMediaCore.Policy.ReceiverSelected, mr.policyInfo.policy === 'active-speaker' ? new _internalMediaCore.ActiveSpeakerInfo(mr.policyInfo.priority, mr.policyInfo.crossPriorityDuplication, mr.policyInfo.crossPolicyDuplication, mr.policyInfo.preferLiveVideo, mr.policyInfo.namedMediaGroups) : new _internalMediaCore.ReceiverSelectedInfo(mr.policyInfo.csi), mr.receiveSlots.map(function (receiveSlot) {
270
+ return receiveSlot.wcmeReceiveSlot;
271
+ }), _this3.getMaxPayloadBitsPerSecond(mr), mr.codecInfo && [new _internalMediaCore.CodecInfo(0x80, new _internalMediaCore.H264Codec(mr.codecInfo.maxFs, mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps, _this3.getH264MaxMbps(mr), mr.codecInfo.maxWidth, mr.codecInfo.maxHeight))]));
272
+ }
103
273
  });
104
- this.sendMediaRequestsCallback(wcmeMediaRequests);
274
+
275
+ //! IMPORTANT: this is only a temporary fix. This will soon be done in the jmp layer (@webex/json-multistream)
276
+ // https://jira-eng-gpk2.cisco.com/jira/browse/WEBEX-326713
277
+ if (!this.checkIsNewRequestsEqualToPrev(streamRequests)) {
278
+ this.sendMediaRequestsCallback(streamRequests);
279
+ this.previousStreamRequests = streamRequests;
280
+ _loggerProxy.default.logger.info("multistream:sendRequests --> media requests sent. ");
281
+ } else {
282
+ _loggerProxy.default.logger.info("multistream:sendRequests --> detected duplicate WCME requests, skipping them... ");
283
+ }
105
284
  }
106
285
  }, {
107
286
  key: "addRequest",
108
287
  value: function addRequest(mediaRequest) {
109
- var _this2 = this;
288
+ var _this4 = this;
110
289
  var commit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
111
290
  // eslint-disable-next-line no-plusplus
112
291
  var newId = "".concat(this.counter++);
113
292
  this.clientRequests[newId] = mediaRequest;
293
+ var eventHandler = function eventHandler(_ref) {
294
+ var maxFs = _ref.maxFs;
295
+ mediaRequest.preferredMaxFs = maxFs;
296
+ _this4.debouncedSourceUpdateListener();
297
+ };
298
+ mediaRequest.handleMaxFs = eventHandler;
114
299
  mediaRequest.receiveSlots.forEach(function (rs) {
115
- rs.on(_receiveSlot.ReceiveSlotEvents.SourceUpdate, _this2.sourceUpdateListener);
116
- rs.on(_receiveSlot.ReceiveSlotEvents.MaxFsUpdate, function (_ref3) {
117
- var maxFs = _ref3.maxFs;
118
- mediaRequest.preferredMaxFs = maxFs;
119
- _this2.debouncedSourceUpdateListener();
120
- });
300
+ rs.on(_receiveSlot.ReceiveSlotEvents.SourceUpdate, _this4.sourceUpdateListener);
301
+ rs.on(_receiveSlot.ReceiveSlotEvents.MaxFsUpdate, mediaRequest.handleMaxFs);
121
302
  });
122
303
  if (commit) {
123
304
  this.commit();
@@ -127,11 +308,12 @@ var MediaRequestManager = /*#__PURE__*/function () {
127
308
  }, {
128
309
  key: "cancelRequest",
129
310
  value: function cancelRequest(requestId) {
130
- var _this$clientRequests$,
131
- _this3 = this;
311
+ var _this5 = this;
132
312
  var commit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
133
- (_this$clientRequests$ = this.clientRequests[requestId]) === null || _this$clientRequests$ === void 0 ? void 0 : _this$clientRequests$.receiveSlots.forEach(function (rs) {
134
- rs.off(_receiveSlot.ReceiveSlotEvents.SourceUpdate, _this3.sourceUpdateListener);
313
+ var mediaRequest = this.clientRequests[requestId];
314
+ mediaRequest === null || mediaRequest === void 0 ? void 0 : mediaRequest.receiveSlots.forEach(function (rs) {
315
+ rs.off(_receiveSlot.ReceiveSlotEvents.SourceUpdate, _this5.sourceUpdateListener);
316
+ rs.off(_receiveSlot.ReceiveSlotEvents.MaxFsUpdate, mediaRequest.handleMaxFs);
135
317
  });
136
318
  delete this.clientRequests[requestId];
137
319
  if (commit) {
@@ -147,6 +329,15 @@ var MediaRequestManager = /*#__PURE__*/function () {
147
329
  key: "reset",
148
330
  value: function reset() {
149
331
  this.clientRequests = {};
332
+ this.numTotalSources = 0;
333
+ this.numLiveSources = 0;
334
+ }
335
+ }, {
336
+ key: "setNumCurrentSources",
337
+ value: function setNumCurrentSources(numTotalSources, numLiveSources) {
338
+ this.numTotalSources = numTotalSources;
339
+ this.numLiveSources = numLiveSources;
340
+ this.sendRequests();
150
341
  }
151
342
  }]);
152
343
  return MediaRequestManager;
@@ -1 +1 @@
1
- {"version":3,"names":["CODEC_DEFAULTS","h264","maxFs","maxFps","maxMbps","DEBOUNCED_SOURCE_UPDATE_TIME","MediaRequestManager","degradationPreferences","sendMediaRequestsCallback","counter","clientRequests","sourceUpdateListener","commit","bind","debouncedSourceUpdateListener","sendRequests","maxFsLimits","getMaxFs","totalMacroblocksRequested","forEach","id","mr","codecInfo","Math","min","preferredMaxFs","i","slotsWithLiveSource","receiveSlots","filter","rs","sourceState","length","maxMacroblocksLimit","LoggerProxy","logger","warn","wcmeMediaRequests","getDegradedClientRequests","maxPayloadBitsPerSecond","push","WcmeMediaRequest","policyInfo","policy","Policy","ActiveSpeaker","ReceiverSelected","ActiveSpeakerInfo","priority","crossPriorityDuplication","crossPolicyDuplication","preferLiveVideo","ReceiverSelectedInfo","csi","map","receiveSlot","wcmeReceiveSlot","WcmeCodecInfo","H264Codec","maxWidth","maxHeight","mediaRequest","newId","on","ReceiveSlotEvents","SourceUpdate","MaxFsUpdate","requestId","off"],"sources":["mediaRequestManager.ts"],"sourcesContent":["/* eslint-disable require-jsdoc */\nimport {\n MediaRequest as WcmeMediaRequest,\n Policy,\n ActiveSpeakerInfo,\n ReceiverSelectedInfo,\n CodecInfo as WcmeCodecInfo,\n H264Codec,\n} from '@webex/internal-media-core';\nimport {cloneDeep, debounce} from 'lodash';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport {ReceiveSlot, ReceiveSlotEvents, ReceiveSlotId} from './receiveSlot';\nimport {getMaxFs} from './remoteMedia';\n\nexport interface ActiveSpeakerPolicyInfo {\n policy: 'active-speaker';\n priority: number;\n crossPriorityDuplication: boolean;\n crossPolicyDuplication: boolean;\n preferLiveVideo: boolean;\n}\n\nexport interface ReceiverSelectedPolicyInfo {\n policy: 'receiver-selected';\n csi: number;\n}\n\nexport type PolicyInfo = ActiveSpeakerPolicyInfo | ReceiverSelectedPolicyInfo;\n\nexport interface H264CodecInfo {\n codec: 'h264';\n maxFs?: number;\n maxFps?: number;\n maxMbps?: number;\n maxWidth?: number;\n maxHeight?: number;\n}\n\nexport type CodecInfo = H264CodecInfo; // we'll add AV1 here in the future when it's available\n\nexport interface MediaRequest {\n policyInfo: PolicyInfo;\n receiveSlots: Array<ReceiveSlot>;\n codecInfo?: CodecInfo;\n preferredMaxFs?: number;\n}\n\nexport type MediaRequestId = string;\n\nconst CODEC_DEFAULTS = {\n h264: {\n maxFs: 8192,\n maxFps: 3000,\n maxMbps: 245760,\n },\n};\n\nconst DEBOUNCED_SOURCE_UPDATE_TIME = 1000;\n\ntype DegradationPreferences = {\n maxMacroblocksLimit: number;\n};\n\ntype SendMediaRequestsCallback = (mediaRequests: WcmeMediaRequest[]) => void;\n\nexport class MediaRequestManager {\n private sendMediaRequestsCallback: SendMediaRequestsCallback;\n\n private counter: number;\n\n private clientRequests: {[key: MediaRequestId]: MediaRequest};\n\n private degradationPreferences: DegradationPreferences;\n\n private sourceUpdateListener: () => void;\n\n private debouncedSourceUpdateListener: () => void;\n\n constructor(\n degradationPreferences: DegradationPreferences,\n sendMediaRequestsCallback: SendMediaRequestsCallback\n ) {\n this.sendMediaRequestsCallback = sendMediaRequestsCallback;\n this.counter = 0;\n this.clientRequests = {};\n this.degradationPreferences = degradationPreferences;\n this.sourceUpdateListener = this.commit.bind(this);\n this.debouncedSourceUpdateListener = debounce(\n this.sourceUpdateListener,\n DEBOUNCED_SOURCE_UPDATE_TIME\n );\n }\n\n public setDegradationPreferences(degradationPreferences: DegradationPreferences) {\n this.degradationPreferences = degradationPreferences;\n this.sendRequests(); // re-send requests after preferences are set\n }\n\n private getDegradedClientRequests() {\n const clientRequests = cloneDeep(this.clientRequests);\n const maxFsLimits = [\n getMaxFs('best'),\n getMaxFs('large'),\n getMaxFs('medium'),\n getMaxFs('small'),\n getMaxFs('very small'),\n getMaxFs('thumbnail'),\n ];\n\n // reduce max-fs until total macroblocks is below limit\n for (let i = 0; i < maxFsLimits.length; i += 1) {\n let totalMacroblocksRequested = 0;\n Object.entries(clientRequests).forEach(([id, mr]) => {\n if (mr.codecInfo) {\n mr.codecInfo.maxFs = Math.min(\n mr.preferredMaxFs || CODEC_DEFAULTS.h264.maxFs,\n mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,\n maxFsLimits[i]\n );\n // we only consider sources with \"live\" state\n const slotsWithLiveSource = this.clientRequests[id].receiveSlots.filter(\n (rs) => rs.sourceState === 'live'\n );\n totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;\n }\n });\n if (totalMacroblocksRequested <= this.degradationPreferences.maxMacroblocksLimit) {\n if (i !== 0) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> too many streams with high max-fs, frame size will be limited to ${maxFsLimits[i]}`\n );\n }\n break;\n } else if (i === maxFsLimits.length - 1) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> even with frame size limited to ${maxFsLimits[i]} you are still requesting too many streams, consider reducing the number of requests`\n );\n }\n }\n\n return clientRequests;\n }\n\n private sendRequests() {\n const wcmeMediaRequests: WcmeMediaRequest[] = [];\n\n const clientRequests = this.getDegradedClientRequests();\n const maxPayloadBitsPerSecond = 10 * 1000 * 1000;\n\n // map all the client media requests to wcme media requests\n Object.values(clientRequests).forEach((mr) => {\n wcmeMediaRequests.push(\n new WcmeMediaRequest(\n mr.policyInfo.policy === 'active-speaker'\n ? Policy.ActiveSpeaker\n : Policy.ReceiverSelected,\n mr.policyInfo.policy === 'active-speaker'\n ? new ActiveSpeakerInfo(\n mr.policyInfo.priority,\n mr.policyInfo.crossPriorityDuplication,\n mr.policyInfo.crossPolicyDuplication,\n mr.policyInfo.preferLiveVideo\n )\n : new ReceiverSelectedInfo(mr.policyInfo.csi),\n mr.receiveSlots.map((receiveSlot) => receiveSlot.wcmeReceiveSlot),\n maxPayloadBitsPerSecond,\n mr.codecInfo && [\n new WcmeCodecInfo(\n 0x80,\n new H264Codec(\n mr.codecInfo.maxFs,\n mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps,\n mr.codecInfo.maxMbps || CODEC_DEFAULTS.h264.maxMbps,\n mr.codecInfo.maxWidth,\n mr.codecInfo.maxHeight\n )\n ),\n ]\n )\n );\n });\n\n this.sendMediaRequestsCallback(wcmeMediaRequests);\n }\n\n public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {\n // eslint-disable-next-line no-plusplus\n const newId = `${this.counter++}`;\n\n this.clientRequests[newId] = mediaRequest;\n\n mediaRequest.receiveSlots.forEach((rs) => {\n rs.on(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n rs.on(ReceiveSlotEvents.MaxFsUpdate, ({maxFs}) => {\n mediaRequest.preferredMaxFs = maxFs;\n this.debouncedSourceUpdateListener();\n });\n });\n\n if (commit) {\n this.commit();\n }\n\n return newId;\n }\n\n public cancelRequest(requestId: MediaRequestId, commit = true) {\n this.clientRequests[requestId]?.receiveSlots.forEach((rs) => {\n rs.off(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n });\n\n delete this.clientRequests[requestId];\n\n if (commit) {\n this.commit();\n }\n }\n\n public commit() {\n return this.sendRequests();\n }\n\n public reset() {\n this.clientRequests = {};\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["CODEC_DEFAULTS","h264","maxFs","maxFps","maxMbps","DEBOUNCED_SOURCE_UPDATE_TIME","MediaRequestManager","sendMediaRequestsCallback","options","counter","numLiveSources","numTotalSources","clientRequests","degradationPreferences","kind","trimRequestsToNumOfSources","sourceUpdateListener","commit","bind","debouncedSourceUpdateListener","sendRequests","maxFsLimits","getMaxFs","totalMacroblocksRequested","forEach","mr","codecInfo","Math","min","preferredMaxFs","i","slotsWithLiveSource","receiveSlots","filter","rs","sourceState","length","maxMacroblocksLimit","LoggerProxy","logger","warn","streamRequestA","streamRequestB","_toJmpStreamRequest","newRequests","previousStreamRequests","every","req","idx","isEqual","mediaRequest","RecommendedOpusBitrates","FB_MONO_MUSIC","getRecommendedMaxBitrateForFrameSize","preferLiveVideo","getPreferLiveVideo","undefined","numStreamsAvailable","sort","a","b","policyInfo","policy","priority","request","trimmedCount","Error","value","key","streamRequests","cloneClientRequests","trimRequests","getDegradedClientRequests","push","StreamRequest","Policy","ActiveSpeaker","ReceiverSelected","ActiveSpeakerInfo","crossPriorityDuplication","crossPolicyDuplication","namedMediaGroups","ReceiverSelectedInfo","csi","map","receiveSlot","wcmeReceiveSlot","getMaxPayloadBitsPerSecond","WcmeCodecInfo","H264Codec","getH264MaxMbps","maxWidth","maxHeight","checkIsNewRequestsEqualToPrev","info","newId","eventHandler","handleMaxFs","on","ReceiveSlotEvents","SourceUpdate","MaxFsUpdate","requestId","off"],"sources":["mediaRequestManager.ts"],"sourcesContent":["/* eslint-disable require-jsdoc */\nimport {\n StreamRequest,\n Policy,\n ActiveSpeakerInfo,\n ReceiverSelectedInfo,\n CodecInfo as WcmeCodecInfo,\n H264Codec,\n getRecommendedMaxBitrateForFrameSize,\n RecommendedOpusBitrates,\n} from '@webex/internal-media-core';\nimport {cloneDeepWith, debounce, isEmpty} from 'lodash';\n\nimport {NamedMediaGroup} from '@webex/json-multistream';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport {ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';\nimport {getMaxFs} from './remoteMedia';\n\nexport interface ActiveSpeakerPolicyInfo {\n policy: 'active-speaker';\n priority: number;\n crossPriorityDuplication: boolean;\n crossPolicyDuplication: boolean;\n preferLiveVideo: boolean;\n namedMediaGroups?: NamedMediaGroup[];\n}\n\nexport interface ReceiverSelectedPolicyInfo {\n policy: 'receiver-selected';\n csi: number;\n}\n\nexport type PolicyInfo = ActiveSpeakerPolicyInfo | ReceiverSelectedPolicyInfo;\n\nexport interface H264CodecInfo {\n codec: 'h264';\n maxFs?: number;\n maxFps?: number;\n maxMbps?: number;\n maxWidth?: number;\n maxHeight?: number;\n}\n\nexport type CodecInfo = H264CodecInfo; // we'll add AV1 here in the future when it's available\n\nexport interface MediaRequest {\n policyInfo: PolicyInfo;\n receiveSlots: Array<ReceiveSlot>;\n codecInfo?: CodecInfo;\n preferredMaxFs?: number;\n handleMaxFs?: ({maxFs}: {maxFs: number}) => void;\n}\n\nexport type MediaRequestId = string;\n\nconst CODEC_DEFAULTS = {\n h264: {\n maxFs: 8192,\n maxFps: 3000,\n maxMbps: 245760,\n },\n};\n\nconst DEBOUNCED_SOURCE_UPDATE_TIME = 1000;\n\ntype DegradationPreferences = {\n maxMacroblocksLimit: number;\n};\n\ntype SendMediaRequestsCallback = (streamRequests: StreamRequest[]) => void;\ntype Kind = 'audio' | 'video';\n\ntype Options = {\n degradationPreferences: DegradationPreferences;\n kind: Kind;\n trimRequestsToNumOfSources: boolean; // if enabled, AS speaker requests will be trimmed based on the calls to setNumCurrentSources()\n};\n\ntype ClientRequestsMap = {[key: MediaRequestId]: MediaRequest};\n\nexport class MediaRequestManager {\n private sendMediaRequestsCallback: SendMediaRequestsCallback;\n\n private kind: Kind;\n\n private counter: number;\n\n private clientRequests: ClientRequestsMap;\n\n private degradationPreferences: DegradationPreferences;\n\n private sourceUpdateListener: () => void;\n\n private debouncedSourceUpdateListener: () => void;\n\n private previousStreamRequests: Array<StreamRequest> = [];\n\n private trimRequestsToNumOfSources: boolean;\n private numTotalSources: number;\n private numLiveSources: number;\n\n constructor(sendMediaRequestsCallback: SendMediaRequestsCallback, options: Options) {\n this.sendMediaRequestsCallback = sendMediaRequestsCallback;\n this.counter = 0;\n this.numLiveSources = 0;\n this.numTotalSources = 0;\n this.clientRequests = {};\n this.degradationPreferences = options.degradationPreferences;\n this.kind = options.kind;\n this.trimRequestsToNumOfSources = options.trimRequestsToNumOfSources;\n this.sourceUpdateListener = this.commit.bind(this);\n this.debouncedSourceUpdateListener = debounce(\n this.sourceUpdateListener,\n DEBOUNCED_SOURCE_UPDATE_TIME\n );\n }\n\n public setDegradationPreferences(degradationPreferences: DegradationPreferences) {\n this.degradationPreferences = degradationPreferences;\n this.sendRequests(); // re-send requests after preferences are set\n }\n\n private getDegradedClientRequests(clientRequests: ClientRequestsMap) {\n const maxFsLimits = [\n getMaxFs('best'),\n getMaxFs('large'),\n getMaxFs('medium'),\n getMaxFs('small'),\n getMaxFs('very small'),\n getMaxFs('thumbnail'),\n ];\n\n // reduce max-fs until total macroblocks is below limit\n for (let i = 0; i < maxFsLimits.length; i += 1) {\n let totalMacroblocksRequested = 0;\n Object.values(clientRequests).forEach((mr) => {\n if (mr.codecInfo) {\n mr.codecInfo.maxFs = Math.min(\n mr.preferredMaxFs || CODEC_DEFAULTS.h264.maxFs,\n mr.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs,\n maxFsLimits[i]\n );\n // we only consider sources with \"live\" state\n const slotsWithLiveSource = mr.receiveSlots.filter((rs) => rs.sourceState === 'live');\n totalMacroblocksRequested += mr.codecInfo.maxFs * slotsWithLiveSource.length;\n }\n });\n if (totalMacroblocksRequested <= this.degradationPreferences.maxMacroblocksLimit) {\n if (i !== 0) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> too many streams with high max-fs, frame size will be limited to ${maxFsLimits[i]}`\n );\n }\n break;\n } else if (i === maxFsLimits.length - 1) {\n LoggerProxy.logger.warn(\n `multistream:mediaRequestManager --> even with frame size limited to ${maxFsLimits[i]} you are still requesting too many streams, consider reducing the number of requests`\n );\n }\n }\n }\n\n /**\n * Returns true if two stream requests are the same, false otherwise.\n *\n * @param {StreamRequest} streamRequestA - Stream request A for comparison.\n * @param {StreamRequest} streamRequestB - Stream request B for comparison.\n * @returns {boolean} - Whether they are equal.\n */\n // eslint-disable-next-line class-methods-use-this\n public isEqual(streamRequestA: StreamRequest, streamRequestB: StreamRequest) {\n return (\n JSON.stringify(streamRequestA._toJmpStreamRequest()) ===\n JSON.stringify(streamRequestB._toJmpStreamRequest())\n );\n }\n\n /**\n * Compares new stream requests to previous ones and determines\n * if they are the same.\n *\n * @param {StreamRequest[]} newRequests - Array with new requests.\n * @returns {boolean} - True if they are equal, false otherwise.\n */\n private checkIsNewRequestsEqualToPrev(newRequests: StreamRequest[]) {\n return (\n !isEmpty(this.previousStreamRequests) &&\n this.previousStreamRequests.length === newRequests.length &&\n this.previousStreamRequests.every((req, idx) => this.isEqual(req, newRequests[idx]))\n );\n }\n\n /**\n * Returns the maxPayloadBitsPerSecond per Stream\n *\n * If MediaRequestManager kind is \"audio\", a constant bitrate will be returned.\n * If MediaRequestManager kind is \"video\", the bitrate will be calculated based\n * on maxFs (default h264 maxFs as fallback if maxFs is not defined)\n *\n * @param {MediaRequest} mediaRequest - mediaRequest to take data from\n * @returns {number} maxPayloadBitsPerSecond\n */\n private getMaxPayloadBitsPerSecond(mediaRequest: MediaRequest): number {\n if (this.kind === 'audio') {\n // return mono_music bitrate default if the kind of mediarequest manager is audio:\n return RecommendedOpusBitrates.FB_MONO_MUSIC;\n }\n\n return getRecommendedMaxBitrateForFrameSize(\n mediaRequest.codecInfo.maxFs || CODEC_DEFAULTS.h264.maxFs\n );\n }\n\n /**\n * Returns the max Macro Blocks per second (maxMbps) per H264 Stream\n *\n * The maxMbps will be calculated based on maxFs and maxFps\n * (default h264 maxFps as fallback if maxFps is not defined)\n *\n * @param {MediaRequest} mediaRequest - mediaRequest to take data from\n * @returns {number} maxMbps\n */\n // eslint-disable-next-line class-methods-use-this\n private getH264MaxMbps(mediaRequest: MediaRequest): number {\n // fallback for maxFps (not needed for maxFs, since there is a fallback already in getDegradedClientRequests)\n const maxFps = mediaRequest.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps;\n\n // divided by 100 since maxFps is 3000 (for 30 frames per seconds)\n return (mediaRequest.codecInfo.maxFs * maxFps) / 100;\n }\n\n /**\n * Clears the previous stream requests.\n *\n * @returns {void}\n */\n public clearPreviousRequests(): void {\n this.previousStreamRequests = [];\n }\n\n /** Modifies the passed in clientRequests and makes sure that in total they don't ask\n * for more streams than there are available.\n *\n * @param {Object} clientRequests\n * @returns {void}\n */\n private trimRequests(clientRequests: ClientRequestsMap) {\n const preferLiveVideo = this.getPreferLiveVideo();\n\n if (!this.trimRequestsToNumOfSources) {\n return;\n }\n\n // preferLiveVideo being undefined means that there are no active-speaker requests so we don't need to do any trimming\n if (preferLiveVideo === undefined) {\n return;\n }\n\n let numStreamsAvailable = preferLiveVideo ? this.numLiveSources : this.numTotalSources;\n\n Object.values(clientRequests)\n .sort((a, b) => {\n // we have to count how many streams we're asking for\n // and should not ask for more than numStreamsAvailable in total,\n // so we might need to trim active-speaker requests and first ones to trim should be\n // the ones with lowest priority\n\n // receiver-selected requests have priority over active-speakers\n if (a.policyInfo.policy === 'receiver-selected') {\n return -1;\n }\n if (b.policyInfo.policy === 'receiver-selected') {\n return 1;\n }\n\n // and active-speakers are sorted by descending priority\n return b.policyInfo.priority - a.policyInfo.priority;\n })\n .forEach((request) => {\n // we only trim active-speaker requests\n if (request.policyInfo.policy === 'active-speaker') {\n const trimmedCount = Math.min(numStreamsAvailable, request.receiveSlots.length);\n\n request.receiveSlots.length = trimmedCount;\n\n numStreamsAvailable -= trimmedCount;\n } else {\n numStreamsAvailable -= request.receiveSlots.length;\n }\n\n if (numStreamsAvailable < 0) {\n numStreamsAvailable = 0;\n }\n });\n }\n\n private getPreferLiveVideo(): boolean | undefined {\n let preferLiveVideo;\n\n Object.values(this.clientRequests).forEach((mr) => {\n if (mr.policyInfo.policy === 'active-speaker') {\n // take the value from first encountered active speaker request\n if (preferLiveVideo === undefined) {\n preferLiveVideo = mr.policyInfo.preferLiveVideo;\n }\n\n if (mr.policyInfo.preferLiveVideo !== preferLiveVideo) {\n throw new Error(\n 'a mix of active-speaker groups with different values for preferLiveVideo is not supported'\n );\n }\n }\n });\n\n return preferLiveVideo;\n }\n\n private cloneClientRequests(): ClientRequestsMap {\n // we clone the client requests but without cloning the ReceiveSlots that they reference\n return cloneDeepWith(this.clientRequests, (value, key) => {\n if (key === 'receiveSlots') {\n return [...value];\n }\n\n return undefined;\n });\n }\n\n private sendRequests() {\n const streamRequests: StreamRequest[] = [];\n\n // clone the requests so that any modifications we do to them don't affect the original ones\n const clientRequests = this.cloneClientRequests();\n\n this.trimRequests(clientRequests);\n this.getDegradedClientRequests(clientRequests);\n\n // map all the client media requests to wcme stream requests\n Object.values(clientRequests).forEach((mr) => {\n if (mr.receiveSlots.length > 0) {\n streamRequests.push(\n new StreamRequest(\n mr.policyInfo.policy === 'active-speaker'\n ? Policy.ActiveSpeaker\n : Policy.ReceiverSelected,\n mr.policyInfo.policy === 'active-speaker'\n ? new ActiveSpeakerInfo(\n mr.policyInfo.priority,\n mr.policyInfo.crossPriorityDuplication,\n mr.policyInfo.crossPolicyDuplication,\n mr.policyInfo.preferLiveVideo,\n mr.policyInfo.namedMediaGroups\n )\n : new ReceiverSelectedInfo(mr.policyInfo.csi),\n mr.receiveSlots.map((receiveSlot) => receiveSlot.wcmeReceiveSlot),\n this.getMaxPayloadBitsPerSecond(mr),\n mr.codecInfo && [\n new WcmeCodecInfo(\n 0x80,\n new H264Codec(\n mr.codecInfo.maxFs,\n mr.codecInfo.maxFps || CODEC_DEFAULTS.h264.maxFps,\n this.getH264MaxMbps(mr),\n mr.codecInfo.maxWidth,\n mr.codecInfo.maxHeight\n )\n ),\n ]\n )\n );\n }\n });\n\n //! IMPORTANT: this is only a temporary fix. This will soon be done in the jmp layer (@webex/json-multistream)\n // https://jira-eng-gpk2.cisco.com/jira/browse/WEBEX-326713\n if (!this.checkIsNewRequestsEqualToPrev(streamRequests)) {\n this.sendMediaRequestsCallback(streamRequests);\n this.previousStreamRequests = streamRequests;\n LoggerProxy.logger.info(`multistream:sendRequests --> media requests sent. `);\n } else {\n LoggerProxy.logger.info(\n `multistream:sendRequests --> detected duplicate WCME requests, skipping them... `\n );\n }\n }\n\n public addRequest(mediaRequest: MediaRequest, commit = true): MediaRequestId {\n // eslint-disable-next-line no-plusplus\n const newId = `${this.counter++}`;\n\n this.clientRequests[newId] = mediaRequest;\n\n const eventHandler = ({maxFs}) => {\n mediaRequest.preferredMaxFs = maxFs;\n this.debouncedSourceUpdateListener();\n };\n mediaRequest.handleMaxFs = eventHandler;\n\n mediaRequest.receiveSlots.forEach((rs) => {\n rs.on(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n rs.on(ReceiveSlotEvents.MaxFsUpdate, mediaRequest.handleMaxFs);\n });\n\n if (commit) {\n this.commit();\n }\n\n return newId;\n }\n\n public cancelRequest(requestId: MediaRequestId, commit = true) {\n const mediaRequest = this.clientRequests[requestId];\n\n mediaRequest?.receiveSlots.forEach((rs) => {\n rs.off(ReceiveSlotEvents.SourceUpdate, this.sourceUpdateListener);\n rs.off(ReceiveSlotEvents.MaxFsUpdate, mediaRequest.handleMaxFs);\n });\n\n delete this.clientRequests[requestId];\n\n if (commit) {\n this.commit();\n }\n }\n\n public commit() {\n return this.sendRequests();\n }\n\n public reset() {\n this.clientRequests = {};\n this.numTotalSources = 0;\n this.numLiveSources = 0;\n }\n\n public setNumCurrentSources(numTotalSources: number, numLiveSources: number) {\n this.numTotalSources = numTotalSources;\n this.numLiveSources = numLiveSources;\n\n this.sendRequests();\n }\n}\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ _Object$defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
9
  exports.ReceiveSlotEvents = exports.ReceiveSlot = void 0;
10
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
10
11
  var _weakMap = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/weak-map"));
11
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
12
13
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
@@ -166,6 +167,15 @@ var ReceiveSlot = /*#__PURE__*/function (_EventsScope) {
166
167
  }
167
168
  }
168
169
 
170
+ /**
171
+ * @returns {string} a log message used to identify the receive slot
172
+ */
173
+ }, {
174
+ key: "logString",
175
+ get: function get() {
176
+ return "ReceiveSlot - ".concat(this.id, ": ").concat((0, _stringify.default)(this.mcReceiveSlot.id));
177
+ }
178
+
169
179
  /**
170
180
  * The MediaStream object associated with this slot.
171
181
  *
@@ -1 +1 @@
1
- {"version":3,"names":["ReceiveSlotEvents","SourceUpdate","MaxFsUpdate","receiveSlotCounter","ReceiveSlot","mediaType","mcReceiveSlot","findMemberIdCallback","id","setupEventListeners","newFs","emit","file","function","maxFs","scope","on","WcmeReceiveSlotEvents","state","csi","LoggerProxy","logger","log","undefined","memberId","stream","EventsScope"],"sources":["receiveSlot.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {\n MediaType,\n ReceiveSlot as WcmeReceiveSlot,\n ReceiveSlotEvents as WcmeReceiveSlotEvents,\n SourceState,\n} from '@webex/internal-media-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nexport const ReceiveSlotEvents = {\n SourceUpdate: 'sourceUpdate',\n MaxFsUpdate: 'maxFsUpdate',\n};\n\nexport type {SourceState} from '@webex/internal-media-core';\nexport type CSI = number;\nexport type MemberId = string;\nexport type ReceiveSlotId = string;\n\nlet receiveSlotCounter = 0;\n\nexport type FindMemberIdCallback = (csi: CSI) => MemberId | undefined;\n\n/**\n * Class representing a receive slot. A single receive slot is able to receive a single track\n * for example some participant's main video or audio\n */\nexport class ReceiveSlot extends EventsScope {\n private readonly mcReceiveSlot: WcmeReceiveSlot;\n\n private readonly findMemberIdCallback: FindMemberIdCallback;\n\n public readonly id: ReceiveSlotId;\n\n public readonly mediaType: MediaType;\n\n #memberId?: MemberId;\n\n #csi?: CSI;\n\n #sourceState: SourceState;\n\n /**\n * constructor - don't use it directly, you should always use meeting.receiveSlotManager.allocateSlot()\n * to create any receive slots\n *\n * @param {MediaType} mediaType\n * @param {ReceiveSlot} mcReceiveSlot\n * @param {FindMemberIdCallback} findMemberIdCallback callback for finding memberId for given CSI\n */\n constructor(\n mediaType: MediaType,\n mcReceiveSlot: WcmeReceiveSlot,\n findMemberIdCallback: FindMemberIdCallback\n ) {\n super();\n\n receiveSlotCounter += 1;\n\n this.findMemberIdCallback = findMemberIdCallback;\n this.mediaType = mediaType;\n this.mcReceiveSlot = mcReceiveSlot;\n this.#sourceState = 'no source';\n this.id = `r${receiveSlotCounter}`;\n\n this.setupEventListeners();\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.#memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.#csi;\n }\n\n /**\n * Set the max frame size for this slot\n * @param newFs frame size\n */\n public setMaxFs(newFs) {\n // emit event for media request manager to listen to\n\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.MaxFsUpdate,\n {\n maxFs: newFs,\n }\n );\n }\n\n /**\n * Getter for sourceState\n */\n public get sourceState() {\n return this.#sourceState;\n }\n\n /**\n * registers event handlers with the underlying ReceiveSlot\n */\n private setupEventListeners() {\n const scope = {\n file: 'meeting/receiveSlot',\n function: 'setupEventListeners',\n };\n\n this.mcReceiveSlot.on(\n WcmeReceiveSlotEvents.SourceUpdate,\n (state: SourceState, csi?: number) => {\n LoggerProxy.logger.log(\n `ReceiveSlot#setupEventListeners --> got source update on receive slot ${this.id}, mediaType=${this.mediaType}, csi=${csi}, state=${state}`\n );\n this.#memberId = csi ? this.findMemberIdCallback(csi) : undefined;\n this.#csi = csi;\n this.#sourceState = state;\n\n this.emit(scope, ReceiveSlotEvents.SourceUpdate, {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n });\n }\n );\n }\n\n /** Tries to find the member id for this receive slot if it hasn't got one */\n public findMemberId() {\n if (this.#memberId === undefined && this.#csi) {\n this.#memberId = this.findMemberIdCallback(this.#csi);\n\n if (this.#memberId) {\n // if we found the memberId, simulate source update so that the client app knows that something's changed\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.SourceUpdate,\n {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n }\n );\n }\n }\n }\n\n /**\n * The MediaStream object associated with this slot.\n *\n * @returns {MediaStream} The MediaStreamTrack.\n */\n get stream(): MediaStream {\n return this.mcReceiveSlot.stream;\n }\n\n /**\n * The underlying WCME receive slot\n */\n get wcmeReceiveSlot(): WcmeReceiveSlot {\n return this.mcReceiveSlot;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["ReceiveSlotEvents","SourceUpdate","MaxFsUpdate","receiveSlotCounter","ReceiveSlot","mediaType","mcReceiveSlot","findMemberIdCallback","id","setupEventListeners","newFs","emit","file","function","maxFs","scope","on","WcmeReceiveSlotEvents","state","csi","LoggerProxy","logger","log","undefined","memberId","stream","EventsScope"],"sources":["receiveSlot.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport {\n MediaType,\n ReceiveSlot as WcmeReceiveSlot,\n ReceiveSlotEvents as WcmeReceiveSlotEvents,\n StreamState,\n} from '@webex/internal-media-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nexport const ReceiveSlotEvents = {\n SourceUpdate: 'sourceUpdate',\n MaxFsUpdate: 'maxFsUpdate',\n};\n\nexport type {StreamState} from '@webex/internal-media-core';\nexport type CSI = number;\nexport type MemberId = string;\nexport type ReceiveSlotId = string;\n\nlet receiveSlotCounter = 0;\n\nexport type FindMemberIdCallback = (csi: CSI) => MemberId | undefined;\n\n/**\n * Class representing a receive slot. A single receive slot is able to receive a single track\n * for example some participant's main video or audio\n */\nexport class ReceiveSlot extends EventsScope {\n private readonly mcReceiveSlot: WcmeReceiveSlot;\n\n private readonly findMemberIdCallback: FindMemberIdCallback;\n\n public readonly id: ReceiveSlotId;\n\n public readonly mediaType: MediaType;\n\n #memberId?: MemberId;\n\n #csi?: CSI;\n\n #sourceState: StreamState;\n\n /**\n * constructor - don't use it directly, you should always use meeting.receiveSlotManager.allocateSlot()\n * to create any receive slots\n *\n * @param {MediaType} mediaType\n * @param {ReceiveSlot} mcReceiveSlot\n * @param {FindMemberIdCallback} findMemberIdCallback callback for finding memberId for given CSI\n */\n constructor(\n mediaType: MediaType,\n mcReceiveSlot: WcmeReceiveSlot,\n findMemberIdCallback: FindMemberIdCallback\n ) {\n super();\n\n receiveSlotCounter += 1;\n\n this.findMemberIdCallback = findMemberIdCallback;\n this.mediaType = mediaType;\n this.mcReceiveSlot = mcReceiveSlot;\n this.#sourceState = 'no source';\n this.id = `r${receiveSlotCounter}`;\n\n this.setupEventListeners();\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.#memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.#csi;\n }\n\n /**\n * Set the max frame size for this slot\n * @param newFs frame size\n */\n public setMaxFs(newFs) {\n // emit event for media request manager to listen to\n\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.MaxFsUpdate,\n {\n maxFs: newFs,\n }\n );\n }\n\n /**\n * Getter for sourceState\n */\n public get sourceState() {\n return this.#sourceState;\n }\n\n /**\n * registers event handlers with the underlying ReceiveSlot\n */\n private setupEventListeners() {\n const scope = {\n file: 'meeting/receiveSlot',\n function: 'setupEventListeners',\n };\n\n this.mcReceiveSlot.on(\n WcmeReceiveSlotEvents.SourceUpdate,\n (state: StreamState, csi?: number) => {\n LoggerProxy.logger.log(\n `ReceiveSlot#setupEventListeners --> got source update on receive slot ${this.id}, mediaType=${this.mediaType}, csi=${csi}, state=${state}`\n );\n this.#memberId = csi ? this.findMemberIdCallback(csi) : undefined;\n this.#csi = csi;\n this.#sourceState = state;\n\n this.emit(scope, ReceiveSlotEvents.SourceUpdate, {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n });\n }\n );\n }\n\n /** Tries to find the member id for this receive slot if it hasn't got one */\n public findMemberId() {\n if (this.#memberId === undefined && this.#csi) {\n this.#memberId = this.findMemberIdCallback(this.#csi);\n\n if (this.#memberId) {\n // if we found the memberId, simulate source update so that the client app knows that something's changed\n this.emit(\n {\n file: 'meeting/receiveSlot',\n function: 'findMemberId',\n },\n ReceiveSlotEvents.SourceUpdate,\n {\n state: this.#sourceState,\n csi: this.#csi,\n memberId: this.#memberId,\n }\n );\n }\n }\n }\n\n /**\n * @returns {string} a log message used to identify the receive slot\n */\n public get logString() {\n return `ReceiveSlot - ${this.id}: ${JSON.stringify(this.mcReceiveSlot.id)}`;\n }\n\n /**\n * The MediaStream object associated with this slot.\n *\n * @returns {MediaStream} The MediaStreamTrack.\n */\n get stream(): MediaStream {\n return this.mcReceiveSlot.stream;\n }\n\n /**\n * The underlying WCME receive slot\n */\n get wcmeReceiveSlot(): WcmeReceiveSlot {\n return this.mcReceiveSlot;\n }\n}\n"],"mappings":"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"}