@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,6 +1,8 @@
1
1
  /* eslint-disable valid-jsdoc */
2
2
  /* eslint-disable require-jsdoc */
3
3
  /* eslint-disable import/prefer-default-export */
4
+ import {forEach} from 'lodash';
5
+ import {NamedMediaGroup} from '@webex/json-multistream';
4
6
  import LoggerProxy from '../common/logs/logger-proxy';
5
7
 
6
8
  import {getMaxFs, RemoteMedia, RemoteVideoResolution} from './remoteMedia';
@@ -10,6 +12,7 @@ import {CSI, ReceiveSlot} from './receiveSlot';
10
12
  type Options = {
11
13
  resolution?: RemoteVideoResolution; // applies only to groups of type MediaType.VideoMain and MediaType.VideoSlides
12
14
  preferLiveVideo?: boolean; // applies only to groups of type MediaType.VideoMain and MediaType.VideoSlides
15
+ namedMediaGroup?: NamedMediaGroup; // applies only to named media groups for audio
13
16
  };
14
17
 
15
18
  export class RemoteMediaGroup {
@@ -66,6 +69,53 @@ export class RemoteMediaGroup {
66
69
  return [...this.unpinnedRemoteMedia, ...this.pinnedRemoteMedia];
67
70
  }
68
71
 
72
+ /**
73
+ * Sets CSIs for multiple RemoteMedia instances belonging to this RemoteMediaGroup.
74
+ * For each entry in the remoteMediaCsis array:
75
+ * - if csi is specified, the RemoteMedia instance is pinned to that CSI
76
+ * - if csi is undefined, the RemoteMedia instance is unpinned
77
+ * @internal
78
+ */
79
+ public setActiveSpeakerCsis(
80
+ remoteMediaCsis: {remoteMedia: RemoteMedia; csi?: number}[],
81
+ commit = true
82
+ ): void {
83
+ forEach(remoteMediaCsis, ({csi, remoteMedia}) => {
84
+ if (csi) {
85
+ if (!(this.pinnedRemoteMedia.indexOf(remoteMedia) >= 0)) {
86
+ const unpinId = this.unpinnedRemoteMedia.indexOf(remoteMedia);
87
+ if (unpinId >= 0) {
88
+ this.unpinnedRemoteMedia.splice(unpinId, 1);
89
+ this.pinnedRemoteMedia.push(remoteMedia);
90
+ } else {
91
+ throw new Error(
92
+ `failed to pin a remote media object ${remoteMedia.id}, because it is not found in this remote media group`
93
+ );
94
+ }
95
+ }
96
+ remoteMedia.sendMediaRequest(csi, false);
97
+ } else {
98
+ if (!(this.unpinnedRemoteMedia.indexOf(remoteMedia) >= 0)) {
99
+ const pinId = this.pinnedRemoteMedia.indexOf(remoteMedia);
100
+ if (pinId >= 0) {
101
+ this.pinnedRemoteMedia.splice(pinId, 1);
102
+ this.unpinnedRemoteMedia.push(remoteMedia);
103
+ } else {
104
+ throw new Error(
105
+ `failed to unpin a remote media object ${remoteMedia.id}, because it is not found in this remote media group`
106
+ );
107
+ }
108
+ }
109
+ remoteMedia.cancelMediaRequest(false);
110
+ }
111
+ });
112
+ this.cancelActiveSpeakerMediaRequest(false);
113
+ this.sendActiveSpeakerMediaRequest(false);
114
+ if (commit) {
115
+ this.mediaRequestManager.commit();
116
+ }
117
+ }
118
+
69
119
  /**
70
120
  * Pins a specific remote media instance to a specfic CSI, so the media will
71
121
  * no longer come from active speaker, but from that CSI.
@@ -151,6 +201,17 @@ export class RemoteMediaGroup {
151
201
  throw new Error(`remote media object ${remoteMedia.id} not found in the group`);
152
202
  }
153
203
 
204
+ /**
205
+ * setPreferLiveVideo - sets preferLiveVideo to true/false
206
+ * @internal
207
+ */
208
+ public setPreferLiveVideo(preferLiveVideo: boolean, commit: boolean) {
209
+ if (this.options.preferLiveVideo !== preferLiveVideo) {
210
+ this.options.preferLiveVideo = preferLiveVideo;
211
+ this.sendActiveSpeakerMediaRequest(commit);
212
+ }
213
+ }
214
+
154
215
  private sendActiveSpeakerMediaRequest(commit: boolean) {
155
216
  this.cancelActiveSpeakerMediaRequest(false);
156
217
 
@@ -162,6 +223,9 @@ export class RemoteMediaGroup {
162
223
  crossPriorityDuplication: false,
163
224
  crossPolicyDuplication: false,
164
225
  preferLiveVideo: !!this.options?.preferLiveVideo,
226
+ namedMediaGroups: this.options.namedMediaGroup?.value
227
+ ? [this.options?.namedMediaGroup]
228
+ : undefined,
165
229
  },
166
230
  receiveSlots: this.unpinnedRemoteMedia.map((remoteMedia) =>
167
231
  remoteMedia.getUnderlyingReceiveSlot()
@@ -182,6 +246,20 @@ export class RemoteMediaGroup {
182
246
  }
183
247
  }
184
248
 
249
+ /**
250
+ * setNamedMediaGroup - sets named media group type and value
251
+ * @internal
252
+ */
253
+ public setNamedMediaGroup(namedMediaGroup: NamedMediaGroup, commit: boolean) {
254
+ if (
255
+ this.options.namedMediaGroup.value !== namedMediaGroup.value ||
256
+ this.options.namedMediaGroup.type !== namedMediaGroup.type
257
+ ) {
258
+ this.options.namedMediaGroup = namedMediaGroup;
259
+ this.sendActiveSpeakerMediaRequest(commit);
260
+ }
261
+ }
262
+
185
263
  /**
186
264
  * Invalidates the remote media group by clearing the references to the receive slots
187
265
  * used by all remote media from that group and cancelling all media requests.
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable valid-jsdoc */
2
- import {cloneDeep, remove} from 'lodash';
2
+ import {cloneDeep, forEach, remove} from 'lodash';
3
3
  import {EventMap} from 'typed-emitter';
4
4
  import {MediaType} from '@webex/internal-media-core';
5
+ import {NamedMediaGroup} from '@webex/json-multistream';
5
6
 
6
7
  import LoggerProxy from '../common/logs/logger-proxy';
7
8
  import EventsScope from '../common/events/events-scope';
@@ -11,6 +12,7 @@ import {ReceiveSlot, CSI} from './receiveSlot';
11
12
  import {ReceiveSlotManager} from './receiveSlotManager';
12
13
  import {RemoteMediaGroup} from './remoteMediaGroup';
13
14
  import {MediaRequestManager} from './mediaRequestManager';
15
+ import {NAMED_MEDIA_GROUP_TYPE_AUDIO} from '../constants';
14
16
 
15
17
  export type PaneSize = RemoteVideoResolution;
16
18
  export type LayoutId = string;
@@ -49,6 +51,7 @@ export interface Configuration {
49
51
 
50
52
  layouts: {[key: LayoutId]: VideoLayout}; // a map of all available layouts, a layout can be set via setLayout() method
51
53
  };
54
+ namedMediaGroup?: NamedMediaGroup;
52
55
  }
53
56
 
54
57
  /* Predefined layouts: */
@@ -96,6 +99,7 @@ const OnePlusFiveLayout: VideoLayout = {
96
99
  };
97
100
 
98
101
  // A layout with 2 big panes for 2 main active speakers and a strip of 6 small panes for other active speakers:
102
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
99
103
  const TwoMainPlusSixSmallLayout: VideoLayout = {
100
104
  activeSpeakerVideoPaneGroups: [
101
105
  {
@@ -172,6 +176,7 @@ export const DefaultConfiguration: Configuration = {
172
176
  export enum Event {
173
177
  // events for audio streams
174
178
  AudioCreated = 'AudioCreated',
179
+ InterpretationAudioCreated = 'InterpretationAudioCreated',
175
180
  ScreenShareAudioCreated = 'ScreenShareAudioCreated',
176
181
 
177
182
  // events for video streams
@@ -220,7 +225,10 @@ export class RemoteMediaManager extends EventsScope {
220
225
  private currentLayout?: VideoLayout;
221
226
 
222
227
  private slots: {
223
- audio: ReceiveSlot[];
228
+ audio: {
229
+ main: ReceiveSlot[];
230
+ si: ReceiveSlot;
231
+ };
224
232
  screenShare: {
225
233
  audio: ReceiveSlot[];
226
234
  video?: ReceiveSlot;
@@ -233,7 +241,10 @@ export class RemoteMediaManager extends EventsScope {
233
241
  };
234
242
 
235
243
  private media: {
236
- audio?: RemoteMediaGroup;
244
+ audio: {
245
+ main?: RemoteMediaGroup;
246
+ si?: RemoteMediaGroup;
247
+ };
237
248
  video: {
238
249
  activeSpeakerGroups: {
239
250
  [key: PaneGroupId]: RemoteMediaGroup;
@@ -276,7 +287,10 @@ export class RemoteMediaManager extends EventsScope {
276
287
  this.receiveSlotManager = receiveSlotManager;
277
288
  this.mediaRequestManagers = mediaRequestManagers;
278
289
  this.media = {
279
- audio: undefined,
290
+ audio: {
291
+ main: undefined,
292
+ si: undefined,
293
+ },
280
294
  video: {
281
295
  activeSpeakerGroups: {},
282
296
  memberPanes: {},
@@ -290,7 +304,10 @@ export class RemoteMediaManager extends EventsScope {
290
304
  this.checkConfigValidity();
291
305
 
292
306
  this.slots = {
293
- audio: [],
307
+ audio: {
308
+ main: [],
309
+ si: undefined,
310
+ },
294
311
  screenShare: {
295
312
  audio: [],
296
313
  video: undefined,
@@ -388,8 +405,11 @@ export class RemoteMediaManager extends EventsScope {
388
405
  });
389
406
 
390
407
  // release all audio receive slots
391
- this.slots.audio.forEach((slot) => this.receiveSlotManager.releaseSlot(slot));
392
- this.slots.audio.length = 0;
408
+ this.slots.audio.main.forEach((slot) => this.receiveSlotManager.releaseSlot(slot));
409
+ this.slots.audio.main.length = 0;
410
+ if (this.slots.audio.si) {
411
+ this.receiveSlotManager.releaseSlot(this.slots.audio.si);
412
+ }
393
413
 
394
414
  // release screen share slots
395
415
  this.slots.screenShare.audio.forEach((slot) => this.receiveSlotManager.releaseSlot(slot));
@@ -472,6 +492,8 @@ export class RemoteMediaManager extends EventsScope {
472
492
  if (!this.started) {
473
493
  throw new Error('setLayout() called before start()');
474
494
  }
495
+ LoggerProxy.logger.log(`RemoteMediaManager#setLayout --> new layout selected: ${layoutId}`);
496
+
475
497
  this.currentLayoutId = layoutId;
476
498
  this.currentLayout = cloneDeep(this.config.video.layouts[this.currentLayoutId]);
477
499
 
@@ -490,22 +512,86 @@ export class RemoteMediaManager extends EventsScope {
490
512
  return this.currentLayoutId;
491
513
  }
492
514
 
515
+ /**
516
+ * sets the preferLiveVideo
517
+ */
518
+ public setPreferLiveVideo(preferLiveVideo: boolean) {
519
+ LoggerProxy.logger.log(
520
+ `RemoteMediaManager#setPreferLiveVideo --> setPreferLiveVideo is called to set preferLiveVideo to ${preferLiveVideo}`
521
+ );
522
+ this.config.video.preferLiveVideo = preferLiveVideo;
523
+ Object.values(this.media.video.activeSpeakerGroups).forEach((activeSpeakerGroup) => {
524
+ activeSpeakerGroup.setPreferLiveVideo(preferLiveVideo, false);
525
+ });
526
+ this.mediaRequestManagers.video.commit();
527
+ }
528
+
529
+ /**
530
+ * Sets CSIs for multiple RemoteMedia instances belonging to RemoteMediaGroup.
531
+ * For each entry in the remoteMediaCsis array:
532
+ * - if csi is specified, the RemoteMedia instance is pinned to that CSI
533
+ * - if csi is undefined, the RemoteMedia instance is unpinned
534
+ */
535
+ public setActiveSpeakerCsis(remoteMediaCsis: {remoteMedia: RemoteMedia; csi?: number}[]) {
536
+ Object.values(this.media.video.activeSpeakerGroups).forEach((remoteMediaGroup) => {
537
+ const groupRemoteMediaCsis = remoteMediaCsis.filter(({remoteMedia}) =>
538
+ remoteMediaGroup.includes(remoteMedia)
539
+ );
540
+ if (groupRemoteMediaCsis.length > 0) {
541
+ remoteMediaGroup.setActiveSpeakerCsis(groupRemoteMediaCsis, false);
542
+ }
543
+ });
544
+ this.mediaRequestManagers.video.commit();
545
+ }
546
+
547
+ /**
548
+ * Sets which named media group need receiving
549
+ * @param {MediaType} mediaType of the stream
550
+ * @param {number} languageCode of the stream. If the languageId is 0, the named media group request will be canceled,
551
+ * and only receive the main audio stream.
552
+ * @returns {void}
553
+ */
554
+ public async setReceiveNamedMediaGroup(mediaType: MediaType, languageId: number) {
555
+ if (mediaType !== MediaType.AudioMain) {
556
+ throw new Error(`cannot set receive named media group which media type is ${mediaType}`);
557
+ }
558
+
559
+ const value = languageId;
560
+ if (value === this.config.namedMediaGroup?.value) {
561
+ return;
562
+ }
563
+
564
+ this.config.namedMediaGroup = {
565
+ type: NAMED_MEDIA_GROUP_TYPE_AUDIO,
566
+ value,
567
+ };
568
+
569
+ if (!this.media.audio.si) {
570
+ await this.createInterpretationAudioMedia(true);
571
+ } else {
572
+ this.media.audio.si.setNamedMediaGroup(this.config.namedMediaGroup, true);
573
+ }
574
+ }
575
+
493
576
  /**
494
577
  * Creates the audio slots
495
578
  */
496
579
  private async createAudioMedia() {
497
- // create the audio receive slots
580
+ // create si audio request
581
+ await this.createInterpretationAudioMedia(false);
582
+
583
+ // create main audio receive slots
498
584
  for (let i = 0; i < this.config.audio.numOfActiveSpeakerStreams; i += 1) {
499
585
  // eslint-disable-next-line no-await-in-loop
500
586
  const slot = await this.receiveSlotManager.allocateSlot(MediaType.AudioMain);
501
587
 
502
- this.slots.audio.push(slot);
588
+ this.slots.audio.main.push(slot);
503
589
  }
504
590
 
505
- // create a remote media group
506
- this.media.audio = new RemoteMediaGroup(
591
+ // create a remote media group for main audio
592
+ this.media.audio.main = new RemoteMediaGroup(
507
593
  this.mediaRequestManagers.audio,
508
- this.slots.audio,
594
+ this.slots.audio.main,
509
595
  255,
510
596
  true
511
597
  );
@@ -513,10 +599,40 @@ export class RemoteMediaManager extends EventsScope {
513
599
  this.emit(
514
600
  {file: 'multistream/remoteMediaManager', function: 'createAudioMedia'},
515
601
  Event.AudioCreated,
516
- this.media.audio
602
+ this.media.audio.main
517
603
  );
518
604
  }
519
605
 
606
+ /**
607
+ * Creates the audio slots for named media
608
+ */
609
+ private async createInterpretationAudioMedia(commitRequest: boolean) {
610
+ // create slot for interpretation language audio
611
+ if (
612
+ this.config.namedMediaGroup?.type === NAMED_MEDIA_GROUP_TYPE_AUDIO &&
613
+ this.config.namedMediaGroup?.value
614
+ ) {
615
+ this.slots.audio.si = await this.receiveSlotManager.allocateSlot(MediaType.AudioMain);
616
+
617
+ // create a remote media group for si audio
618
+ this.media.audio.si = new RemoteMediaGroup(
619
+ this.mediaRequestManagers.audio,
620
+ [this.slots.audio.si],
621
+ 255,
622
+ commitRequest,
623
+ {
624
+ namedMediaGroup: this.config.namedMediaGroup,
625
+ }
626
+ );
627
+
628
+ this.emit(
629
+ {file: 'multistream/remoteMediaManager', function: 'createInterpretationAudioMedia'},
630
+ Event.InterpretationAudioCreated,
631
+ this.media.audio.si
632
+ );
633
+ }
634
+ }
635
+
520
636
  /**
521
637
  * Creates receive slots required for receiving screen share audio and video
522
638
  */
@@ -601,25 +717,37 @@ export class RemoteMediaManager extends EventsScope {
601
717
  }
602
718
 
603
719
  /**
604
- * Allocates receive slots to all video panes in the current selected layout
720
+ * Allocates receive slots to all active speaker video panes
721
+ * in the current selected layout.
722
+ *
723
+ * Allocation tries to keep the same order of the slots between the previous
724
+ * layout and the new one. Sorting helps making sure that highest priority slots
725
+ * go in the same order in the new layout.
605
726
  */
606
- private allocateSlotsToVideoPaneGroups() {
607
- this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};
608
-
609
- this.currentLayout?.activeSpeakerVideoPaneGroups?.forEach((group) => {
610
- this.receiveSlotAllocations.activeSpeaker[group.id] = {slots: []};
611
-
612
- for (let paneIndex = 0; paneIndex < group.numPanes; paneIndex += 1) {
613
- // allocate a slot from the "unused" list
614
- const freeSlot = this.slots.video.unused.pop();
615
-
616
- if (freeSlot) {
617
- this.slots.video.activeSpeaker.push(freeSlot);
618
- this.receiveSlotAllocations.activeSpeaker[group.id].slots.push(freeSlot);
727
+ private allocateSlotsToActiveSpeakerPaneGroups() {
728
+ this.currentLayout?.activeSpeakerVideoPaneGroups
729
+ // sorting in descending order based on group priority
730
+ ?.sort((a, b) => (a.priority < b.priority ? 1 : -1))
731
+ ?.forEach((group) => {
732
+ this.receiveSlotAllocations.activeSpeaker[group.id] = {slots: []};
733
+
734
+ for (let paneIndex = 0; paneIndex < group.numPanes; paneIndex += 1) {
735
+ // allocate a slot from the "unused" list, by grabbing in same order (shift) as previous layout
736
+ const freeSlot = this.slots.video.unused.shift();
737
+
738
+ if (freeSlot) {
739
+ this.slots.video.activeSpeaker.push(freeSlot);
740
+ this.receiveSlotAllocations.activeSpeaker[group.id].slots.push(freeSlot);
741
+ }
619
742
  }
620
- }
621
- });
743
+ });
744
+ }
622
745
 
746
+ /**
747
+ * Allocates receive slots to all receiver selected video panes
748
+ * in the current selected layout
749
+ */
750
+ private allocateSlotsToReceiverSelectedVideoPaneGroups() {
623
751
  this.currentLayout?.memberVideoPanes?.forEach((memberPane) => {
624
752
  // check if there is existing slot for this csi
625
753
  const existingSlot = this.slots.video.receiverSelected.find(
@@ -646,19 +774,15 @@ export class RemoteMediaManager extends EventsScope {
646
774
  }
647
775
 
648
776
  /**
649
- * Makes sure we have the right number of receive slots created for the current layout
650
- * and allocates them to the right video panes / pane groups
651
- *
652
- * @returns {Promise}
777
+ * Ensures that we have enough slots for the current layout.
653
778
  */
654
- private async updateVideoReceiveSlots() {
779
+ private async refillRequiredSlotsIfNeeded() {
655
780
  const requiredNumSlots = this.getRequiredNumVideoSlotsForLayout(this.currentLayout);
656
781
  const totalNumSlots =
657
782
  this.slots.video.unused.length +
658
783
  this.slots.video.activeSpeaker.length +
659
784
  this.slots.video.receiverSelected.length;
660
785
 
661
- // ensure we have enough total slots for current layout
662
786
  if (totalNumSlots < requiredNumSlots) {
663
787
  let numSlotsToCreate = requiredNumSlots - totalNumSlots;
664
788
 
@@ -671,20 +795,95 @@ export class RemoteMediaManager extends EventsScope {
671
795
  numSlotsToCreate -= 1;
672
796
  }
673
797
  }
798
+ }
674
799
 
675
- // move all no longer needed receiver-selected slots to "unused"
676
- this.trimReceiverSelectedSlots();
677
-
678
- // move all active speaker slots to "unused"
800
+ /**
801
+ * Move all active speaker slots to "unused"
802
+ */
803
+ private trimActiveSpeakerSlots() {
679
804
  this.slots.video.unused.push(...this.slots.video.activeSpeaker);
680
805
  this.slots.video.activeSpeaker.length = 0;
806
+ }
681
807
 
682
- // allocate the slots to the right panes / pane groups
683
- this.allocateSlotsToVideoPaneGroups();
808
+ /**
809
+ * Logs the state of the receive slots
810
+ */
811
+ private logMainVideoReceiveSlots() {
812
+ let logMessage = '';
813
+ forEach(this.receiveSlotAllocations.activeSpeaker, (group, groupName) => {
814
+ logMessage += `\ngroup: ${groupName}\n${group.slots
815
+ .map((slot) => slot.logString)
816
+ .join(', ')}`;
817
+ });
818
+
819
+ logMessage += '\nreceiverSelected:\n';
820
+ forEach(this.receiveSlotAllocations.receiverSelected, (slot, key) => {
821
+ logMessage += ` ${key}: ${slot.logString}\n`;
822
+ });
823
+
824
+ LoggerProxy.logger.log(
825
+ `RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: unused=${this.slots.video.unused.length}, activeSpeaker=${this.slots.video.activeSpeaker.length}, receiverSelected=${this.slots.video.receiverSelected.length}${logMessage}`
826
+ );
827
+ }
828
+
829
+ /** logs main audio slots */
830
+ private logMainAudioReceiveSlots() {
831
+ LoggerProxy.logger.log(
832
+ `RemoteMediaManager#logMainAudioReceiveSlots --> MAIN AUDIO receive slots: ${this.slots.audio.main
833
+ .map((slot) => slot.logString)
834
+ .join(', ')}`
835
+ );
836
+ }
837
+
838
+ /** logs slides video slots */
839
+ private logSlidesVideoReceiveSlots() {
840
+ LoggerProxy.logger.log(
841
+ `RemoteMediaManager#logSlidesVideoReceiveSlots --> SLIDES VIDEO receive slot: ${this.slots.screenShare.video?.logString}`
842
+ );
843
+ }
684
844
 
845
+ /** logs slides audio slots */
846
+ private logSlidesAudioReceiveSlots() {
685
847
  LoggerProxy.logger.log(
686
- `RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=${this.slots.video.unused.length}, activeSpeaker=${this.slots.video.activeSpeaker.length}, receiverSelected=${this.slots.video.receiverSelected.length}`
848
+ `RemoteMediaManager#logSlidesAudioReceiveSlots --> SLIDES AUDIO receive slots: ${this.slots.screenShare.audio
849
+ .map((slot) => slot.logString)
850
+ .join(', ')}`
687
851
  );
852
+ }
853
+
854
+ /** Logs all current receive slots */
855
+ public logAllReceiveSlots() {
856
+ this.logMainVideoReceiveSlots();
857
+ this.logMainAudioReceiveSlots();
858
+ this.logSlidesVideoReceiveSlots();
859
+ this.logSlidesAudioReceiveSlots();
860
+ }
861
+
862
+ /**
863
+ * Makes sure we have the right number of receive slots created for the current layout
864
+ * and allocates them to the right video panes / pane groups
865
+ *
866
+ * @returns {Promise}
867
+ */
868
+ private async updateVideoReceiveSlots() {
869
+ // move all active speaker slots to "unused"
870
+ this.trimActiveSpeakerSlots();
871
+
872
+ // move all no longer needed receiver-selected slots to "unused"
873
+ this.trimReceiverSelectedSlots();
874
+
875
+ // ensure we have enough total slots for current layout
876
+ await this.refillRequiredSlotsIfNeeded();
877
+
878
+ // allocate the slots to the right panes / pane groups
879
+ // reset allocations
880
+ this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};
881
+ // allocate active speaker
882
+ this.allocateSlotsToActiveSpeakerPaneGroups();
883
+ // allocate receiver selected
884
+ this.allocateSlotsToReceiverSelectedVideoPaneGroups();
885
+
886
+ this.logMainVideoReceiveSlots();
688
887
 
689
888
  // If this is the initial layout, there may be some "unused" slots left because of the preallocation
690
889
  // done in this.preallocateVideoReceiveSlots(), so release them now
@@ -806,8 +1005,13 @@ export class RemoteMediaManager extends EventsScope {
806
1005
  }) {
807
1006
  const {audio, video, screenShareAudio, screenShareVideo, commit} = options;
808
1007
 
809
- if (audio && this.media.audio) {
810
- this.media.audio.stop(commit);
1008
+ if (audio) {
1009
+ if (this.media.audio.main) {
1010
+ this.media.audio.main.stop(commit);
1011
+ }
1012
+ if (this.media.audio.si) {
1013
+ this.media.audio.si.stop(commit);
1014
+ }
811
1015
  }
812
1016
  if (video) {
813
1017
  Object.values(this.media.video.activeSpeakerGroups).forEach((remoteMediaGroup) => {