@webex/plugin-meetings 3.0.0-beta.21 → 3.0.0-beta.211
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 +45 -7
- 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 +114 -14
- 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 +841 -19
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +78 -0
- package/dist/breakouts/request.js.map +1 -0
- package/dist/breakouts/utils.js +67 -0
- package/dist/breakouts/utils.js.map +1 -0
- package/dist/common/errors/webex-errors.js +3 -2
- 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/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +3 -8
- package/dist/config.js.map +1 -1
- package/dist/constants.js +179 -30
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +14 -0
- package/dist/controls-options-manager/constants.js.map +1 -0
- package/dist/controls-options-manager/enums.js +27 -0
- package/dist/controls-options-manager/enums.js.map +1 -0
- package/dist/controls-options-manager/index.js +297 -0
- package/dist/controls-options-manager/index.js.map +1 -0
- 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 +319 -0
- package/dist/controls-options-manager/util.js.map +1 -0
- package/dist/index.js +106 -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 +359 -64
- 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 +43 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +219 -63
- 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 +48 -135
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +29 -90
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +505 -493
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +90 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +2770 -2547
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +291 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +229 -124
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +199 -193
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +532 -414
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +48 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +171 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +20 -5
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +22 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +357 -66
- 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 +88 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +49 -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 +121 -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 +86 -5
- 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 +316 -233
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +3 -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 +49 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +52 -34
- 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 +173 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +4 -2
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/reachability/index.js +72 -27
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +12 -5
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +196 -155
- 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 +21 -29
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +110 -89
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +93 -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/global.js +1 -93
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +326 -311
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +90 -53
- 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/breakout.d.ts +8 -0
- package/dist/types/breakouts/collection.d.ts +5 -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/index.d.ts +5 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/browser-detection.d.ts +9 -0
- package/dist/types/common/collection.d.ts +48 -0
- package/dist/types/common/config.d.ts +2 -0
- package/dist/types/common/errors/captcha-error.d.ts +15 -0
- package/dist/types/common/errors/intent-to-join.d.ts +16 -0
- package/dist/types/common/errors/join-meeting.d.ts +17 -0
- package/dist/types/common/errors/media.d.ts +15 -0
- package/dist/types/common/errors/parameter.d.ts +15 -0
- package/dist/types/common/errors/password-error.d.ts +15 -0
- package/dist/types/common/errors/permission.d.ts +14 -0
- package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
- package/dist/types/common/errors/reconnection.d.ts +15 -0
- package/dist/types/common/errors/stats.d.ts +15 -0
- package/dist/types/common/errors/webex-errors.d.ts +69 -0
- package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/types/common/events/events-scope.d.ts +17 -0
- package/dist/types/common/events/events.d.ts +12 -0
- package/dist/types/common/events/trigger-proxy.d.ts +2 -0
- package/dist/types/common/events/util.d.ts +2 -0
- package/dist/types/common/logs/logger-config.d.ts +2 -0
- package/dist/types/common/logs/logger-proxy.d.ts +2 -0
- package/dist/types/common/logs/request.d.ts +34 -0
- package/dist/types/common/queue.d.ts +34 -0
- package/dist/types/config.d.ts +72 -0
- package/dist/types/constants.d.ts +1020 -0
- package/dist/types/controls-options-manager/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/enums.d.ts +15 -0
- package/dist/types/controls-options-manager/index.d.ts +136 -0
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -0
- package/dist/types/index.d.ts +7 -0
- 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/controlsUtils.d.ts +2 -0
- package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/types/locus-info/fullState.d.ts +2 -0
- package/dist/types/locus-info/hostUtils.d.ts +2 -0
- package/dist/types/locus-info/index.d.ts +322 -0
- package/dist/types/locus-info/infoUtils.d.ts +2 -0
- package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/types/locus-info/parser.d.ts +271 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/index.d.ts +34 -0
- package/dist/types/media/properties.d.ts +93 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +163 -0
- package/dist/types/meeting/index.d.ts +1482 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +72 -0
- package/dist/types/meeting/muteState.d.ts +184 -0
- package/dist/types/meeting/request.d.ts +257 -0
- package/dist/types/meeting/request.type.d.ts +11 -0
- package/dist/types/meeting/state.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +79 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +62 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
- package/dist/types/meeting-info/request.d.ts +22 -0
- package/dist/types/meeting-info/util.d.ts +2 -0
- package/dist/types/meeting-info/utilv2.d.ts +2 -0
- package/dist/types/meetings/collection.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +367 -0
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/meetings/request.d.ts +27 -0
- package/dist/types/meetings/util.d.ts +18 -0
- package/dist/types/member/index.d.ts +159 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/member/util.d.ts +2 -0
- package/dist/types/members/collection.d.ts +29 -0
- package/dist/types/members/index.d.ts +353 -0
- package/dist/types/members/request.d.ts +114 -0
- package/dist/types/members/types.d.ts +24 -0
- package/dist/types/members/util.d.ts +210 -0
- package/dist/types/metrics/constants.d.ts +55 -0
- package/dist/types/metrics/index.d.ts +45 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
- package/dist/types/multistream/receiveSlot.d.ts +68 -0
- package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/types/multistream/remoteMedia.d.ts +72 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/types/personal-meeting-room/index.d.ts +47 -0
- package/dist/types/personal-meeting-room/request.d.ts +14 -0
- package/dist/types/personal-meeting-room/util.d.ts +2 -0
- package/dist/types/reachability/index.d.ts +152 -0
- package/dist/types/reachability/request.d.ts +37 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +126 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +207 -0
- package/dist/types/recording-controller/util.d.ts +14 -0
- package/dist/types/roap/index.d.ts +77 -0
- package/dist/types/roap/request.d.ts +36 -0
- package/dist/types/roap/turnDiscovery.d.ts +91 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +46 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +200 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
- package/dist/types/transcription/index.d.ts +64 -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 +44 -14
- package/src/breakouts/breakout.ts +87 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +710 -10
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/errors/webex-errors.ts +6 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +2 -7
- package/src/constants.ts +165 -21
- package/src/controls-options-manager/constants.ts +5 -0
- package/src/controls-options-manager/enums.ts +18 -0
- package/src/controls-options-manager/index.ts +278 -0
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +300 -0
- package/src/index.ts +39 -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 +383 -61
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +48 -0
- package/src/locus-info/parser.ts +224 -39
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +87 -140
- package/src/media/properties.ts +49 -90
- package/src/mediaQualityMetrics/config.ts +379 -377
- package/src/meeting/in-meeting-actions.ts +179 -3
- package/src/meeting/index.ts +2099 -2083
- package/src/meeting/locusMediaRequest.ts +311 -0
- package/src/meeting/muteState.ts +228 -132
- package/src/meeting/request.ts +105 -115
- package/src/meeting/util.ts +511 -397
- package/src/meeting-info/index.ts +54 -8
- package/src/meeting-info/meeting-info-v2.ts +148 -14
- package/src/meeting-info/utilv2.ts +13 -3
- package/src/meetings/collection.ts +20 -0
- package/src/meetings/index.ts +392 -84
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +103 -4
- package/src/member/index.ts +49 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +127 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +107 -6
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +28 -0
- package/src/members/util.ts +319 -240
- package/src/metrics/constants.ts +2 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +289 -79
- package/src/multistream/receiveSlot.ts +55 -18
- package/src/multistream/receiveSlotManager.ts +46 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +113 -32
- package/src/networkQualityMonitor/index.ts +6 -6
- package/src/reachability/index.ts +62 -15
- package/src/reachability/request.ts +10 -5
- package/src/reconnection-manager/index.ts +68 -43
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +21 -30
- package/src/roap/request.ts +101 -95
- package/src/roap/turnDiscovery.ts +47 -25
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/global.ts +1 -94
- package/src/statsAnalyzer/index.ts +376 -386
- package/src/statsAnalyzer/mqaUtil.ts +100 -99
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +336 -259
- package/test/integration/spec/space-meeting.js +77 -4
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +142 -24
- 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 +1545 -48
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +287 -0
- package/test/unit/spec/controls-options-manager/util.js +582 -0
- 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 +1169 -36
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
- package/test/unit/spec/locus-info/parser.js +62 -22
- 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 +138 -28
- package/test/unit/spec/meeting/in-meeting-actions.ts +89 -3
- package/test/unit/spec/meeting/index.js +3573 -1663
- package/test/unit/spec/meeting/locusMediaRequest.ts +438 -0
- package/test/unit/spec/meeting/muteState.js +370 -208
- package/test/unit/spec/meeting/request.js +339 -44
- package/test/unit/spec/meeting/utils.js +456 -53
- package/test/unit/spec/meeting-info/index.js +181 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +14 -0
- package/test/unit/spec/meetings/index.js +867 -125
- package/test/unit/spec/meetings/utils.js +206 -2
- package/test/unit/spec/member/index.js +58 -4
- package/test/unit/spec/member/util.js +479 -35
- package/test/unit/spec/members/index.js +319 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +184 -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 +72 -13
- package/test/unit/spec/multistream/receiveSlotManager.ts +58 -28
- 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 +318 -0
- package/test/unit/spec/networkQualityMonitor/index.js +4 -4
- package/test/unit/spec/reachability/index.ts +125 -8
- package/test/unit/spec/reachability/request.js +66 -0
- package/test/unit/spec/reconnection-manager/index.js +59 -6
- 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 +26 -51
- package/test/unit/spec/roap/request.ts +196 -85
- package/test/unit/spec/roap/turnDiscovery.ts +30 -7
- package/test/unit/spec/rtcMetrics/index.ts +60 -0
- package/test/unit/spec/stats-analyzer/index.js +92 -41
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -45
- package/test/utils/webex-config.js +4 -0
- package/test/utils/webex-test-users.js +6 -3
- 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/multistream/multistreamMedia.js +0 -110
- package/dist/multistream/multistreamMedia.js.map +0 -1
- package/src/index.js +0 -16
- package/src/meeting/effectsState.ts +0 -211
- package/src/metrics/config.ts +0 -495
- package/src/multistream/multistreamMedia.ts +0 -97
- package/test/unit/spec/meeting/effectsState.js +0 -285
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/* eslint-disable valid-jsdoc */
|
|
2
2
|
/* eslint-disable import/prefer-default-export */
|
|
3
|
-
import {MediaType} from '@webex/internal-media-core';
|
|
4
|
-
|
|
3
|
+
import {MediaType, ReceiveSlot as WcmeReceiveSlot} from '@webex/internal-media-core';
|
|
5
4
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
6
|
-
import Meeting from '../meeting';
|
|
7
5
|
|
|
8
|
-
import {
|
|
6
|
+
import {FindMemberIdCallback, ReceiveSlot} from './receiveSlot';
|
|
7
|
+
|
|
8
|
+
export type CreateSlotCallback = (mediaType: MediaType) => Promise<WcmeReceiveSlot>;
|
|
9
|
+
|
|
10
|
+
export type {CSI, FindMemberIdCallback} from './receiveSlot';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Manages all receive slots used by a meeting. WMCE receive slots cannot be ever deleted,
|
|
@@ -16,13 +18,18 @@ export class ReceiveSlotManager {
|
|
|
16
18
|
|
|
17
19
|
private freeSlots: {[key in MediaType]: ReceiveSlot[]};
|
|
18
20
|
|
|
19
|
-
private
|
|
21
|
+
private createSlotCallback: CreateSlotCallback;
|
|
22
|
+
|
|
23
|
+
private findMemberIdByCsiCallback: FindMemberIdCallback;
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
26
|
* Constructor
|
|
23
27
|
* @param {Meeting} meeting
|
|
24
28
|
*/
|
|
25
|
-
constructor(
|
|
29
|
+
constructor(
|
|
30
|
+
createSlotCallback: CreateSlotCallback,
|
|
31
|
+
findMemberIdByCsiCallback: FindMemberIdCallback
|
|
32
|
+
) {
|
|
26
33
|
this.allocatedSlots = {
|
|
27
34
|
[MediaType.AudioMain]: [],
|
|
28
35
|
[MediaType.VideoMain]: [],
|
|
@@ -35,7 +42,8 @@ export class ReceiveSlotManager {
|
|
|
35
42
|
[MediaType.AudioSlides]: [],
|
|
36
43
|
[MediaType.VideoSlides]: [],
|
|
37
44
|
};
|
|
38
|
-
this.
|
|
45
|
+
this.createSlotCallback = createSlotCallback;
|
|
46
|
+
this.findMemberIdByCsiCallback = findMemberIdByCsiCallback;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
/**
|
|
@@ -45,34 +53,24 @@ export class ReceiveSlotManager {
|
|
|
45
53
|
* @returns {Promise<ReceiveSlot>}
|
|
46
54
|
*/
|
|
47
55
|
async allocateSlot(mediaType: MediaType): Promise<ReceiveSlot> {
|
|
48
|
-
if (!this.meeting?.mediaProperties?.webrtcMediaConnection) {
|
|
49
|
-
return Promise.reject(new Error('Webrtc media connection is missing'));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
56
|
// try to use one of the free ones
|
|
53
57
|
const availableSlot = this.freeSlots[mediaType].pop();
|
|
54
58
|
|
|
55
59
|
if (availableSlot) {
|
|
56
60
|
this.allocatedSlots[mediaType].push(availableSlot);
|
|
57
61
|
|
|
58
|
-
LoggerProxy.logger.log(
|
|
62
|
+
LoggerProxy.logger.log(`${mediaType}: receive slot re-used: ${availableSlot.id}`);
|
|
59
63
|
|
|
60
64
|
return availableSlot;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
// we have to create a new one
|
|
64
|
-
const wcmeReceiveSlot =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const receiveSlot = new ReceiveSlot(
|
|
68
|
-
mediaType,
|
|
69
|
-
wcmeReceiveSlot,
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
(csi: CSI) => this.meeting.members.findMemberByCsi(csi)?.id
|
|
72
|
-
);
|
|
68
|
+
const wcmeReceiveSlot = await this.createSlotCallback(mediaType);
|
|
69
|
+
|
|
70
|
+
const receiveSlot = new ReceiveSlot(mediaType, wcmeReceiveSlot, this.findMemberIdByCsiCallback);
|
|
73
71
|
|
|
74
72
|
this.allocatedSlots[mediaType].push(receiveSlot);
|
|
75
|
-
LoggerProxy.logger.log(
|
|
73
|
+
LoggerProxy.logger.log(`${mediaType}: new receive slot allocated: ${receiveSlot.id}`);
|
|
76
74
|
|
|
77
75
|
return receiveSlot;
|
|
78
76
|
}
|
|
@@ -89,10 +87,10 @@ export class ReceiveSlotManager {
|
|
|
89
87
|
if (idx >= 0) {
|
|
90
88
|
this.allocatedSlots[slot.mediaType].splice(idx, 1);
|
|
91
89
|
this.freeSlots[slot.mediaType].push(slot);
|
|
92
|
-
LoggerProxy.logger.log(
|
|
90
|
+
LoggerProxy.logger.log(`${slot.mediaType}: receive slot released: ${slot.id}`);
|
|
93
91
|
} else {
|
|
94
92
|
LoggerProxy.logger.warn(
|
|
95
|
-
|
|
93
|
+
`ReceiveSlotManager#releaseSlot --> trying to release a ${slot.mediaType}} slot that is not managed by this ReceiveSlotManager`
|
|
96
94
|
);
|
|
97
95
|
}
|
|
98
96
|
}
|
|
@@ -141,4 +139,28 @@ export class ReceiveSlotManager {
|
|
|
141
139
|
numFreeSlots,
|
|
142
140
|
};
|
|
143
141
|
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Tries to find the member id on all allocated receive slots
|
|
145
|
+
* This function should be called when new members are added to the meeting.
|
|
146
|
+
*/
|
|
147
|
+
updateMemberIds() {
|
|
148
|
+
Object.keys(this.allocatedSlots).forEach((key) => {
|
|
149
|
+
this.allocatedSlots[key].forEach((slot: ReceiveSlot) => {
|
|
150
|
+
slot.findMemberId();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Find a receive slot by a ssrc.
|
|
157
|
+
*
|
|
158
|
+
* @param ssrc - The ssrc of the receive slot to find.
|
|
159
|
+
* @returns - The receive slot with this ssrc, undefined if not found.
|
|
160
|
+
*/
|
|
161
|
+
findReceiveSlotBySsrc(ssrc: number): ReceiveSlot | undefined {
|
|
162
|
+
return Object.values(this.allocatedSlots)
|
|
163
|
+
.flat()
|
|
164
|
+
.find((r) => ssrc && r.wcmeReceiveSlot?.id?.ssrc === ssrc);
|
|
165
|
+
}
|
|
144
166
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable valid-jsdoc */
|
|
2
|
-
import {MediaType,
|
|
2
|
+
import {MediaType, StreamState} from '@webex/internal-media-core';
|
|
3
3
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
4
4
|
import EventsScope from '../common/events/events-scope';
|
|
5
5
|
|
|
@@ -102,6 +102,31 @@ export class RemoteMedia extends EventsScope {
|
|
|
102
102
|
this.id = `RM${remoteMediaCounter}-${this.receiveSlot.id}`;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Supply the width and height of the video element
|
|
107
|
+
* to restrict the requested resolution to this size
|
|
108
|
+
* @param width width of the video element
|
|
109
|
+
* @param height height of the video element
|
|
110
|
+
*/
|
|
111
|
+
public setSizeHint(width, height) {
|
|
112
|
+
// only base on height for now
|
|
113
|
+
let fs: number;
|
|
114
|
+
|
|
115
|
+
if (height < 135) {
|
|
116
|
+
fs = 60;
|
|
117
|
+
} else if (height < 270) {
|
|
118
|
+
fs = 240;
|
|
119
|
+
} else if (height < 540) {
|
|
120
|
+
fs = 920;
|
|
121
|
+
} else if (height <= 720) {
|
|
122
|
+
fs = 3600;
|
|
123
|
+
} else {
|
|
124
|
+
fs = 8192;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
this.receiveSlot?.setMaxFs(fs);
|
|
128
|
+
}
|
|
129
|
+
|
|
105
130
|
/**
|
|
106
131
|
* Invalidates the remote media by clearing the reference to a receive slot and
|
|
107
132
|
* cancelling the media request.
|
|
@@ -208,7 +233,7 @@ export class RemoteMedia extends EventsScope {
|
|
|
208
233
|
/**
|
|
209
234
|
* Getter for source state
|
|
210
235
|
*/
|
|
211
|
-
public get sourceState():
|
|
236
|
+
public get sourceState(): StreamState {
|
|
212
237
|
return this.receiveSlot?.sourceState;
|
|
213
238
|
}
|
|
214
239
|
|
|
@@ -1,6 +1,7 @@
|
|
|
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';
|
|
4
5
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
5
6
|
|
|
6
7
|
import {getMaxFs, RemoteMedia, RemoteVideoResolution} from './remoteMedia';
|
|
@@ -66,6 +67,53 @@ export class RemoteMediaGroup {
|
|
|
66
67
|
return [...this.unpinnedRemoteMedia, ...this.pinnedRemoteMedia];
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Sets CSIs for multiple RemoteMedia instances belonging to this RemoteMediaGroup.
|
|
72
|
+
* For each entry in the remoteMediaCsis array:
|
|
73
|
+
* - if csi is specified, the RemoteMedia instance is pinned to that CSI
|
|
74
|
+
* - if csi is undefined, the RemoteMedia instance is unpinned
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
public setActiveSpeakerCsis(
|
|
78
|
+
remoteMediaCsis: {remoteMedia: RemoteMedia; csi?: number}[],
|
|
79
|
+
commit = true
|
|
80
|
+
): void {
|
|
81
|
+
forEach(remoteMediaCsis, ({csi, remoteMedia}) => {
|
|
82
|
+
if (csi) {
|
|
83
|
+
if (!(this.pinnedRemoteMedia.indexOf(remoteMedia) >= 0)) {
|
|
84
|
+
const unpinId = this.unpinnedRemoteMedia.indexOf(remoteMedia);
|
|
85
|
+
if (unpinId >= 0) {
|
|
86
|
+
this.unpinnedRemoteMedia.splice(unpinId, 1);
|
|
87
|
+
this.pinnedRemoteMedia.push(remoteMedia);
|
|
88
|
+
} else {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`failed to pin a remote media object ${remoteMedia.id}, because it is not found in this remote media group`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
remoteMedia.sendMediaRequest(csi, false);
|
|
95
|
+
} else {
|
|
96
|
+
if (!(this.unpinnedRemoteMedia.indexOf(remoteMedia) >= 0)) {
|
|
97
|
+
const pinId = this.pinnedRemoteMedia.indexOf(remoteMedia);
|
|
98
|
+
if (pinId >= 0) {
|
|
99
|
+
this.pinnedRemoteMedia.splice(pinId, 1);
|
|
100
|
+
this.unpinnedRemoteMedia.push(remoteMedia);
|
|
101
|
+
} else {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`failed to unpin a remote media object ${remoteMedia.id}, because it is not found in this remote media group`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
remoteMedia.cancelMediaRequest(false);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
this.cancelActiveSpeakerMediaRequest(false);
|
|
111
|
+
this.sendActiveSpeakerMediaRequest(false);
|
|
112
|
+
if (commit) {
|
|
113
|
+
this.mediaRequestManager.commit();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
69
117
|
/**
|
|
70
118
|
* Pins a specific remote media instance to a specfic CSI, so the media will
|
|
71
119
|
* no longer come from active speaker, but from that CSI.
|
|
@@ -151,6 +199,17 @@ export class RemoteMediaGroup {
|
|
|
151
199
|
throw new Error(`remote media object ${remoteMedia.id} not found in the group`);
|
|
152
200
|
}
|
|
153
201
|
|
|
202
|
+
/**
|
|
203
|
+
* setPreferLiveVideo - sets preferLiveVideo to true/false
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
public setPreferLiveVideo(preferLiveVideo: boolean, commit: boolean) {
|
|
207
|
+
if (this.options.preferLiveVideo !== preferLiveVideo) {
|
|
208
|
+
this.options.preferLiveVideo = preferLiveVideo;
|
|
209
|
+
this.sendActiveSpeakerMediaRequest(commit);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
154
213
|
private sendActiveSpeakerMediaRequest(commit: boolean) {
|
|
155
214
|
this.cancelActiveSpeakerMediaRequest(false);
|
|
156
215
|
|
|
@@ -1,5 +1,5 @@
|
|
|
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
5
|
|
|
@@ -96,6 +96,7 @@ const OnePlusFiveLayout: VideoLayout = {
|
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
// A layout with 2 big panes for 2 main active speakers and a strip of 6 small panes for other active speakers:
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
99
100
|
const TwoMainPlusSixSmallLayout: VideoLayout = {
|
|
100
101
|
activeSpeakerVideoPaneGroups: [
|
|
101
102
|
{
|
|
@@ -115,7 +116,7 @@ const TwoMainPlusSixSmallLayout: VideoLayout = {
|
|
|
115
116
|
|
|
116
117
|
// A strip of 8 small video panes (thumbnails) displayed at the top of a remote screenshare:
|
|
117
118
|
const RemoteScreenShareWithSmallThumbnailsLayout: VideoLayout = {
|
|
118
|
-
|
|
119
|
+
screenShareVideo: {size: 'best'},
|
|
119
120
|
activeSpeakerVideoPaneGroups: [
|
|
120
121
|
{
|
|
121
122
|
id: 'thumbnails',
|
|
@@ -153,7 +154,7 @@ const Stage2x2With6ThumbnailsLayout: VideoLayout = {
|
|
|
153
154
|
export const DefaultConfiguration: Configuration = {
|
|
154
155
|
audio: {
|
|
155
156
|
numOfActiveSpeakerStreams: 3,
|
|
156
|
-
numOfScreenShareStreams:
|
|
157
|
+
numOfScreenShareStreams: 1,
|
|
157
158
|
},
|
|
158
159
|
video: {
|
|
159
160
|
preferLiveVideo: true,
|
|
@@ -490,6 +491,38 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
490
491
|
return this.currentLayoutId;
|
|
491
492
|
}
|
|
492
493
|
|
|
494
|
+
/**
|
|
495
|
+
* sets the preferLiveVideo
|
|
496
|
+
*/
|
|
497
|
+
public setPreferLiveVideo(preferLiveVideo: boolean) {
|
|
498
|
+
LoggerProxy.logger.log(
|
|
499
|
+
`RemoteMediaManager#setPreferLiveVideo --> setPreferLiveVideo is called to set preferLiveVideo to ${preferLiveVideo}`
|
|
500
|
+
);
|
|
501
|
+
this.config.video.preferLiveVideo = preferLiveVideo;
|
|
502
|
+
Object.values(this.media.video.activeSpeakerGroups).forEach((activeSpeakerGroup) => {
|
|
503
|
+
activeSpeakerGroup.setPreferLiveVideo(preferLiveVideo, false);
|
|
504
|
+
});
|
|
505
|
+
this.mediaRequestManagers.video.commit();
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Sets CSIs for multiple RemoteMedia instances belonging to RemoteMediaGroup.
|
|
510
|
+
* For each entry in the remoteMediaCsis array:
|
|
511
|
+
* - if csi is specified, the RemoteMedia instance is pinned to that CSI
|
|
512
|
+
* - if csi is undefined, the RemoteMedia instance is unpinned
|
|
513
|
+
*/
|
|
514
|
+
public setActiveSpeakerCsis(remoteMediaCsis: {remoteMedia: RemoteMedia; csi?: number}[]) {
|
|
515
|
+
Object.values(this.media.video.activeSpeakerGroups).forEach((remoteMediaGroup) => {
|
|
516
|
+
const groupRemoteMediaCsis = remoteMediaCsis.filter(({remoteMedia}) =>
|
|
517
|
+
remoteMediaGroup.includes(remoteMedia)
|
|
518
|
+
);
|
|
519
|
+
if (groupRemoteMediaCsis.length > 0) {
|
|
520
|
+
remoteMediaGroup.setActiveSpeakerCsis(groupRemoteMediaCsis, false);
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
this.mediaRequestManagers.video.commit();
|
|
524
|
+
}
|
|
525
|
+
|
|
493
526
|
/**
|
|
494
527
|
* Creates the audio slots
|
|
495
528
|
*/
|
|
@@ -601,25 +634,37 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
601
634
|
}
|
|
602
635
|
|
|
603
636
|
/**
|
|
604
|
-
* Allocates receive slots to all video panes
|
|
637
|
+
* Allocates receive slots to all active speaker video panes
|
|
638
|
+
* in the current selected layout.
|
|
639
|
+
*
|
|
640
|
+
* Allocation tries to keep the same order of the slots between the previous
|
|
641
|
+
* layout and the new one. Sorting helps making sure that highest priority slots
|
|
642
|
+
* go in the same order in the new layout.
|
|
605
643
|
*/
|
|
606
|
-
private
|
|
607
|
-
this.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
644
|
+
private allocateSlotsToActiveSpeakerPaneGroups() {
|
|
645
|
+
this.currentLayout?.activeSpeakerVideoPaneGroups
|
|
646
|
+
// sorting in descending order based on group priority
|
|
647
|
+
?.sort((a, b) => (a.priority < b.priority ? 1 : -1))
|
|
648
|
+
?.forEach((group) => {
|
|
649
|
+
this.receiveSlotAllocations.activeSpeaker[group.id] = {slots: []};
|
|
650
|
+
|
|
651
|
+
for (let paneIndex = 0; paneIndex < group.numPanes; paneIndex += 1) {
|
|
652
|
+
// allocate a slot from the "unused" list, by grabbing in same order (shift) as previous layout
|
|
653
|
+
const freeSlot = this.slots.video.unused.shift();
|
|
654
|
+
|
|
655
|
+
if (freeSlot) {
|
|
656
|
+
this.slots.video.activeSpeaker.push(freeSlot);
|
|
657
|
+
this.receiveSlotAllocations.activeSpeaker[group.id].slots.push(freeSlot);
|
|
658
|
+
}
|
|
619
659
|
}
|
|
620
|
-
}
|
|
621
|
-
|
|
660
|
+
});
|
|
661
|
+
}
|
|
622
662
|
|
|
663
|
+
/**
|
|
664
|
+
* Allocates receive slots to all receiver selected video panes
|
|
665
|
+
* in the current selected layout
|
|
666
|
+
*/
|
|
667
|
+
private allocateSlotsToReceiverSelectedVideoPaneGroups() {
|
|
623
668
|
this.currentLayout?.memberVideoPanes?.forEach((memberPane) => {
|
|
624
669
|
// check if there is existing slot for this csi
|
|
625
670
|
const existingSlot = this.slots.video.receiverSelected.find(
|
|
@@ -646,19 +691,15 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
646
691
|
}
|
|
647
692
|
|
|
648
693
|
/**
|
|
649
|
-
*
|
|
650
|
-
* and allocates them to the right video panes / pane groups
|
|
651
|
-
*
|
|
652
|
-
* @returns {Promise}
|
|
694
|
+
* Ensures that we have enough slots for the current layout.
|
|
653
695
|
*/
|
|
654
|
-
private async
|
|
696
|
+
private async refillRequiredSlotsIfNeeded() {
|
|
655
697
|
const requiredNumSlots = this.getRequiredNumVideoSlotsForLayout(this.currentLayout);
|
|
656
698
|
const totalNumSlots =
|
|
657
699
|
this.slots.video.unused.length +
|
|
658
700
|
this.slots.video.activeSpeaker.length +
|
|
659
701
|
this.slots.video.receiverSelected.length;
|
|
660
702
|
|
|
661
|
-
// ensure we have enough total slots for current layout
|
|
662
703
|
if (totalNumSlots < requiredNumSlots) {
|
|
663
704
|
let numSlotsToCreate = requiredNumSlots - totalNumSlots;
|
|
664
705
|
|
|
@@ -671,20 +712,60 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
671
712
|
numSlotsToCreate -= 1;
|
|
672
713
|
}
|
|
673
714
|
}
|
|
715
|
+
}
|
|
674
716
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
717
|
+
/**
|
|
718
|
+
* Move all active speaker slots to "unused"
|
|
719
|
+
*/
|
|
720
|
+
private trimActiveSpeakerSlots() {
|
|
679
721
|
this.slots.video.unused.push(...this.slots.video.activeSpeaker);
|
|
680
722
|
this.slots.video.activeSpeaker.length = 0;
|
|
723
|
+
}
|
|
681
724
|
|
|
682
|
-
|
|
683
|
-
|
|
725
|
+
/**
|
|
726
|
+
* Logs the state of the receive slots
|
|
727
|
+
*/
|
|
728
|
+
private logReceieveSlots() {
|
|
729
|
+
let logMessage = '';
|
|
730
|
+
forEach(this.receiveSlotAllocations.activeSpeaker, (group, groupName) => {
|
|
731
|
+
logMessage += `group: ${groupName}\n${group.slots.map((slot) => slot.logString).join(' ')}`;
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
logMessage += '\nreceiverSelected:\n';
|
|
735
|
+
forEach(this.receiveSlotAllocations.receiverSelected, (slot, key) => {
|
|
736
|
+
logMessage += ` ${key}: ${slot.logString}\n`;
|
|
737
|
+
});
|
|
684
738
|
|
|
685
739
|
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}`
|
|
740
|
+
`RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=${this.slots.video.unused.length}, activeSpeaker=${this.slots.video.activeSpeaker.length}, receiverSelected=${this.slots.video.receiverSelected.length}\n${logMessage}`
|
|
687
741
|
);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Makes sure we have the right number of receive slots created for the current layout
|
|
746
|
+
* and allocates them to the right video panes / pane groups
|
|
747
|
+
*
|
|
748
|
+
* @returns {Promise}
|
|
749
|
+
*/
|
|
750
|
+
private async updateVideoReceiveSlots() {
|
|
751
|
+
// move all active speaker slots to "unused"
|
|
752
|
+
this.trimActiveSpeakerSlots();
|
|
753
|
+
|
|
754
|
+
// move all no longer needed receiver-selected slots to "unused"
|
|
755
|
+
this.trimReceiverSelectedSlots();
|
|
756
|
+
|
|
757
|
+
// ensure we have enough total slots for current layout
|
|
758
|
+
await this.refillRequiredSlotsIfNeeded();
|
|
759
|
+
|
|
760
|
+
// allocate the slots to the right panes / pane groups
|
|
761
|
+
// reset allocations
|
|
762
|
+
this.receiveSlotAllocations = {activeSpeaker: {}, receiverSelected: {}};
|
|
763
|
+
// allocate active speaker
|
|
764
|
+
this.allocateSlotsToActiveSpeakerPaneGroups();
|
|
765
|
+
// allocate receiver selected
|
|
766
|
+
this.allocateSlotsToReceiverSelectedVideoPaneGroups();
|
|
767
|
+
|
|
768
|
+
this.logReceieveSlots();
|
|
688
769
|
|
|
689
770
|
// If this is the initial layout, there may be some "unused" slots left because of the preallocation
|
|
690
771
|
// done in this.preallocateVideoReceiveSlots(), so release them now
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import EventsScope from '../common/events/events-scope';
|
|
2
|
-
import {EVENT_TRIGGERS
|
|
2
|
+
import {EVENT_TRIGGERS} from '../constants';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Meeting - network quality event
|
|
@@ -49,11 +49,7 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
49
49
|
});
|
|
50
50
|
this.networkQualityScore = 1;
|
|
51
51
|
this.networkQualityStatus = {
|
|
52
|
-
[this.frequencyTypes.UPLINK]: {
|
|
53
|
-
[STATS.VIDEO_CORRELATE]: {},
|
|
54
|
-
[STATS.AUDIO_CORRELATE]: {},
|
|
55
|
-
[STATS.SHARE_CORRELATE]: {},
|
|
56
|
-
},
|
|
52
|
+
[this.frequencyTypes.UPLINK]: {},
|
|
57
53
|
};
|
|
58
54
|
this.mediaType = null;
|
|
59
55
|
}
|
|
@@ -172,6 +168,10 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
172
168
|
const determineIfUndefined = (value: number | undefined) =>
|
|
173
169
|
typeof value === 'undefined' ? null : value;
|
|
174
170
|
|
|
171
|
+
if (!this.networkQualityStatus[UPLINK][mediaType]) {
|
|
172
|
+
this.networkQualityStatus[UPLINK][mediaType] = {};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
175
|
/**
|
|
176
176
|
* Values for some browsers specifically Safari will be undefined we explicitly set to null
|
|
177
177
|
* https://bugs.webkit.org/show_bug.cgi?id=206645
|
|
@@ -14,6 +14,7 @@ import ReachabilityRequest from './request';
|
|
|
14
14
|
const DEFAULT_TIMEOUT = 3000;
|
|
15
15
|
const VIDEO_MESH_TIMEOUT = 1000;
|
|
16
16
|
|
|
17
|
+
export type ICECandidateResult = {clusterId: string; elapsed?: string | null; publicIPs?: string[]};
|
|
17
18
|
/**
|
|
18
19
|
* @class Reachability
|
|
19
20
|
* @export
|
|
@@ -63,11 +64,13 @@ export default class Reachability {
|
|
|
63
64
|
|
|
64
65
|
// Remove stored reachability results to ensure no stale data
|
|
65
66
|
// @ts-ignore
|
|
66
|
-
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.
|
|
67
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageResult);
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageJoinCookie);
|
|
67
70
|
|
|
68
71
|
// Fetch clusters and measure latency
|
|
69
72
|
try {
|
|
70
|
-
const clusters = await this.reachabilityRequest.getClusters();
|
|
73
|
+
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters();
|
|
71
74
|
|
|
72
75
|
// Perform Reachability Check
|
|
73
76
|
const results = await this.performReachabilityCheck(clusters);
|
|
@@ -75,9 +78,15 @@ export default class Reachability {
|
|
|
75
78
|
// @ts-ignore
|
|
76
79
|
await this.webex.boundedStorage.put(
|
|
77
80
|
this.namespace,
|
|
78
|
-
REACHABILITY.
|
|
81
|
+
REACHABILITY.localStorageResult,
|
|
79
82
|
JSON.stringify(results)
|
|
80
83
|
);
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
await this.webex.boundedStorage.put(
|
|
86
|
+
this.namespace,
|
|
87
|
+
REACHABILITY.localStorageJoinCookie,
|
|
88
|
+
JSON.stringify(joinCookie)
|
|
89
|
+
);
|
|
81
90
|
|
|
82
91
|
LoggerProxy.logger.log(
|
|
83
92
|
'Reachability:index#gatherReachability --> Reachability checks completed'
|
|
@@ -103,7 +112,7 @@ export default class Reachability {
|
|
|
103
112
|
let reachable = false;
|
|
104
113
|
// @ts-ignore
|
|
105
114
|
const reachabilityData = await this.webex.boundedStorage
|
|
106
|
-
.get(this.namespace, REACHABILITY.
|
|
115
|
+
.get(this.namespace, REACHABILITY.localStorageResult)
|
|
107
116
|
.catch(() => {});
|
|
108
117
|
|
|
109
118
|
if (reachabilityData) {
|
|
@@ -292,6 +301,8 @@ export default class Reachability {
|
|
|
292
301
|
`Reachability:index#onIceCandidate --> Successfully pinged ${peerConnection.key}:`,
|
|
293
302
|
elapsed
|
|
294
303
|
);
|
|
304
|
+
// order is important
|
|
305
|
+
this.addPublicIP(peerConnection, e.candidate.address);
|
|
295
306
|
this.setLatencyAndClose(peerConnection, elapsed);
|
|
296
307
|
}
|
|
297
308
|
};
|
|
@@ -309,8 +320,9 @@ export default class Reachability {
|
|
|
309
320
|
private iceGatheringState(peerConnection: RTCPeerConnection, timeout: number) {
|
|
310
321
|
const ELAPSED = 'elapsed';
|
|
311
322
|
|
|
312
|
-
return new Promise((resolve) => {
|
|
323
|
+
return new Promise<ICECandidateResult>((resolve) => {
|
|
313
324
|
const peerConnectionProxy = new window.Proxy(peerConnection, {
|
|
325
|
+
// eslint-disable-next-line require-jsdoc
|
|
314
326
|
get(target, property) {
|
|
315
327
|
const targetMember = target[property];
|
|
316
328
|
|
|
@@ -324,7 +336,7 @@ export default class Reachability {
|
|
|
324
336
|
// only intercept elapsed property
|
|
325
337
|
if (property === ELAPSED) {
|
|
326
338
|
// @ts-ignore
|
|
327
|
-
resolve({clusterId: peerConnection.key, elapsed: value});
|
|
339
|
+
resolve({clusterId: peerConnection.key, publicIPs: target.publicIPs, elapsed: value});
|
|
328
340
|
|
|
329
341
|
return true;
|
|
330
342
|
}
|
|
@@ -345,6 +357,8 @@ export default class Reachability {
|
|
|
345
357
|
|
|
346
358
|
// Close any open peerConnections
|
|
347
359
|
if (peerConnectionProxy.connectionState !== CLOSED) {
|
|
360
|
+
// order is important
|
|
361
|
+
this.addPublicIP(peerConnectionProxy, null);
|
|
348
362
|
this.setLatencyAndClose(peerConnectionProxy, null);
|
|
349
363
|
}
|
|
350
364
|
}, timeout);
|
|
@@ -369,24 +383,30 @@ export default class Reachability {
|
|
|
369
383
|
|
|
370
384
|
/**
|
|
371
385
|
* Calculates time to establish connection
|
|
372
|
-
* @param {
|
|
386
|
+
* @param {Array<ICECandidateResult>} iceResults iceResults
|
|
373
387
|
* @returns {object} reachabilityMap
|
|
374
|
-
* @
|
|
388
|
+
* @protected
|
|
375
389
|
* @memberof Reachability
|
|
376
390
|
*/
|
|
377
|
-
|
|
391
|
+
protected parseIceResultsToReachabilityResults(iceResults: Array<ICECandidateResult>) {
|
|
378
392
|
const reachabilityMap = {};
|
|
379
393
|
|
|
380
|
-
iceResults.forEach(({clusterId, elapsed}) => {
|
|
381
|
-
|
|
394
|
+
iceResults.forEach(({clusterId, elapsed, publicIPs}) => {
|
|
395
|
+
const latencyResult = {};
|
|
382
396
|
|
|
383
|
-
if (elapsed
|
|
384
|
-
latencyResult
|
|
397
|
+
if (!elapsed) {
|
|
398
|
+
Object.assign(latencyResult, {reachable: 'false'});
|
|
385
399
|
} else {
|
|
386
|
-
latencyResult
|
|
400
|
+
Object.assign(latencyResult, {
|
|
387
401
|
reachable: 'true',
|
|
388
402
|
latencyInMilliseconds: elapsed.toString(),
|
|
389
|
-
};
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (publicIPs) {
|
|
407
|
+
Object.assign(latencyResult, {
|
|
408
|
+
clientMediaIPs: publicIPs,
|
|
409
|
+
});
|
|
390
410
|
}
|
|
391
411
|
|
|
392
412
|
reachabilityMap[clusterId] = {
|
|
@@ -432,6 +452,33 @@ export default class Reachability {
|
|
|
432
452
|
});
|
|
433
453
|
}
|
|
434
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Adds public IP (client media IPs)
|
|
457
|
+
* @param {RTCPeerConnection} peerConnection
|
|
458
|
+
* @param {string} publicIP
|
|
459
|
+
* @returns {void}
|
|
460
|
+
*/
|
|
461
|
+
protected addPublicIP(peerConnection: RTCPeerConnection, publicIP?: string | null) {
|
|
462
|
+
const modifiedPeerConnection: RTCPeerConnection & {publicIPs?: string[]} = peerConnection;
|
|
463
|
+
const {CLOSED} = CONNECTION_STATE;
|
|
464
|
+
|
|
465
|
+
if (modifiedPeerConnection.connectionState === CLOSED) {
|
|
466
|
+
LoggerProxy.logger.log(
|
|
467
|
+
`Reachability:index#addPublicIP --> Attempting to set publicIP of ${publicIP} on closed peerConnection.`
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (publicIP) {
|
|
472
|
+
if (modifiedPeerConnection.publicIPs) {
|
|
473
|
+
modifiedPeerConnection.publicIPs.push(publicIP);
|
|
474
|
+
} else {
|
|
475
|
+
modifiedPeerConnection.publicIPs = [publicIP];
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
modifiedPeerConnection.publicIPs = null;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
435
482
|
/**
|
|
436
483
|
* Records latency and closes the peerConnection
|
|
437
484
|
* @param {RTCPeerConnection} peerConnection
|