@webex/plugin-meetings 3.0.0-beta.31 → 3.0.0-beta.310
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.
- package/README.md +46 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +709 -35
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -11
- package/dist/config.js.map +1 -1
- package/dist/constants.js +233 -29
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +112 -1
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +383 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +57 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +61 -116
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +82 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3777 -2929
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +230 -124
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +260 -196
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +601 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +415 -115
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +72 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +102 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +13 -5
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -468
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +238 -49
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +29 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +44 -18
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +209 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/index.js +225 -59
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +17 -8
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +201 -156
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +62 -32
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +112 -97
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +95 -36
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +86 -78
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +11 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +1 -7
- package/dist/types/constants.d.ts +194 -24
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -4
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +67 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -48
- package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
- package/dist/types/meeting/index.d.ts +463 -510
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +99 -23
- package/dist/types/meeting/request.d.ts +72 -43
- package/dist/types/meeting/util.d.ts +101 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +98 -20
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +12 -4
- package/dist/types/metrics/index.d.ts +4 -119
- package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
- package/dist/types/multistream/receiveSlot.d.ts +13 -11
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +8 -29
- package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
- package/dist/types/multistream/sendSlotManager.d.ts +61 -0
- package/dist/types/reachability/index.d.ts +61 -7
- package/dist/types/reachability/request.d.ts +7 -3
- package/dist/types/reconnection-manager/index.d.ts +9 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +15 -11
- package/dist/types/roap/turnDiscovery.d.ts +21 -3
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/index.d.ts +7 -1
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +23 -20
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +42 -12
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +592 -20
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -10
- package/src/constants.ts +221 -19
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +413 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +102 -122
- package/src/media/properties.ts +87 -110
- package/src/meeting/in-meeting-actions.ts +163 -3
- package/src/meeting/index.ts +3132 -2541
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +229 -131
- package/src/meeting/request.ts +177 -121
- package/src/meeting/util.ts +588 -394
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +445 -123
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +80 -11
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +12 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +289 -79
- package/src/multistream/receiveSlot.ts +31 -17
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +148 -30
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/index.ts +228 -37
- package/src/reachability/request.ts +17 -8
- package/src/reconnection-manager/index.ts +83 -56
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +63 -32
- package/src/roap/request.ts +100 -104
- package/src/roap/turnDiscovery.ts +48 -26
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/index.ts +105 -91
- package/src/statsAnalyzer/mqaUtil.ts +13 -14
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +118 -28
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1395 -69
- package/test/unit/spec/breakouts/utils.js +52 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1304 -33
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +104 -37
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
- package/test/unit/spec/meeting/index.js +5216 -1956
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +408 -208
- package/test/unit/spec/meeting/request.js +483 -49
- package/test/unit/spec/meeting/utils.js +679 -64
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1011 -205
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
- package/test/unit/spec/multistream/receiveSlot.ts +28 -20
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +30 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/index.ts +549 -9
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +85 -9
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +178 -64
- package/test/unit/spec/roap/request.ts +203 -85
- package/test/unit/spec/roap/turnDiscovery.ts +82 -36
- package/test/unit/spec/rtcMetrics/index.ts +73 -0
- package/test/unit/spec/stats-analyzer/index.js +136 -2
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -52
- package/dist/meeting/effectsState.js +0 -262
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -299
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/meeting/effectsState.d.ts +0 -42
- package/dist/types/metrics/config.d.ts +0 -178
- package/src/index.js +0 -16
- package/src/meeting/effectsState.ts +0 -211
- package/src/metrics/config.ts +0 -495
- package/test/unit/spec/meeting/effectsState.js +0 -285
package/src/meeting/muteState.ts
CHANGED
|
@@ -1,123 +1,188 @@
|
|
|
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
|
-
import Media from '../media';
|
|
5
4
|
import MeetingUtil from './util';
|
|
6
5
|
import {AUDIO, VIDEO} from '../constants';
|
|
7
6
|
|
|
8
|
-
/* Certain aspects of server interaction for video muting are not implemented as we currently don't support remote muting of video.
|
|
9
|
-
If we ever need to support it, search for REMOTE_MUTE_VIDEO_MISSING_IMPLEMENTATION string to find the places that need updating
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
7
|
// eslint-disable-next-line import/prefer-default-export
|
|
13
|
-
export const createMuteState = (type, meeting,
|
|
14
|
-
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
if (type === VIDEO && !mediaDirection.sendVideo) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
8
|
+
export const createMuteState = (type, meeting, enabled: boolean) => {
|
|
9
|
+
// todo: remove the meeting argument (SPARK-399695)
|
|
20
10
|
|
|
21
11
|
LoggerProxy.logger.info(
|
|
22
12
|
`Meeting:muteState#createMuteState --> ${type}: creating MuteState for meeting id ${meeting?.id}`
|
|
23
13
|
);
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
const muteState = new MuteState(type, meeting, enabled);
|
|
16
|
+
|
|
17
|
+
return muteState;
|
|
26
18
|
};
|
|
27
19
|
|
|
28
20
|
/** The purpose of this class is to manage the local and remote mute state and make sure that the server state always matches
|
|
29
21
|
the last requested state by the client.
|
|
30
22
|
|
|
31
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
|
|
32
26
|
*/
|
|
33
|
-
class MuteState {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
+
|
|
37
37
|
type: any;
|
|
38
|
+
ignoreMuteStateChange: boolean;
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Constructor
|
|
41
42
|
*
|
|
42
43
|
* @param {String} type - audio or video
|
|
43
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
|
|
44
46
|
*/
|
|
45
|
-
constructor(type: string, meeting: any) {
|
|
47
|
+
constructor(type: string, meeting: any, enabled: boolean) {
|
|
46
48
|
if (type !== AUDIO && type !== VIDEO) {
|
|
47
49
|
throw new ParameterError('Mute state is designed for handling audio or video only');
|
|
48
50
|
}
|
|
49
51
|
this.type = type;
|
|
52
|
+
this.ignoreMuteStateChange = false;
|
|
50
53
|
this.state = {
|
|
51
54
|
client: {
|
|
52
|
-
|
|
55
|
+
enabled,
|
|
56
|
+
localMute: true,
|
|
53
57
|
},
|
|
54
58
|
server: {
|
|
55
|
-
localMute:
|
|
56
|
-
//
|
|
57
|
-
remoteMute: type === AUDIO ? meeting.remoteMuted : false,
|
|
58
|
-
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,
|
|
59
63
|
},
|
|
60
64
|
syncToServerInProgress: false,
|
|
61
65
|
};
|
|
62
|
-
// these 2 hold the resolve, reject methods for the promise we returned to the client in last handleClientRequest() call
|
|
63
|
-
this.pendingPromiseResolve = null;
|
|
64
|
-
this.pendingPromiseReject = null;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
|
-
*
|
|
69
|
-
* 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
70
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
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.
|
|
74
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
|
|
116
|
+
*
|
|
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
|
|
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
|
|
75
147
|
* @public
|
|
76
148
|
* @memberof MuteState
|
|
77
149
|
* @param {Object} [meeting] the meeting object
|
|
78
150
|
* @param {Boolean} [mute] true for muting, false for unmuting request
|
|
79
|
-
* @returns {
|
|
151
|
+
* @returns {void}
|
|
80
152
|
*/
|
|
81
|
-
public
|
|
153
|
+
public handleLocalStreamMuteStateChange(meeting?: object, mute?: boolean) {
|
|
154
|
+
if (this.ignoreMuteStateChange) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
82
157
|
LoggerProxy.logger.info(
|
|
83
|
-
`Meeting:muteState#
|
|
158
|
+
`Meeting:muteState#handleLocalStreamMuteStateChange --> ${this.type}: local stream new mute state: ${mute}`
|
|
84
159
|
);
|
|
85
160
|
|
|
86
|
-
if (!mute && !this.state.server.unmuteAllowed) {
|
|
87
|
-
return Promise.reject(
|
|
88
|
-
new PermissionError('User is not allowed to unmute self (hard mute feature is being used)')
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 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,
|
|
93
|
-
// because the client may have changed the audio/vidoe tracks
|
|
94
161
|
this.state.client.localMute = mute;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return new Promise((resolve, reject) => {
|
|
98
|
-
if (this.pendingPromiseResolve) {
|
|
99
|
-
// resolve the last promise we returned to the client as the client has issued a new request that has superseded the previous one
|
|
100
|
-
this.pendingPromiseResolve();
|
|
101
|
-
}
|
|
102
|
-
this.pendingPromiseResolve = resolve;
|
|
103
|
-
this.pendingPromiseReject = reject;
|
|
104
|
-
this.applyClientStateToServer(meeting);
|
|
105
|
-
});
|
|
162
|
+
|
|
163
|
+
this.applyClientStateToServer(meeting);
|
|
106
164
|
}
|
|
107
165
|
|
|
108
166
|
/**
|
|
109
|
-
* Applies the current mute state to the local
|
|
167
|
+
* Applies the current mute state to the local stream (by enabling or disabling it accordingly)
|
|
110
168
|
*
|
|
111
169
|
* @public
|
|
112
170
|
* @param {Object} [meeting] the meeting object
|
|
171
|
+
* @param {ServerMuteReason} reason - reason why we're applying our client state to the local stream
|
|
113
172
|
* @memberof MuteState
|
|
114
173
|
* @returns {void}
|
|
115
174
|
*/
|
|
116
|
-
public applyClientStateLocally(meeting?: any) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
175
|
+
public applyClientStateLocally(meeting?: any, reason?: ServerMuteReason) {
|
|
176
|
+
this.muteLocalStream(meeting, this.state.client.localMute, reason);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Returns true if client is locally muted - it takes into account not just the client local mute state,
|
|
180
|
+
* but also whether audio/video is enabled at all
|
|
181
|
+
*
|
|
182
|
+
* @returns {boolean}
|
|
183
|
+
*/
|
|
184
|
+
private getClientLocalMuteState() {
|
|
185
|
+
return this.state.client.enabled ? this.state.client.localMute : true;
|
|
121
186
|
}
|
|
122
187
|
|
|
123
188
|
/**
|
|
@@ -128,7 +193,7 @@ class MuteState {
|
|
|
128
193
|
* @memberof MuteState
|
|
129
194
|
* @returns {void}
|
|
130
195
|
*/
|
|
131
|
-
private applyClientStateToServer(meeting?:
|
|
196
|
+
private applyClientStateToServer(meeting?: any) {
|
|
132
197
|
if (this.state.syncToServerInProgress) {
|
|
133
198
|
LoggerProxy.logger.info(
|
|
134
199
|
`Meeting:muteState#applyClientStateToServer --> ${this.type}: request to server in progress, we need to wait for it to complete`
|
|
@@ -137,11 +202,12 @@ class MuteState {
|
|
|
137
202
|
return;
|
|
138
203
|
}
|
|
139
204
|
|
|
140
|
-
const
|
|
141
|
-
const
|
|
205
|
+
const localMuteState = this.getClientLocalMuteState();
|
|
206
|
+
const localMuteRequiresSync = localMuteState !== this.state.server.localMute;
|
|
207
|
+
const remoteMuteRequiresSync = !localMuteState && this.state.server.remoteMute;
|
|
142
208
|
|
|
143
209
|
LoggerProxy.logger.info(
|
|
144
|
-
`Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${
|
|
210
|
+
`Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${localMuteState} ?= ${this.state.server.localMute})`
|
|
145
211
|
);
|
|
146
212
|
LoggerProxy.logger.info(
|
|
147
213
|
`Meeting:muteState#applyClientStateToServer --> ${this.type}: remoteMuteRequiresSync: ${remoteMuteRequiresSync}`
|
|
@@ -152,12 +218,6 @@ class MuteState {
|
|
|
152
218
|
`Meeting:muteState#applyClientStateToServer --> ${this.type}: client state already matching server state, nothing to do`
|
|
153
219
|
);
|
|
154
220
|
|
|
155
|
-
if (this.pendingPromiseResolve) {
|
|
156
|
-
this.pendingPromiseResolve();
|
|
157
|
-
}
|
|
158
|
-
this.pendingPromiseResolve = null;
|
|
159
|
-
this.pendingPromiseReject = null;
|
|
160
|
-
|
|
161
221
|
return;
|
|
162
222
|
}
|
|
163
223
|
|
|
@@ -185,11 +245,11 @@ class MuteState {
|
|
|
185
245
|
.catch((e) => {
|
|
186
246
|
this.state.syncToServerInProgress = false;
|
|
187
247
|
|
|
188
|
-
|
|
189
|
-
this.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.
|
|
248
|
+
LoggerProxy.logger.warn(
|
|
249
|
+
`Meeting:muteState#applyClientStateToServer --> ${this.type}: error: ${e}`
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
this.applyServerMuteToLocalStream(meeting, 'clientRequestFailed');
|
|
193
253
|
});
|
|
194
254
|
}
|
|
195
255
|
|
|
@@ -202,16 +262,14 @@ class MuteState {
|
|
|
202
262
|
* @returns {Promise}
|
|
203
263
|
*/
|
|
204
264
|
private sendLocalMuteRequestToServer(meeting?: any) {
|
|
205
|
-
const audioMuted =
|
|
206
|
-
|
|
207
|
-
const videoMuted =
|
|
208
|
-
this.type === VIDEO ? this.state.client.localMute : meeting.video?.state.client.localMute;
|
|
265
|
+
const audioMuted = this.type === AUDIO ? this.getClientLocalMuteState() : undefined;
|
|
266
|
+
const videoMuted = this.type === VIDEO ? this.getClientLocalMuteState() : undefined;
|
|
209
267
|
|
|
210
268
|
LoggerProxy.logger.info(
|
|
211
269
|
`Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: sending local mute (audio=${audioMuted}, video=${videoMuted}) to server`
|
|
212
270
|
);
|
|
213
271
|
|
|
214
|
-
return MeetingUtil.remoteUpdateAudioVideo(audioMuted, videoMuted
|
|
272
|
+
return MeetingUtil.remoteUpdateAudioVideo(meeting, audioMuted, videoMuted)
|
|
215
273
|
.then((locus) => {
|
|
216
274
|
LoggerProxy.logger.info(
|
|
217
275
|
`Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: local mute (audio=${audioMuted}, video=${videoMuted}) applied to server`
|
|
@@ -219,7 +277,9 @@ class MuteState {
|
|
|
219
277
|
|
|
220
278
|
this.state.server.localMute = this.type === AUDIO ? audioMuted : videoMuted;
|
|
221
279
|
|
|
222
|
-
|
|
280
|
+
if (locus) {
|
|
281
|
+
meeting.locusInfo.handleLocusDelta(locus, meeting);
|
|
282
|
+
}
|
|
223
283
|
|
|
224
284
|
return locus;
|
|
225
285
|
})
|
|
@@ -241,35 +301,54 @@ class MuteState {
|
|
|
241
301
|
* @returns {Promise}
|
|
242
302
|
*/
|
|
243
303
|
private sendRemoteMuteRequestToServer(meeting?: any) {
|
|
244
|
-
|
|
245
|
-
const remoteMute = this.state.client.localMute;
|
|
304
|
+
const remoteMute = this.getClientLocalMuteState();
|
|
246
305
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
306
|
+
LoggerProxy.logger.info(
|
|
307
|
+
`Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: sending remote mute:${remoteMute} to server`
|
|
308
|
+
);
|
|
250
309
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
310
|
+
return meeting.members
|
|
311
|
+
.muteMember(meeting.members.selfId, remoteMute, this.type === AUDIO)
|
|
312
|
+
.then(() => {
|
|
313
|
+
LoggerProxy.logger.info(
|
|
314
|
+
`Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: remote mute:${remoteMute} applied to server`
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
this.state.server.remoteMute = remoteMute;
|
|
318
|
+
})
|
|
319
|
+
.catch((remoteUpdateError) => {
|
|
320
|
+
LoggerProxy.logger.warn(
|
|
321
|
+
`Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: failed to apply remote mute ${remoteMute} to server: ${remoteUpdateError}`
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
return Promise.reject(remoteUpdateError);
|
|
325
|
+
});
|
|
326
|
+
}
|
|
268
327
|
|
|
269
|
-
|
|
270
|
-
|
|
328
|
+
/** Sets the mute state of the local stream according to what server thinks is our state
|
|
329
|
+
* @param {Object} meeting - the meeting object
|
|
330
|
+
* @param {ServerMuteReason} serverMuteReason - reason why we're applying server mute to the local stream
|
|
331
|
+
* @returns {void}
|
|
332
|
+
*/
|
|
333
|
+
private applyServerMuteToLocalStream(meeting: any, serverMuteReason: ServerMuteReason) {
|
|
334
|
+
const muted = this.state.server.localMute || this.state.server.remoteMute;
|
|
335
|
+
|
|
336
|
+
// update the local stream mute state, but not this.state.client.localMute
|
|
337
|
+
this.muteLocalStream(meeting, muted, serverMuteReason);
|
|
338
|
+
}
|
|
271
339
|
|
|
272
|
-
|
|
340
|
+
/** Applies the current value for unmute allowed to the underlying stream
|
|
341
|
+
*
|
|
342
|
+
* @param {Meeting} meeting
|
|
343
|
+
* @returns {void}
|
|
344
|
+
*/
|
|
345
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
346
|
+
private applyUnmuteAllowedToStream(meeting: any) {
|
|
347
|
+
if (this.type === AUDIO) {
|
|
348
|
+
meeting.mediaProperties.audioStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);
|
|
349
|
+
} else {
|
|
350
|
+
meeting.mediaProperties.videoStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);
|
|
351
|
+
}
|
|
273
352
|
}
|
|
274
353
|
|
|
275
354
|
/**
|
|
@@ -277,16 +356,23 @@ class MuteState {
|
|
|
277
356
|
*
|
|
278
357
|
* @public
|
|
279
358
|
* @memberof MuteState
|
|
359
|
+
* @param {Meeting} meeting
|
|
280
360
|
* @param {Boolean} [muted] true if user is remotely muted, false otherwise
|
|
281
361
|
* @param {Boolean} [unmuteAllowed] indicates if user is allowed to unmute self (false when "hard mute" feature is used)
|
|
282
362
|
* @returns {undefined}
|
|
283
363
|
*/
|
|
284
|
-
public handleServerRemoteMuteUpdate(muted?: boolean, unmuteAllowed?: boolean) {
|
|
364
|
+
public handleServerRemoteMuteUpdate(meeting: any, muted?: boolean, unmuteAllowed?: boolean) {
|
|
285
365
|
LoggerProxy.logger.info(
|
|
286
366
|
`Meeting:muteState#handleServerRemoteMuteUpdate --> ${this.type}: updating server remoteMute to (${muted})`
|
|
287
367
|
);
|
|
288
|
-
|
|
289
|
-
|
|
368
|
+
if (unmuteAllowed !== undefined) {
|
|
369
|
+
this.state.server.unmuteAllowed = unmuteAllowed;
|
|
370
|
+
this.applyUnmuteAllowedToStream(meeting);
|
|
371
|
+
}
|
|
372
|
+
if (muted !== undefined) {
|
|
373
|
+
this.state.server.remoteMute = muted;
|
|
374
|
+
this.applyServerMuteToLocalStream(meeting, 'remotelyMuted');
|
|
375
|
+
}
|
|
290
376
|
}
|
|
291
377
|
|
|
292
378
|
/**
|
|
@@ -298,27 +384,27 @@ class MuteState {
|
|
|
298
384
|
* @returns {undefined}
|
|
299
385
|
*/
|
|
300
386
|
public handleServerLocalUnmuteRequired(meeting?: object) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
387
|
+
if (!this.state.client.enabled) {
|
|
388
|
+
LoggerProxy.logger.warn(
|
|
389
|
+
`Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`
|
|
390
|
+
);
|
|
391
|
+
} else {
|
|
392
|
+
LoggerProxy.logger.info(
|
|
393
|
+
`Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
304
396
|
|
|
397
|
+
// 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
398
|
this.state.server.remoteMute = false;
|
|
306
399
|
this.state.client.localMute = false;
|
|
307
400
|
|
|
308
|
-
|
|
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;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
this.applyClientStateLocally(meeting);
|
|
401
|
+
this.applyClientStateLocally(meeting, 'localUnmuteRequired');
|
|
317
402
|
this.applyClientStateToServer(meeting);
|
|
318
403
|
}
|
|
319
404
|
|
|
320
405
|
/**
|
|
321
|
-
* Returns true if the user is locally or remotely muted
|
|
406
|
+
* Returns true if the user is locally or remotely muted.
|
|
407
|
+
* It only checks the mute status, ignoring the fact whether audio/video is enabled.
|
|
322
408
|
*
|
|
323
409
|
* @public
|
|
324
410
|
* @memberof MuteState
|
|
@@ -331,23 +417,35 @@ class MuteState {
|
|
|
331
417
|
}
|
|
332
418
|
|
|
333
419
|
/**
|
|
334
|
-
* Returns true if the user is
|
|
420
|
+
* Returns true if the user is remotely muted
|
|
335
421
|
*
|
|
336
422
|
* @public
|
|
337
423
|
* @memberof MuteState
|
|
338
424
|
* @returns {Boolean}
|
|
339
425
|
*/
|
|
340
|
-
public
|
|
341
|
-
return this.state.
|
|
426
|
+
public isRemotelyMuted() {
|
|
427
|
+
return this.state.server.remoteMute;
|
|
342
428
|
}
|
|
343
429
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Returns true if unmute is allowed
|
|
432
|
+
*
|
|
433
|
+
* @public
|
|
434
|
+
* @memberof MuteState
|
|
435
|
+
* @returns {Boolean}
|
|
436
|
+
*/
|
|
437
|
+
public isUnmuteAllowed() {
|
|
438
|
+
return this.state.server.unmuteAllowed;
|
|
347
439
|
}
|
|
348
440
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
441
|
+
/**
|
|
442
|
+
* Returns true if the user is locally muted or audio/video is disabled
|
|
443
|
+
*
|
|
444
|
+
* @public
|
|
445
|
+
* @memberof MuteState
|
|
446
|
+
* @returns {Boolean}
|
|
447
|
+
*/
|
|
448
|
+
public isLocallyMuted() {
|
|
449
|
+
return this.getClientLocalMuteState();
|
|
352
450
|
}
|
|
353
451
|
}
|