@webex/plugin-meetings 3.0.0-beta.41 → 3.0.0-beta.411

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 (398) 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 +625 -123
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +27 -8
  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 +6 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +247 -34
  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 +116 -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 +4531 -2994
  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 +236 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +189 -155
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +676 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting/voicea-meeting.js +172 -0
  83. package/dist/meeting/voicea-meeting.js.map +1 -0
  84. package/dist/meeting-info/index.js +73 -7
  85. package/dist/meeting-info/index.js.map +1 -1
  86. package/dist/meeting-info/meeting-info-v2.js +201 -57
  87. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  88. package/dist/meeting-info/util.js +8 -7
  89. package/dist/meeting-info/util.js.map +1 -1
  90. package/dist/meeting-info/utilv2.js +44 -40
  91. package/dist/meeting-info/utilv2.js.map +1 -1
  92. package/dist/meetings/collection.js +39 -0
  93. package/dist/meetings/collection.js.map +1 -1
  94. package/dist/meetings/index.js +484 -119
  95. package/dist/meetings/index.js.map +1 -1
  96. package/dist/meetings/meetings.types.js +7 -0
  97. package/dist/meetings/meetings.types.js.map +1 -0
  98. package/dist/meetings/request.js +2 -0
  99. package/dist/meetings/request.js.map +1 -1
  100. package/dist/meetings/util.js +73 -7
  101. package/dist/meetings/util.js.map +1 -1
  102. package/dist/member/index.js +57 -0
  103. package/dist/member/index.js.map +1 -1
  104. package/dist/member/types.js +25 -0
  105. package/dist/member/types.js.map +1 -0
  106. package/dist/member/util.js +132 -25
  107. package/dist/member/util.js.map +1 -1
  108. package/dist/members/collection.js +10 -0
  109. package/dist/members/collection.js.map +1 -1
  110. package/dist/members/index.js +100 -5
  111. package/dist/members/index.js.map +1 -1
  112. package/dist/members/request.js +106 -38
  113. package/dist/members/request.js.map +1 -1
  114. package/dist/members/types.js +15 -0
  115. package/dist/members/types.js.map +1 -0
  116. package/dist/members/util.js +326 -232
  117. package/dist/members/util.js.map +1 -1
  118. package/dist/metrics/constants.js +18 -1
  119. package/dist/metrics/constants.js.map +1 -1
  120. package/dist/metrics/index.js +1 -446
  121. package/dist/metrics/index.js.map +1 -1
  122. package/dist/multistream/mediaRequestManager.js +223 -32
  123. package/dist/multistream/mediaRequestManager.js.map +1 -1
  124. package/dist/multistream/receiveSlot.js +10 -0
  125. package/dist/multistream/receiveSlot.js.map +1 -1
  126. package/dist/multistream/receiveSlotManager.js +39 -36
  127. package/dist/multistream/receiveSlotManager.js.map +1 -1
  128. package/dist/multistream/remoteMedia.js +3 -1
  129. package/dist/multistream/remoteMedia.js.map +1 -1
  130. package/dist/multistream/remoteMediaGroup.js +76 -5
  131. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  132. package/dist/multistream/remoteMediaManager.js +366 -104
  133. package/dist/multistream/remoteMediaManager.js.map +1 -1
  134. package/dist/multistream/sendSlotManager.js +255 -0
  135. package/dist/multistream/sendSlotManager.js.map +1 -0
  136. package/dist/reachability/clusterReachability.js +356 -0
  137. package/dist/reachability/clusterReachability.js.map +1 -0
  138. package/dist/reachability/index.js +263 -390
  139. package/dist/reachability/index.js.map +1 -1
  140. package/dist/reachability/request.js +6 -4
  141. package/dist/reachability/request.js.map +1 -1
  142. package/dist/reachability/util.js +29 -0
  143. package/dist/reachability/util.js.map +1 -0
  144. package/dist/reconnection-manager/index.js +266 -202
  145. package/dist/reconnection-manager/index.js.map +1 -1
  146. package/dist/recording-controller/index.js +21 -2
  147. package/dist/recording-controller/index.js.map +1 -1
  148. package/dist/recording-controller/util.js +9 -8
  149. package/dist/recording-controller/util.js.map +1 -1
  150. package/dist/roap/index.js +66 -28
  151. package/dist/roap/index.js.map +1 -1
  152. package/dist/roap/request.js +48 -64
  153. package/dist/roap/request.js.map +1 -1
  154. package/dist/roap/turnDiscovery.js +407 -79
  155. package/dist/roap/turnDiscovery.js.map +1 -1
  156. package/dist/rtcMetrics/constants.js +12 -0
  157. package/dist/rtcMetrics/constants.js.map +1 -0
  158. package/dist/rtcMetrics/index.js +179 -0
  159. package/dist/rtcMetrics/index.js.map +1 -0
  160. package/dist/statsAnalyzer/index.js +389 -304
  161. package/dist/statsAnalyzer/index.js.map +1 -1
  162. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  163. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  164. package/dist/types/annotation/annotation.types.d.ts +42 -0
  165. package/dist/types/annotation/constants.d.ts +31 -0
  166. package/dist/types/annotation/index.d.ts +117 -0
  167. package/dist/types/breakouts/events.d.ts +8 -0
  168. package/dist/types/breakouts/utils.d.ts +9 -2
  169. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  170. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  171. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  172. package/dist/types/common/logs/request.d.ts +2 -0
  173. package/dist/types/common/queue.d.ts +9 -7
  174. package/dist/types/config.d.ts +2 -7
  175. package/dist/types/constants.d.ts +204 -32
  176. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  177. package/dist/types/controls-options-manager/index.d.ts +17 -1
  178. package/dist/types/controls-options-manager/types.d.ts +43 -0
  179. package/dist/types/controls-options-manager/util.d.ts +1 -7
  180. package/dist/types/index.d.ts +6 -5
  181. package/dist/types/interceptors/index.d.ts +2 -0
  182. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  183. package/dist/types/interpretation/collection.d.ts +5 -0
  184. package/dist/types/interpretation/index.d.ts +5 -0
  185. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  186. package/dist/types/locus-info/index.d.ts +57 -4
  187. package/dist/types/locus-info/parser.d.ts +66 -6
  188. package/dist/types/media/index.d.ts +2 -0
  189. package/dist/types/media/properties.d.ts +34 -49
  190. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  191. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  192. package/dist/types/meeting/index.d.ts +630 -505
  193. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  194. package/dist/types/meeting/muteState.d.ts +88 -26
  195. package/dist/types/meeting/request.d.ts +67 -43
  196. package/dist/types/meeting/util.d.ts +117 -1
  197. package/dist/types/meeting/voicea-meeting.d.ts +16 -0
  198. package/dist/types/meeting-info/index.d.ts +13 -1
  199. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  200. package/dist/types/meetings/collection.d.ts +17 -0
  201. package/dist/types/meetings/index.d.ts +113 -21
  202. package/dist/types/meetings/meetings.types.d.ts +4 -0
  203. package/dist/types/member/index.d.ts +14 -0
  204. package/dist/types/member/types.d.ts +32 -0
  205. package/dist/types/members/collection.d.ts +5 -0
  206. package/dist/types/members/index.d.ts +35 -2
  207. package/dist/types/members/request.d.ts +73 -9
  208. package/dist/types/members/types.d.ts +25 -0
  209. package/dist/types/members/util.d.ts +214 -1
  210. package/dist/types/metrics/constants.d.ts +17 -0
  211. package/dist/types/metrics/index.d.ts +4 -111
  212. package/dist/types/multistream/mediaRequestManager.d.ts +71 -3
  213. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  214. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  215. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  216. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  217. package/dist/types/multistream/remoteMediaManager.d.ts +61 -2
  218. package/dist/types/multistream/sendSlotManager.d.ts +69 -0
  219. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  220. package/dist/types/reachability/index.d.ts +60 -95
  221. package/dist/types/reachability/request.d.ts +3 -1
  222. package/dist/types/reachability/util.d.ts +8 -0
  223. package/dist/types/reconnection-manager/index.d.ts +19 -0
  224. package/dist/types/recording-controller/index.d.ts +15 -1
  225. package/dist/types/recording-controller/util.d.ts +5 -4
  226. package/dist/types/roap/index.d.ts +11 -2
  227. package/dist/types/roap/request.d.ts +9 -8
  228. package/dist/types/roap/turnDiscovery.d.ts +90 -9
  229. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  230. package/dist/types/rtcMetrics/index.d.ts +61 -0
  231. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  232. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  233. package/dist/types/webinar/collection.d.ts +16 -0
  234. package/dist/types/webinar/index.d.ts +5 -0
  235. package/dist/webinar/collection.js +44 -0
  236. package/dist/webinar/collection.js.map +1 -0
  237. package/dist/webinar/index.js +69 -0
  238. package/dist/webinar/index.js.map +1 -0
  239. package/package.json +22 -19
  240. package/src/annotation/annotation.types.ts +50 -0
  241. package/src/annotation/constants.ts +36 -0
  242. package/src/annotation/index.ts +328 -0
  243. package/src/breakouts/README.md +27 -6
  244. package/src/breakouts/breakout.ts +67 -9
  245. package/src/breakouts/events.ts +56 -0
  246. package/src/breakouts/index.ts +494 -73
  247. package/src/breakouts/utils.ts +26 -8
  248. package/src/common/errors/no-meeting-info.ts +24 -0
  249. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  250. package/src/common/errors/webex-errors.ts +44 -2
  251. package/src/common/logs/logger-proxy.ts +1 -1
  252. package/src/common/logs/request.ts +5 -1
  253. package/src/common/queue.ts +22 -8
  254. package/src/config.ts +6 -13
  255. package/src/constants.ts +234 -22
  256. package/src/controls-options-manager/enums.ts +12 -0
  257. package/src/controls-options-manager/index.ts +116 -21
  258. package/src/controls-options-manager/types.ts +59 -0
  259. package/src/controls-options-manager/util.ts +294 -14
  260. package/src/index.ts +45 -0
  261. package/src/interceptors/index.ts +3 -0
  262. package/src/interceptors/locusRetry.ts +67 -0
  263. package/src/interpretation/README.md +60 -0
  264. package/src/interpretation/collection.ts +19 -0
  265. package/src/interpretation/index.ts +349 -0
  266. package/src/interpretation/siLanguage.ts +18 -0
  267. package/src/locus-info/controlsUtils.ts +108 -0
  268. package/src/locus-info/index.ts +417 -59
  269. package/src/locus-info/infoUtils.ts +10 -2
  270. package/src/locus-info/mediaSharesUtils.ts +80 -0
  271. package/src/locus-info/parser.ts +258 -47
  272. package/src/locus-info/selfUtils.ts +81 -5
  273. package/src/media/index.ts +100 -108
  274. package/src/media/properties.ts +88 -117
  275. package/src/mediaQualityMetrics/config.ts +103 -238
  276. package/src/meeting/in-meeting-actions.ts +171 -3
  277. package/src/meeting/index.ts +3929 -2622
  278. package/src/meeting/locusMediaRequest.ts +313 -0
  279. package/src/meeting/muteState.ts +237 -136
  280. package/src/meeting/request.ts +173 -122
  281. package/src/meeting/util.ts +690 -395
  282. package/src/meeting/voicea-meeting.ts +122 -0
  283. package/src/meeting-info/index.ts +81 -8
  284. package/src/meeting-info/meeting-info-v2.ts +166 -16
  285. package/src/meeting-info/util.ts +13 -10
  286. package/src/meeting-info/utilv2.ts +47 -37
  287. package/src/meetings/collection.ts +33 -0
  288. package/src/meetings/index.ts +507 -127
  289. package/src/meetings/meetings.types.ts +12 -0
  290. package/src/meetings/request.ts +2 -0
  291. package/src/meetings/util.ts +81 -12
  292. package/src/member/index.ts +57 -0
  293. package/src/member/types.ts +38 -0
  294. package/src/member/util.ts +141 -25
  295. package/src/members/collection.ts +8 -0
  296. package/src/members/index.ts +133 -7
  297. package/src/members/request.ts +97 -17
  298. package/src/members/types.ts +29 -0
  299. package/src/members/util.ts +333 -240
  300. package/src/metrics/constants.ts +17 -0
  301. package/src/metrics/index.ts +1 -469
  302. package/src/multistream/mediaRequestManager.ts +271 -56
  303. package/src/multistream/receiveSlot.ts +11 -4
  304. package/src/multistream/receiveSlotManager.ts +34 -24
  305. package/src/multistream/remoteMedia.ts +5 -3
  306. package/src/multistream/remoteMediaGroup.ts +78 -0
  307. package/src/multistream/remoteMediaManager.ts +248 -45
  308. package/src/multistream/sendSlotManager.ts +198 -0
  309. package/src/reachability/clusterReachability.ts +320 -0
  310. package/src/reachability/index.ts +229 -346
  311. package/src/reachability/request.ts +8 -4
  312. package/src/reachability/util.ts +24 -0
  313. package/src/reconnection-manager/index.ts +128 -97
  314. package/src/recording-controller/index.ts +20 -3
  315. package/src/recording-controller/util.ts +26 -9
  316. package/src/roap/index.ts +76 -25
  317. package/src/roap/request.ts +48 -67
  318. package/src/roap/turnDiscovery.ts +331 -67
  319. package/src/rtcMetrics/constants.ts +3 -0
  320. package/src/rtcMetrics/index.ts +166 -0
  321. package/src/statsAnalyzer/index.ts +496 -419
  322. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  323. package/src/webinar/collection.ts +31 -0
  324. package/src/webinar/index.ts +62 -0
  325. package/test/integration/spec/converged-space-meetings.js +60 -3
  326. package/test/integration/spec/journey.js +321 -262
  327. package/test/integration/spec/space-meeting.js +76 -3
  328. package/test/unit/spec/annotation/index.ts +418 -0
  329. package/test/unit/spec/breakouts/breakout.ts +119 -28
  330. package/test/unit/spec/breakouts/events.ts +89 -0
  331. package/test/unit/spec/breakouts/index.ts +1204 -118
  332. package/test/unit/spec/breakouts/utils.js +27 -2
  333. package/test/unit/spec/common/queue.js +31 -2
  334. package/test/unit/spec/controls-options-manager/index.js +163 -0
  335. package/test/unit/spec/controls-options-manager/util.js +576 -60
  336. package/test/unit/spec/fixture/locus.js +1 -0
  337. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  338. package/test/unit/spec/interpretation/collection.ts +15 -0
  339. package/test/unit/spec/interpretation/index.ts +625 -0
  340. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  341. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  342. package/test/unit/spec/locus-info/index.js +1372 -37
  343. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  344. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  345. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  346. package/test/unit/spec/locus-info/parser.js +116 -35
  347. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  348. package/test/unit/spec/locus-info/selfUtils.js +203 -17
  349. package/test/unit/spec/media/index.ts +178 -81
  350. package/test/unit/spec/media/properties.ts +2 -2
  351. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  352. package/test/unit/spec/meeting/index.js +7835 -2501
  353. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  354. package/test/unit/spec/meeting/muteState.js +549 -207
  355. package/test/unit/spec/meeting/request.js +494 -54
  356. package/test/unit/spec/meeting/utils.js +827 -74
  357. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  358. package/test/unit/spec/meeting-info/index.js +300 -0
  359. package/test/unit/spec/meeting-info/meetinginfov2.js +535 -9
  360. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  361. package/test/unit/spec/meetings/collection.js +26 -0
  362. package/test/unit/spec/meetings/index.js +1489 -219
  363. package/test/unit/spec/meetings/utils.js +229 -2
  364. package/test/unit/spec/member/index.js +61 -6
  365. package/test/unit/spec/member/util.js +510 -34
  366. package/test/unit/spec/members/index.js +432 -1
  367. package/test/unit/spec/members/request.js +206 -27
  368. package/test/unit/spec/members/utils.js +210 -0
  369. package/test/unit/spec/metrics/index.js +2 -52
  370. package/test/unit/spec/multistream/mediaRequestManager.ts +782 -114
  371. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  372. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  373. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  374. package/test/unit/spec/multistream/remoteMediaGroup.ts +344 -0
  375. package/test/unit/spec/multistream/remoteMediaManager.ts +524 -0
  376. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  377. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  378. package/test/unit/spec/reachability/index.ts +551 -14
  379. package/test/unit/spec/reachability/request.js +3 -1
  380. package/test/unit/spec/reachability/util.ts +40 -0
  381. package/test/unit/spec/reconnection-manager/index.js +171 -11
  382. package/test/unit/spec/recording-controller/index.js +293 -218
  383. package/test/unit/spec/recording-controller/util.js +223 -96
  384. package/test/unit/spec/roap/index.ts +233 -81
  385. package/test/unit/spec/roap/request.ts +100 -62
  386. package/test/unit/spec/roap/turnDiscovery.ts +682 -108
  387. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  388. package/test/unit/spec/stats-analyzer/index.js +1431 -12
  389. package/test/unit/spec/webinar/collection.ts +13 -0
  390. package/test/unit/spec/webinar/index.ts +60 -0
  391. package/test/utils/integrationTestUtils.js +46 -0
  392. package/test/utils/testUtils.js +0 -57
  393. package/test/utils/webex-test-users.js +12 -4
  394. package/dist/metrics/config.js +0 -289
  395. package/dist/metrics/config.js.map +0 -1
  396. package/dist/types/metrics/config.d.ts +0 -169
  397. package/src/index.js +0 -18
  398. package/src/metrics/config.ts +0 -485
@@ -1,123 +1,203 @@
1
+ import {ServerMuteReason} from '@webex/media-helpers';
1
2
  import LoggerProxy from '../common/logs/logger-proxy';
2
3
  import ParameterError from '../common/errors/parameter';
3
- import PermissionError from '../common/errors/permission';
4
4
  import MeetingUtil from './util';
5
5
  import {AUDIO, VIDEO} from '../constants';
6
6
 
7
- /* Certain aspects of server interaction for video muting are not implemented as we currently don't support remote muting of video.
8
- If we ever need to support it, search for REMOTE_MUTE_VIDEO_MISSING_IMPLEMENTATION string to find the places that need updating
9
- */
10
-
11
7
  // eslint-disable-next-line import/prefer-default-export
12
- export const createMuteState = (type, meeting, mediaDirection) => {
13
- if (type === AUDIO && !mediaDirection.sendAudio) {
14
- return null;
15
- }
16
- if (type === VIDEO && !mediaDirection.sendVideo) {
17
- return null;
18
- }
8
+ export const createMuteState = (type, meeting, enabled: boolean) => {
9
+ // todo: remove the meeting argument (SPARK-399695)
19
10
 
20
11
  LoggerProxy.logger.info(
21
12
  `Meeting:muteState#createMuteState --> ${type}: creating MuteState for meeting id ${meeting?.id}`
22
13
  );
23
14
 
24
- return new MuteState(type, meeting);
15
+ const muteState = new MuteState(type, meeting, enabled);
16
+
17
+ return muteState;
25
18
  };
26
19
 
27
20
  /** The purpose of this class is to manage the local and remote mute state and make sure that the server state always matches
28
21
  the last requested state by the client.
29
22
 
30
23
  More info about Locus muting API: https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html#
24
+
25
+ This class is exported only for unit tests. It should never be instantiated directly with new MuteState(), instead createMuteState() should be called
31
26
  */
32
- class MuteState {
33
- pendingPromiseReject: any;
34
- pendingPromiseResolve: any;
35
- state: any;
27
+ export class MuteState {
28
+ state: {
29
+ client: {
30
+ enabled: boolean; // indicates if audio/video is enabled at all or not
31
+ localMute: boolean;
32
+ };
33
+ server: {localMute: boolean; remoteMute: boolean; unmuteAllowed: boolean};
34
+ syncToServerInProgress: boolean;
35
+ };
36
+
36
37
  type: any;
38
+ ignoreMuteStateChange: boolean;
37
39
 
38
40
  /**
39
41
  * Constructor
40
42
  *
41
43
  * @param {String} type - audio or video
42
44
  * @param {Object} meeting - the meeting object (used for reading current remote mute status)
45
+ * @param {boolean} enabled - whether the client audio/video is enabled at all
43
46
  */
44
- constructor(type: string, meeting: any) {
47
+ constructor(type: string, meeting: any, enabled: boolean) {
45
48
  if (type !== AUDIO && type !== VIDEO) {
46
49
  throw new ParameterError('Mute state is designed for handling audio or video only');
47
50
  }
48
51
  this.type = type;
52
+ this.ignoreMuteStateChange = false;
49
53
  this.state = {
50
54
  client: {
51
- localMute: false,
55
+ enabled,
56
+ localMute: true,
52
57
  },
53
58
  server: {
54
- localMute: false,
55
- // initial values available only for audio (REMOTE_MUTE_VIDEO_MISSING_IMPLEMENTATION)
56
- remoteMute: type === AUDIO ? meeting.remoteMuted : false,
57
- unmuteAllowed: type === AUDIO ? meeting.unmuteAllowed : true,
59
+ localMute: true,
60
+ // because remoteVideoMuted and unmuteVideoAllowed are updated seperately, they might be undefined
61
+ remoteMute: type === AUDIO ? meeting.remoteMuted : meeting.remoteVideoMuted ?? false,
62
+ unmuteAllowed: type === AUDIO ? meeting.unmuteAllowed : meeting.unmuteVideoAllowed ?? true,
58
63
  },
59
64
  syncToServerInProgress: false,
60
65
  };
61
- // these 2 hold the resolve, reject methods for the promise we returned to the client in last handleClientRequest() call
62
- this.pendingPromiseResolve = null;
63
- this.pendingPromiseReject = null;
64
66
  }
65
67
 
66
68
  /**
67
- * Handles mute/unmute request from the client/user. Returns a promise that's resolved once the server update is completed or
68
- * at the point that this request becomese superseded by another client request.
69
+ * Starts the mute state machine. Needs to be called after a new MuteState instance is created.
70
+ *
71
+ * @param {Object} meeting - the meeting object
72
+ * @returns {void}
73
+ */
74
+ public init(meeting: any) {
75
+ this.applyUnmuteAllowedToStream(meeting);
76
+
77
+ // if we are remotely muted, we need to apply that to the local stream now (mute on-entry)
78
+ if (this.state.server.remoteMute) {
79
+ this.muteLocalStream(meeting, this.state.server.remoteMute, 'remotelyMuted');
80
+ }
81
+
82
+ const initialMute =
83
+ this.type === AUDIO
84
+ ? meeting.mediaProperties.audioStream?.muted
85
+ : meeting.mediaProperties.videoStream?.muted;
86
+
87
+ LoggerProxy.logger.info(
88
+ `Meeting:muteState#init --> ${this.type}: local stream initial mute state: ${initialMute}`
89
+ );
90
+
91
+ if (initialMute !== undefined) {
92
+ this.state.client.localMute = initialMute;
93
+ } else {
94
+ // there is no stream, so it's like we are locally muted
95
+ // (this is important especially for transcoded meetings, in which the SDP m-line direction always stays "sendrecv")
96
+ this.state.client.localMute = true;
97
+ }
98
+ this.applyClientStateToServer(meeting);
99
+ }
100
+
101
+ /**
102
+ * This method needs to be called whenever the local audio/video stream has changed.
103
+ * It reapplies the remote mute state onto the new stream and also reads the current
104
+ * local mute state from the stream and updates the internal state machine and sends
105
+ * any required requests to the server.
106
+ *
107
+ * @param {Object} meeting - the meeting object
108
+ * @returns {void}
109
+ */
110
+ public handleLocalStreamChange(meeting: any) {
111
+ return this.init(meeting);
112
+ }
113
+
114
+ /**
115
+ * Enables/disables audio/video
69
116
  *
70
- * The client doesn't have to wait for the returned promise to resolve before calling handleClientRequest() again. If
71
- * handleClientRequest() is called again before the previous one resolved, the MuteState class will make sure that eventually
72
- * the server state will match the last requested state from the client.
117
+ * @param {Object} meeting - the meeting object
118
+ * @param {boolean} enable
119
+ * @returns {void}
120
+ */
121
+ public enable(meeting: any, enable: boolean) {
122
+ this.state.client.enabled = enable;
123
+
124
+ this.applyClientStateToServer(meeting);
125
+ }
126
+
127
+ /**
128
+ * Mutes/unmutes local stream
73
129
  *
130
+ * @param {Object} meeting - the meeting object
131
+ * @param {Boolean} mute - true to mute the stream, false to unmute it
132
+ * @param {ServerMuteReason} reason - reason for muting/unmuting
133
+ * @returns {void}
134
+ */
135
+ private muteLocalStream(meeting: any, mute: boolean, reason: ServerMuteReason) {
136
+ this.ignoreMuteStateChange = true;
137
+ if (this.type === AUDIO) {
138
+ meeting.mediaProperties.audioStream?.setServerMuted(mute, reason);
139
+ } else {
140
+ meeting.mediaProperties.videoStream?.setServerMuted(mute, reason);
141
+ }
142
+ this.ignoreMuteStateChange = false;
143
+ }
144
+
145
+ /**
146
+ * This method should be called when the local stream mute state is changed
74
147
  * @public
75
148
  * @memberof MuteState
76
149
  * @param {Object} [meeting] the meeting object
77
150
  * @param {Boolean} [mute] true for muting, false for unmuting request
78
- * @returns {Promise}
151
+ * @returns {void}
79
152
  */
80
- public handleClientRequest(meeting?: object, mute?: boolean) {
153
+ public handleLocalStreamMuteStateChange(meeting?: any) {
154
+ if (this.ignoreMuteStateChange) {
155
+ return;
156
+ }
157
+
158
+ // either user or system may have triggered a mute state change, but localMute should reflect both
159
+ let newMuteState: boolean;
160
+ let userMuteState: boolean;
161
+ let systemMuteState: boolean;
162
+ if (this.type === AUDIO) {
163
+ newMuteState = meeting.mediaProperties.audioStream?.muted;
164
+ userMuteState = meeting.mediaProperties.audioStream?.userMuted;
165
+ systemMuteState = meeting.mediaProperties.audioStream?.systemMuted;
166
+ } else {
167
+ newMuteState = meeting.mediaProperties.videoStream?.muted;
168
+ userMuteState = meeting.mediaProperties.videoStream?.userMuted;
169
+ systemMuteState = meeting.mediaProperties.videoStream?.systemMuted;
170
+ }
171
+
81
172
  LoggerProxy.logger.info(
82
- `Meeting:muteState#handleClientRequest --> ${this.type}: user requesting new mute state: ${mute}`
173
+ `Meeting:muteState#handleLocalStreamMuteStateChange --> ${this.type}: local stream new mute state: ${newMuteState} (user mute: ${userMuteState}, system mute: ${systemMuteState})`
83
174
  );
84
175
 
85
- if (!mute && !this.state.server.unmuteAllowed) {
86
- return Promise.reject(
87
- new PermissionError('User is not allowed to unmute self (hard mute feature is being used)')
88
- );
89
- }
176
+ this.state.client.localMute = newMuteState;
90
177
 
91
- // we don't check if we're already in the same state, because even if we were, we would still have to apply the mute state locally,
92
- // because the client may have changed the audio/vidoe tracks
93
- this.state.client.localMute = mute;
94
- this.applyClientStateLocally(meeting);
95
-
96
- return new Promise((resolve, reject) => {
97
- if (this.pendingPromiseResolve) {
98
- // resolve the last promise we returned to the client as the client has issued a new request that has superseded the previous one
99
- this.pendingPromiseResolve();
100
- }
101
- this.pendingPromiseResolve = resolve;
102
- this.pendingPromiseReject = reject;
103
- this.applyClientStateToServer(meeting);
104
- });
178
+ this.applyClientStateToServer(meeting);
105
179
  }
106
180
 
107
181
  /**
108
- * Applies the current mute state to the local track (by enabling or disabling it accordingly)
182
+ * Applies the current mute state to the local stream (by enabling or disabling it accordingly)
109
183
  *
110
184
  * @public
111
185
  * @param {Object} [meeting] the meeting object
186
+ * @param {ServerMuteReason} reason - reason why we're applying our client state to the local stream
112
187
  * @memberof MuteState
113
188
  * @returns {void}
114
189
  */
115
- public applyClientStateLocally(meeting?: any) {
116
- if (this.type === AUDIO) {
117
- meeting.mediaProperties.audioTrack?.setMuted(this.state.client.localMute);
118
- } else {
119
- meeting.mediaProperties.videoTrack?.setMuted(this.state.client.localMute);
120
- }
190
+ public applyClientStateLocally(meeting?: any, reason?: ServerMuteReason) {
191
+ this.muteLocalStream(meeting, this.state.client.localMute, reason);
192
+ }
193
+
194
+ /** Returns true if client is locally muted - it takes into account not just the client local mute state,
195
+ * but also whether audio/video is enabled at all
196
+ *
197
+ * @returns {boolean}
198
+ */
199
+ private getClientLocalMuteState() {
200
+ return this.state.client.enabled ? this.state.client.localMute : true;
121
201
  }
122
202
 
123
203
  /**
@@ -128,7 +208,7 @@ class MuteState {
128
208
  * @memberof MuteState
129
209
  * @returns {void}
130
210
  */
131
- private applyClientStateToServer(meeting?: object) {
211
+ private applyClientStateToServer(meeting?: any) {
132
212
  if (this.state.syncToServerInProgress) {
133
213
  LoggerProxy.logger.info(
134
214
  `Meeting:muteState#applyClientStateToServer --> ${this.type}: request to server in progress, we need to wait for it to complete`
@@ -137,11 +217,12 @@ class MuteState {
137
217
  return;
138
218
  }
139
219
 
140
- const localMuteRequiresSync = this.state.client.localMute !== this.state.server.localMute;
141
- const remoteMuteRequiresSync = !this.state.client.localMute && this.state.server.remoteMute;
220
+ const localMuteState = this.getClientLocalMuteState();
221
+ const localMuteRequiresSync = localMuteState !== this.state.server.localMute;
222
+ const remoteMuteRequiresSync = !localMuteState && this.state.server.remoteMute;
142
223
 
143
224
  LoggerProxy.logger.info(
144
- `Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${this.state.client.localMute} ?= ${this.state.server.localMute})`
225
+ `Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${localMuteState} ?= ${this.state.server.localMute})`
145
226
  );
146
227
  LoggerProxy.logger.info(
147
228
  `Meeting:muteState#applyClientStateToServer --> ${this.type}: remoteMuteRequiresSync: ${remoteMuteRequiresSync}`
@@ -152,12 +233,6 @@ class MuteState {
152
233
  `Meeting:muteState#applyClientStateToServer --> ${this.type}: client state already matching server state, nothing to do`
153
234
  );
154
235
 
155
- if (this.pendingPromiseResolve) {
156
- this.pendingPromiseResolve();
157
- }
158
- this.pendingPromiseResolve = null;
159
- this.pendingPromiseReject = null;
160
-
161
236
  return;
162
237
  }
163
238
 
@@ -185,11 +260,16 @@ class MuteState {
185
260
  .catch((e) => {
186
261
  this.state.syncToServerInProgress = false;
187
262
 
188
- if (this.pendingPromiseReject) {
189
- this.pendingPromiseReject(e);
190
- }
191
- this.pendingPromiseResolve = null;
192
- this.pendingPromiseReject = null;
263
+ LoggerProxy.logger.warn(
264
+ `Meeting:muteState#applyClientStateToServer --> ${this.type}: error: ${e}`
265
+ );
266
+
267
+ // failed to apply client state to server, so revert stream mute state to server state
268
+ this.muteLocalStream(
269
+ meeting,
270
+ this.state.server.localMute || this.state.server.remoteMute,
271
+ 'clientRequestFailed'
272
+ );
193
273
  });
194
274
  }
195
275
 
@@ -202,16 +282,14 @@ class MuteState {
202
282
  * @returns {Promise}
203
283
  */
204
284
  private sendLocalMuteRequestToServer(meeting?: any) {
205
- const audioMuted =
206
- this.type === AUDIO ? this.state.client.localMute : meeting.audio?.state.client.localMute;
207
- const videoMuted =
208
- this.type === VIDEO ? this.state.client.localMute : meeting.video?.state.client.localMute;
285
+ const audioMuted = this.type === AUDIO ? this.getClientLocalMuteState() : undefined;
286
+ const videoMuted = this.type === VIDEO ? this.getClientLocalMuteState() : undefined;
209
287
 
210
288
  LoggerProxy.logger.info(
211
289
  `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: sending local mute (audio=${audioMuted}, video=${videoMuted}) to server`
212
290
  );
213
291
 
214
- return MeetingUtil.remoteUpdateAudioVideo(audioMuted, videoMuted, meeting)
292
+ return MeetingUtil.remoteUpdateAudioVideo(meeting, audioMuted, videoMuted)
215
293
  .then((locus) => {
216
294
  LoggerProxy.logger.info(
217
295
  `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: local mute (audio=${audioMuted}, video=${videoMuted}) applied to server`
@@ -219,7 +297,9 @@ class MuteState {
219
297
 
220
298
  this.state.server.localMute = this.type === AUDIO ? audioMuted : videoMuted;
221
299
 
222
- meeting.locusInfo.onFullLocus(locus);
300
+ if (locus) {
301
+ meeting.locusInfo.handleLocusDelta(locus, meeting);
302
+ }
223
303
 
224
304
  return locus;
225
305
  })
@@ -241,35 +321,42 @@ class MuteState {
241
321
  * @returns {Promise}
242
322
  */
243
323
  private sendRemoteMuteRequestToServer(meeting?: any) {
244
- if (this.type === AUDIO) {
245
- const remoteMute = this.state.client.localMute;
324
+ const remoteMute = this.getClientLocalMuteState();
246
325
 
247
- LoggerProxy.logger.info(
248
- `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: sending remote mute:${remoteMute} to server`
249
- );
326
+ LoggerProxy.logger.info(
327
+ `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: sending remote mute:${remoteMute} to server`
328
+ );
250
329
 
251
- return meeting.members
252
- .muteMember(meeting.members.selfId, remoteMute)
253
- .then(() => {
254
- LoggerProxy.logger.info(
255
- `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: remote mute:${remoteMute} applied to server`
256
- );
257
-
258
- this.state.server.remoteMute = remoteMute;
259
- })
260
- .catch((remoteUpdateError) => {
261
- LoggerProxy.logger.warn(
262
- `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: failed to apply remote mute ${remoteMute} to server: ${remoteUpdateError}`
263
- );
264
-
265
- return Promise.reject(remoteUpdateError);
266
- });
267
- }
330
+ return meeting.members
331
+ .muteMember(meeting.members.selfId, remoteMute, this.type === AUDIO)
332
+ .then(() => {
333
+ LoggerProxy.logger.info(
334
+ `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: remote mute:${remoteMute} applied to server`
335
+ );
268
336
 
269
- // for now we don't need to support remote muting of video (REMOTE_MUTE_VIDEO_MISSING_IMPLEMENTATION)
270
- this.state.server.remoteMute = this.state.client.localMute;
337
+ this.state.server.remoteMute = remoteMute;
338
+ })
339
+ .catch((remoteUpdateError) => {
340
+ LoggerProxy.logger.warn(
341
+ `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: failed to apply remote mute ${remoteMute} to server: ${remoteUpdateError}`
342
+ );
343
+
344
+ return Promise.reject(remoteUpdateError);
345
+ });
346
+ }
271
347
 
272
- return Promise.resolve();
348
+ /** Applies the current value for unmute allowed to the underlying stream
349
+ *
350
+ * @param {Meeting} meeting
351
+ * @returns {void}
352
+ */
353
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
354
+ private applyUnmuteAllowedToStream(meeting: any) {
355
+ if (this.type === AUDIO) {
356
+ meeting.mediaProperties.audioStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);
357
+ } else {
358
+ meeting.mediaProperties.videoStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);
359
+ }
273
360
  }
274
361
 
275
362
  /**
@@ -277,16 +364,23 @@ class MuteState {
277
364
  *
278
365
  * @public
279
366
  * @memberof MuteState
367
+ * @param {Meeting} meeting
280
368
  * @param {Boolean} [muted] true if user is remotely muted, false otherwise
281
369
  * @param {Boolean} [unmuteAllowed] indicates if user is allowed to unmute self (false when "hard mute" feature is used)
282
370
  * @returns {undefined}
283
371
  */
284
- public handleServerRemoteMuteUpdate(muted?: boolean, unmuteAllowed?: boolean) {
372
+ public handleServerRemoteMuteUpdate(meeting: any, muted?: boolean, unmuteAllowed?: boolean) {
285
373
  LoggerProxy.logger.info(
286
374
  `Meeting:muteState#handleServerRemoteMuteUpdate --> ${this.type}: updating server remoteMute to (${muted})`
287
375
  );
288
- this.state.server.remoteMute = muted;
289
- this.state.server.unmuteAllowed = unmuteAllowed;
376
+ if (unmuteAllowed !== undefined) {
377
+ this.state.server.unmuteAllowed = unmuteAllowed;
378
+ this.applyUnmuteAllowedToStream(meeting);
379
+ }
380
+ if (muted !== undefined) {
381
+ this.state.server.remoteMute = muted;
382
+ this.muteLocalStream(meeting, muted, 'remotelyMuted');
383
+ }
290
384
  }
291
385
 
292
386
  /**
@@ -297,28 +391,34 @@ class MuteState {
297
391
  * @param {Object} [meeting] the meeting object
298
392
  * @returns {undefined}
299
393
  */
300
- public handleServerLocalUnmuteRequired(meeting?: object) {
301
- LoggerProxy.logger.info(
302
- `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
303
- );
394
+ public handleServerLocalUnmuteRequired(meeting?: any) {
395
+ if (!this.state.client.enabled) {
396
+ LoggerProxy.logger.warn(
397
+ `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`
398
+ );
399
+ } else {
400
+ LoggerProxy.logger.info(
401
+ `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
402
+ );
403
+ }
304
404
 
405
+ // todo: I'm seeing "you can now unmute yourself " popup when this happens - but same thing happens on web.w.c so we can ignore for now
305
406
  this.state.server.remoteMute = false;
306
- this.state.client.localMute = false;
307
407
 
308
- if (this.pendingPromiseReject) {
309
- this.pendingPromiseReject(
310
- new Error('Server requested local unmute - this overrides any client request in progress')
311
- );
312
- this.pendingPromiseResolve = null;
313
- this.pendingPromiseReject = null;
408
+ // change user mute state to false, but keep localMute true if overall mute state is still true
409
+ this.muteLocalStream(meeting, false, 'localUnmuteRequired');
410
+ if (this.type === AUDIO) {
411
+ this.state.client.localMute = meeting.mediaProperties.audioStream?.muted;
412
+ } else {
413
+ this.state.client.localMute = meeting.mediaProperties.videoStream?.muted;
314
414
  }
315
415
 
316
- this.applyClientStateLocally(meeting);
317
416
  this.applyClientStateToServer(meeting);
318
417
  }
319
418
 
320
419
  /**
321
- * Returns true if the user is locally or remotely muted
420
+ * Returns true if the user is locally or remotely muted.
421
+ * It only checks the mute status, ignoring the fact whether audio/video is enabled.
322
422
  *
323
423
  * @public
324
424
  * @memberof MuteState
@@ -331,34 +431,35 @@ class MuteState {
331
431
  }
332
432
 
333
433
  /**
334
- * Returns true if the user is locally muted
434
+ * Returns true if the user is remotely muted
335
435
  *
336
436
  * @public
337
437
  * @memberof MuteState
338
438
  * @returns {Boolean}
339
439
  */
340
- public isLocallyMuted() {
341
- return this.state.client.localMute || this.state.server.localMute;
440
+ public isRemotelyMuted() {
441
+ return this.state.server.remoteMute;
342
442
  }
343
443
 
344
444
  /**
345
- * Returns true if the user is muted as a result of the client request (and not remotely muted)
445
+ * Returns true if unmute is allowed
346
446
  *
347
447
  * @public
348
448
  * @memberof MuteState
349
449
  * @returns {Boolean}
350
450
  */
351
- public isSelf() {
352
- return this.state.client.localMute && !this.state.server.remoteMute;
353
- }
354
-
355
- // defined for backwards compatibility with the old AudioStateMachine/VideoStateMachine classes
356
- get muted() {
357
- return this.isMuted();
451
+ public isUnmuteAllowed() {
452
+ return this.state.server.unmuteAllowed;
358
453
  }
359
454
 
360
- // defined for backwards compatibility with the old AudioStateMachine/VideoStateMachine classes
361
- get self() {
362
- return this.isSelf();
455
+ /**
456
+ * Returns true if the user is locally muted or audio/video is disabled
457
+ *
458
+ * @public
459
+ * @memberof MuteState
460
+ * @returns {Boolean}
461
+ */
462
+ public isLocallyMuted() {
463
+ return this.getClientLocalMuteState();
363
464
  }
364
465
  }