@webex/plugin-meetings 3.0.0-beta.13 → 3.0.0-beta.130
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 -1
- package/UPGRADING.md +9 -9
- package/browsers.js +19 -24
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +48 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +355 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +193 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.js +23 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +43 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +994 -0
- package/dist/breakouts/index.js.map +1 -0
- 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/browser-detection.js +1 -20
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +5 -20
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +0 -7
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +5 -26
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +5 -26
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +6 -27
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +5 -26
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/parameter.js +5 -33
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +5 -26
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +4 -25
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reconnection-in-progress.js +0 -17
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +5 -26
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +5 -26
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +6 -41
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -24
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +0 -22
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +0 -23
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +0 -12
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +0 -15
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +0 -4
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -8
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +35 -61
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +4 -14
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +6 -6
- package/dist/config.js.map +1 -1
- package/dist/constants.js +201 -53
- 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 +294 -0
- package/dist/controls-options-manager/util.js.map +1 -0
- package/dist/index.js +72 -17
- package/dist/index.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +100 -29
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -26
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +0 -15
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +4 -12
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +392 -212
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +0 -38
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +54 -38
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +88 -123
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +99 -91
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +55 -165
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +71 -117
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +2 -9
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +505 -495
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +77 -14
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +2597 -2464
- 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 +292 -138
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +315 -336
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js +7 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +21 -31
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.js +463 -583
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +3 -25
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +10 -33
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +305 -286
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -16
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +98 -183
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +156 -232
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +24 -20
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +692 -593
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +23 -42
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +186 -155
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +89 -88
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +15 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +101 -69
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +12 -12
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +166 -205
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +120 -85
- 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 +314 -260
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/config.js +50 -16
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/constants.js +4 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +93 -162
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +167 -50
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +58 -65
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +74 -93
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +55 -74
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +6 -40
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +466 -442
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +32 -59
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +10 -45
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -33
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +0 -13
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/index.js +190 -199
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +14 -23
- package/dist/reachability/request.js.map +1 -1
- package/dist/reactions/constants.js +13 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.js +2 -4
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js +19 -23
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +326 -465
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +17 -0
- package/dist/recording-controller/enums.js.map +1 -0
- package/dist/recording-controller/index.js +343 -0
- package/dist/recording-controller/index.js.map +1 -0
- package/dist/recording-controller/util.js +63 -0
- package/dist/recording-controller/util.js.map +1 -0
- package/dist/roap/index.js +31 -75
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +129 -136
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +143 -103
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/global.js +1 -95
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +369 -461
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +144 -94
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +13 -45
- package/dist/transcription/index.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +35 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +124 -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 +2 -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 +32 -0
- package/dist/types/config.d.ts +78 -0
- package/dist/types/constants.d.ts +991 -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/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 +315 -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 +212 -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 +108 -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 +147 -0
- package/dist/types/meeting/index.d.ts +1762 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
- package/dist/types/meeting/muteState.d.ts +186 -0
- package/dist/types/meeting/request.d.ts +269 -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 +76 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +57 -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 +345 -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 +157 -0
- package/dist/types/member/types.d.ts +21 -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/config.d.ts +195 -0
- package/dist/types/metrics/constants.d.ts +55 -0
- package/dist/types/metrics/index.d.ts +169 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +101 -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 +263 -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 +193 -0
- package/dist/types/recording-controller/util.d.ts +13 -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/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/internal-README.md +7 -6
- package/package.json +28 -21
- package/src/annotation/annotation.types.ts +42 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +339 -0
- package/src/breakouts/README.md +220 -0
- package/src/breakouts/breakout.ts +163 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +37 -0
- package/src/breakouts/index.ts +860 -0
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/browser-detection.ts +9 -6
- package/src/common/collection.ts +3 -1
- package/src/common/errors/captcha-error.ts +6 -6
- package/src/common/errors/intent-to-join.ts +6 -6
- package/src/common/errors/join-meeting.ts +12 -8
- package/src/common/errors/media.ts +6 -6
- package/src/common/errors/parameter.ts +9 -6
- package/src/common/errors/password-error.ts +6 -6
- package/src/common/errors/permission.ts +5 -5
- package/src/common/errors/reconnection.ts +6 -6
- package/src/common/errors/stats.ts +6 -6
- package/src/common/errors/webex-errors.ts +7 -5
- package/src/common/errors/webex-meetings-error.ts +1 -1
- package/src/common/events/events-scope.ts +5 -1
- package/src/common/events/events.ts +5 -1
- package/src/common/events/trigger-proxy.ts +8 -3
- package/src/common/events/util.ts +1 -2
- package/src/common/logs/logger-proxy.ts +21 -10
- package/src/common/logs/request.ts +11 -8
- package/src/config.ts +16 -12
- package/src/constants.ts +151 -7
- 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 +281 -0
- package/src/index.ts +33 -0
- package/src/locus-info/controlsUtils.ts +142 -24
- package/src/locus-info/fullState.ts +15 -11
- package/src/locus-info/hostUtils.ts +4 -3
- package/src/locus-info/index.ts +335 -55
- package/src/locus-info/infoUtils.ts +12 -4
- package/src/locus-info/mediaSharesUtils.ts +52 -4
- package/src/locus-info/parser.ts +46 -68
- package/src/locus-info/selfUtils.ts +187 -56
- package/src/media/index.ts +139 -196
- package/src/media/properties.ts +43 -36
- package/src/media/util.ts +1 -1
- package/src/mediaQualityMetrics/config.ts +380 -378
- package/src/meeting/in-meeting-actions.ts +159 -3
- package/src/meeting/index.ts +2789 -1584
- package/src/meeting/locusMediaRequest.ts +309 -0
- package/src/meeting/muteState.ts +290 -72
- package/src/meeting/request.ts +247 -178
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/state.ts +45 -30
- package/src/meeting/util.ts +445 -395
- package/src/meeting-info/collection.ts +2 -1
- package/src/meeting-info/index.ts +32 -30
- package/src/meeting-info/meeting-info-v2.ts +235 -116
- package/src/meeting-info/request.ts +9 -3
- package/src/meeting-info/util.ts +54 -46
- package/src/meeting-info/utilv2.ts +71 -55
- package/src/meetings/collection.ts +21 -1
- package/src/meetings/index.ts +772 -437
- package/src/meetings/request.ts +29 -25
- package/src/meetings/util.ts +132 -33
- package/src/member/index.ts +95 -49
- package/src/member/types.ts +24 -0
- package/src/member/util.ts +106 -13
- package/src/members/collection.ts +8 -1
- package/src/members/index.ts +288 -130
- package/src/members/request.ts +144 -31
- package/src/members/types.ts +28 -0
- package/src/members/util.ts +316 -235
- package/src/metrics/config.ts +302 -90
- package/src/metrics/constants.ts +2 -6
- package/src/metrics/index.ts +124 -95
- package/src/multistream/mediaRequestManager.ts +203 -45
- package/src/multistream/receiveSlot.ts +69 -26
- package/src/multistream/receiveSlotManager.ts +62 -38
- package/src/multistream/remoteMedia.ts +30 -4
- package/src/multistream/remoteMediaGroup.ts +4 -3
- package/src/multistream/remoteMediaManager.ts +230 -66
- package/src/networkQualityMonitor/index.ts +24 -27
- package/src/personal-meeting-room/index.ts +12 -16
- package/src/personal-meeting-room/request.ts +10 -3
- package/src/personal-meeting-room/util.ts +3 -3
- package/src/reachability/index.ts +131 -79
- package/src/reachability/request.ts +43 -34
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +8 -8
- package/src/reactions/reactions.type.ts +31 -5
- package/src/reconnection-manager/index.ts +193 -111
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +315 -0
- package/src/recording-controller/util.ts +58 -0
- package/src/roap/index.ts +53 -53
- package/src/roap/request.ts +77 -64
- package/src/roap/turnDiscovery.ts +101 -48
- package/src/statsAnalyzer/global.ts +8 -104
- package/src/statsAnalyzer/index.ts +624 -376
- package/src/statsAnalyzer/mqaUtil.ts +203 -90
- package/src/transcription/index.ts +34 -32
- package/test/integration/spec/converged-space-meetings.js +177 -0
- package/test/integration/spec/journey.js +670 -466
- package/test/integration/spec/space-meeting.js +320 -204
- package/test/integration/spec/transcription.js +7 -8
- package/test/unit/spec/annotation/index.ts +433 -0
- package/test/unit/spec/breakouts/breakout.ts +203 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +77 -0
- package/test/unit/spec/breakouts/index.ts +1609 -0
- package/test/unit/spec/breakouts/request.ts +104 -0
- package/test/unit/spec/breakouts/utils.js +72 -0
- package/test/unit/spec/common/browser-detection.js +9 -28
- package/test/unit/spec/controls-options-manager/index.js +287 -0
- package/test/unit/spec/controls-options-manager/util.js +504 -0
- package/test/unit/spec/fixture/locus.js +93 -90
- package/test/unit/spec/locus-info/controlsUtils.js +305 -32
- package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
- package/test/unit/spec/locus-info/index.js +598 -5
- package/test/unit/spec/locus-info/infoUtils.js +26 -33
- package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
- package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
- package/test/unit/spec/locus-info/parser.js +3 -9
- package/test/unit/spec/locus-info/selfConstant.js +110 -103
- package/test/unit/spec/locus-info/selfUtils.js +236 -12
- package/test/unit/spec/media/index.ts +104 -8
- package/test/unit/spec/media/properties.ts +9 -9
- package/test/unit/spec/meeting/in-meeting-actions.ts +76 -3
- package/test/unit/spec/meeting/index.js +3094 -921
- package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
- package/test/unit/spec/meeting/muteState.js +421 -94
- package/test/unit/spec/meeting/request.js +421 -79
- package/test/unit/spec/meeting/utils.js +326 -189
- package/test/unit/spec/meeting-info/meetinginfov2.js +481 -76
- package/test/unit/spec/meeting-info/request.js +7 -9
- package/test/unit/spec/meeting-info/util.js +11 -12
- package/test/unit/spec/meeting-info/utilv2.js +131 -74
- package/test/unit/spec/meetings/collection.js +15 -1
- package/test/unit/spec/meetings/index.js +1126 -328
- package/test/unit/spec/meetings/utils.js +220 -14
- package/test/unit/spec/member/index.js +24 -1
- package/test/unit/spec/member/util.js +383 -32
- package/test/unit/spec/members/index.js +424 -55
- package/test/unit/spec/members/request.js +228 -40
- package/test/unit/spec/members/utils.js +191 -4
- package/test/unit/spec/metrics/index.js +113 -20
- package/test/unit/spec/multistream/mediaRequestManager.ts +650 -105
- package/test/unit/spec/multistream/receiveSlot.ts +76 -17
- package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
- package/test/unit/spec/multistream/remoteMedia.ts +32 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +549 -65
- package/test/unit/spec/networkQualityMonitor/index.js +24 -18
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
- package/test/unit/spec/reachability/index.ts +176 -27
- package/test/unit/spec/reachability/request.js +66 -0
- package/test/unit/spec/reconnection-manager/index.js +62 -31
- package/test/unit/spec/recording-controller/index.js +231 -0
- package/test/unit/spec/recording-controller/util.js +102 -0
- package/test/unit/spec/roap/index.ts +19 -49
- package/test/unit/spec/roap/request.ts +187 -0
- package/test/unit/spec/roap/turnDiscovery.ts +92 -50
- package/test/unit/spec/stats-analyzer/index.js +116 -60
- package/test/utils/cmr.js +44 -42
- package/test/utils/constants.js +9 -0
- package/test/utils/integrationTestUtils.js +64 -0
- package/test/utils/testUtils.js +63 -99
- package/test/utils/webex-config.js +22 -18
- package/test/utils/webex-test-users.js +57 -50
- package/tsconfig.json +6 -0
- package/dist/media/internal-media-core-wrapper.js +0 -22
- package/dist/media/internal-media-core-wrapper.js.map +0 -1
- package/dist/meeting/effectsState.js +0 -334
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/multistream/multistreamMedia.js +0 -116
- package/dist/multistream/multistreamMedia.js.map +0 -1
- package/src/index.js +0 -15
- package/src/media/internal-media-core-wrapper.ts +0 -9
- package/src/meeting/effectsState.ts +0 -211
- package/src/multistream/multistreamMedia.ts +0 -92
- package/test/unit/spec/meeting/effectsState.js +0 -291
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable require-jsdoc */
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {MediaType} from '@webex/internal-media-core';
|
|
5
5
|
import {
|
|
6
6
|
Configuration,
|
|
7
7
|
Event,
|
|
@@ -15,15 +15,18 @@ import {cloneDeep} from 'lodash';
|
|
|
15
15
|
import {MediaRequest} from '@webex/plugin-meetings/src/multistream/mediaRequestManager';
|
|
16
16
|
import {CSI, ReceiveSlotId} from '@webex/plugin-meetings/src/multistream/receiveSlot';
|
|
17
17
|
import testUtils from '../../../utils/testUtils';
|
|
18
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
19
|
+
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
20
|
+
import { expect } from 'chai';
|
|
18
21
|
|
|
19
22
|
class FakeSlot extends EventEmitter {
|
|
20
|
-
public mediaType:
|
|
23
|
+
public mediaType: MediaType;
|
|
21
24
|
|
|
22
25
|
public id: string;
|
|
23
26
|
|
|
24
27
|
public csi?: number;
|
|
25
28
|
|
|
26
|
-
constructor(mediaType:
|
|
29
|
+
constructor(mediaType: MediaType, id: string) {
|
|
27
30
|
super();
|
|
28
31
|
this.mediaType = mediaType;
|
|
29
32
|
this.id = id;
|
|
@@ -32,11 +35,16 @@ class FakeSlot extends EventEmitter {
|
|
|
32
35
|
// Calling setMaxListeners() fixes the warning.
|
|
33
36
|
this.setMaxListeners(50);
|
|
34
37
|
}
|
|
38
|
+
|
|
39
|
+
public get logString() {
|
|
40
|
+
return this.id;
|
|
41
|
+
}
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
const DefaultTestConfiguration: Configuration = {
|
|
38
45
|
audio: {
|
|
39
46
|
numOfActiveSpeakerStreams: 3,
|
|
47
|
+
numOfScreenShareStreams: 1,
|
|
40
48
|
},
|
|
41
49
|
video: {
|
|
42
50
|
preferLiveVideo: true,
|
|
@@ -44,7 +52,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
44
52
|
|
|
45
53
|
layouts: {
|
|
46
54
|
AllEqual: {
|
|
47
|
-
screenShareVideo: {size: null},
|
|
48
55
|
activeSpeakerVideoPaneGroups: [
|
|
49
56
|
{
|
|
50
57
|
id: 'main',
|
|
@@ -55,7 +62,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
55
62
|
],
|
|
56
63
|
},
|
|
57
64
|
OnePlusFive: {
|
|
58
|
-
screenShareVideo: {size: null},
|
|
59
65
|
activeSpeakerVideoPaneGroups: [
|
|
60
66
|
{
|
|
61
67
|
id: 'mainBigOne',
|
|
@@ -72,7 +78,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
72
78
|
],
|
|
73
79
|
},
|
|
74
80
|
Single: {
|
|
75
|
-
screenShareVideo: {size: null},
|
|
76
81
|
activeSpeakerVideoPaneGroups: [
|
|
77
82
|
{
|
|
78
83
|
id: 'main',
|
|
@@ -83,7 +88,6 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
83
88
|
],
|
|
84
89
|
},
|
|
85
90
|
Stage: {
|
|
86
|
-
screenShareVideo: {size: null},
|
|
87
91
|
activeSpeakerVideoPaneGroups: [
|
|
88
92
|
{
|
|
89
93
|
id: 'thumbnails',
|
|
@@ -99,12 +103,19 @@ const DefaultTestConfiguration: Configuration = {
|
|
|
99
103
|
{id: 'stage-4', size: 'medium', csi: undefined},
|
|
100
104
|
],
|
|
101
105
|
},
|
|
106
|
+
ScreenShareView: {
|
|
107
|
+
screenShareVideo: {size: 'medium'},
|
|
108
|
+
activeSpeakerVideoPaneGroups: [
|
|
109
|
+
{
|
|
110
|
+
id: 'thumbnails',
|
|
111
|
+
numPanes: 6,
|
|
112
|
+
size: 'thumbnail',
|
|
113
|
+
priority: 255,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
102
117
|
},
|
|
103
118
|
},
|
|
104
|
-
screenShare: {
|
|
105
|
-
audio: true,
|
|
106
|
-
video: true,
|
|
107
|
-
},
|
|
108
119
|
};
|
|
109
120
|
|
|
110
121
|
describe('RemoteMediaManager', () => {
|
|
@@ -113,18 +124,50 @@ describe('RemoteMediaManager', () => {
|
|
|
113
124
|
let fakeMediaRequestManagers;
|
|
114
125
|
let fakeAudioSlot;
|
|
115
126
|
let fakeVideoSlot;
|
|
127
|
+
let fakeScreenShareAudioSlot;
|
|
128
|
+
let fakeScreenShareVideoSlot;
|
|
129
|
+
|
|
130
|
+
const logger = {
|
|
131
|
+
log: sinon.fake(),
|
|
132
|
+
error: () => {},
|
|
133
|
+
warn: () => {},
|
|
134
|
+
trace: () => {},
|
|
135
|
+
debug: () => {},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
afterEach(() => {
|
|
139
|
+
LoggerConfig.set({enable: false});
|
|
140
|
+
LoggerProxy.set();
|
|
141
|
+
});
|
|
116
142
|
|
|
117
143
|
beforeEach(() => {
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
LoggerConfig.set({enable: true});
|
|
145
|
+
LoggerProxy.set(logger);
|
|
146
|
+
|
|
147
|
+
fakeAudioSlot = new FakeSlot(MediaType.AudioMain, 'fake audio slot');
|
|
148
|
+
fakeVideoSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
149
|
+
fakeScreenShareAudioSlot = new FakeSlot(
|
|
150
|
+
MediaType.AudioSlides,
|
|
151
|
+
'fake screen share audio slot'
|
|
152
|
+
);
|
|
153
|
+
fakeScreenShareVideoSlot = new FakeSlot(
|
|
154
|
+
MediaType.VideoSlides,
|
|
155
|
+
'fake screen share video slot'
|
|
156
|
+
);
|
|
120
157
|
|
|
121
158
|
fakeReceiveSlotManager = {
|
|
122
159
|
allocateSlot: sinon.stub().callsFake((mediaType) => {
|
|
123
|
-
|
|
124
|
-
|
|
160
|
+
switch (mediaType) {
|
|
161
|
+
case MediaType.AudioMain:
|
|
162
|
+
return Promise.resolve(fakeAudioSlot);
|
|
163
|
+
case MediaType.VideoMain:
|
|
164
|
+
return Promise.resolve(fakeVideoSlot);
|
|
165
|
+
case MediaType.AudioSlides:
|
|
166
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
167
|
+
case MediaType.VideoSlides:
|
|
168
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
125
169
|
}
|
|
126
|
-
|
|
127
|
-
return Promise.resolve(fakeVideoSlot);
|
|
170
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
128
171
|
}),
|
|
129
172
|
releaseSlot: sinon.stub(),
|
|
130
173
|
};
|
|
@@ -140,6 +183,16 @@ describe('RemoteMediaManager', () => {
|
|
|
140
183
|
cancelRequest: sinon.stub(),
|
|
141
184
|
commit: sinon.stub(),
|
|
142
185
|
},
|
|
186
|
+
screenShareAudio: {
|
|
187
|
+
addRequest: sinon.stub(),
|
|
188
|
+
cancelRequest: sinon.stub(),
|
|
189
|
+
commit: sinon.stub(),
|
|
190
|
+
},
|
|
191
|
+
screenShareVideo: {
|
|
192
|
+
addRequest: sinon.stub(),
|
|
193
|
+
cancelRequest: sinon.stub(),
|
|
194
|
+
commit: sinon.stub(),
|
|
195
|
+
},
|
|
143
196
|
};
|
|
144
197
|
|
|
145
198
|
// create remote media manager with default configuration
|
|
@@ -159,6 +212,9 @@ describe('RemoteMediaManager', () => {
|
|
|
159
212
|
fakeMediaRequestManagers.video.addRequest.resetHistory();
|
|
160
213
|
fakeMediaRequestManagers.video.cancelRequest.resetHistory();
|
|
161
214
|
fakeMediaRequestManagers.video.commit.resetHistory();
|
|
215
|
+
fakeMediaRequestManagers.screenShareVideo.commit.resetHistory();
|
|
216
|
+
fakeMediaRequestManagers.screenShareAudio.commit.resetHistory();
|
|
217
|
+
logger.log.resetHistory();
|
|
162
218
|
};
|
|
163
219
|
|
|
164
220
|
describe('start', () => {
|
|
@@ -176,8 +232,8 @@ describe('RemoteMediaManager', () => {
|
|
|
176
232
|
await remoteMediaManager.start();
|
|
177
233
|
|
|
178
234
|
// check that the 2nd start() creates slots and media requests and is not a no-op
|
|
179
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
180
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
235
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioMain);
|
|
236
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
181
237
|
|
|
182
238
|
assert.called(fakeMediaRequestManagers.audio.addRequest);
|
|
183
239
|
assert.called(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -187,25 +243,18 @@ describe('RemoteMediaManager', () => {
|
|
|
187
243
|
let createdAudioGroup: RemoteMediaGroup | null = null;
|
|
188
244
|
|
|
189
245
|
// create a config with just audio, no video at all and no screen share
|
|
190
|
-
const config = {
|
|
246
|
+
const config: Configuration = {
|
|
191
247
|
audio: {
|
|
192
248
|
numOfActiveSpeakerStreams: 5,
|
|
249
|
+
numOfScreenShareStreams: 0,
|
|
193
250
|
},
|
|
194
251
|
video: {
|
|
195
252
|
preferLiveVideo: false,
|
|
196
253
|
initialLayoutId: 'empty',
|
|
197
254
|
layouts: {
|
|
198
|
-
empty: {
|
|
199
|
-
screenShareVideo: {
|
|
200
|
-
size: null,
|
|
201
|
-
},
|
|
202
|
-
},
|
|
255
|
+
empty: {},
|
|
203
256
|
},
|
|
204
257
|
},
|
|
205
|
-
screenShare: {
|
|
206
|
-
audio: false,
|
|
207
|
-
video: false,
|
|
208
|
-
},
|
|
209
258
|
};
|
|
210
259
|
|
|
211
260
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -223,7 +272,7 @@ describe('RemoteMediaManager', () => {
|
|
|
223
272
|
await testUtils.flushPromises();
|
|
224
273
|
|
|
225
274
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 5);
|
|
226
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
275
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioMain);
|
|
227
276
|
|
|
228
277
|
assert.isNotNull(createdAudioGroup);
|
|
229
278
|
if (createdAudioGroup) {
|
|
@@ -231,7 +280,7 @@ describe('RemoteMediaManager', () => {
|
|
|
231
280
|
assert.isTrue(
|
|
232
281
|
createdAudioGroup
|
|
233
282
|
.getRemoteMedia()
|
|
234
|
-
.every((remoteMedia) => remoteMedia.mediaType ===
|
|
283
|
+
.every((remoteMedia) => remoteMedia.mediaType === MediaType.AudioMain)
|
|
235
284
|
);
|
|
236
285
|
assert.strictEqual(createdAudioGroup.getRemoteMedia('pinned').length, 0);
|
|
237
286
|
}
|
|
@@ -255,9 +304,6 @@ describe('RemoteMediaManager', () => {
|
|
|
255
304
|
|
|
256
305
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
257
306
|
config.video.layouts.huge = {
|
|
258
|
-
screenShareVideo: {
|
|
259
|
-
size: null,
|
|
260
|
-
},
|
|
261
307
|
activeSpeakerVideoPaneGroups: [
|
|
262
308
|
{
|
|
263
309
|
id: 'big one',
|
|
@@ -267,6 +313,8 @@ describe('RemoteMediaManager', () => {
|
|
|
267
313
|
},
|
|
268
314
|
],
|
|
269
315
|
};
|
|
316
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
317
|
+
delete config.video.layouts.ScreenShareView;
|
|
270
318
|
|
|
271
319
|
remoteMediaManager = new RemoteMediaManager(
|
|
272
320
|
fakeReceiveSlotManager,
|
|
@@ -279,7 +327,7 @@ describe('RemoteMediaManager', () => {
|
|
|
279
327
|
// even though our "big one" layout is not the default one, the remote media manager should still
|
|
280
328
|
// preallocate enough video receive slots for it up front
|
|
281
329
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 99);
|
|
282
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
330
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
283
331
|
});
|
|
284
332
|
|
|
285
333
|
it('starts with the initial layout', async () => {
|
|
@@ -302,8 +350,128 @@ describe('RemoteMediaManager', () => {
|
|
|
302
350
|
receivedLayoutInfo.activeSpeakerVideoPanes.main.getRemoteMedia().length,
|
|
303
351
|
9
|
|
304
352
|
);
|
|
353
|
+
assert.isUndefined(receivedLayoutInfo.screenShareVideo); // the initial layout has no screen share
|
|
305
354
|
}
|
|
306
355
|
});
|
|
356
|
+
|
|
357
|
+
it('creates RemoteMedia for screen share audio correctly', async () => {
|
|
358
|
+
let createdAudioGroup: RemoteMediaGroup | null = null;
|
|
359
|
+
|
|
360
|
+
const NUM_STREAMS = 2;
|
|
361
|
+
|
|
362
|
+
// create a config with just screen share audio, nothing else
|
|
363
|
+
const config: Configuration = {
|
|
364
|
+
audio: {
|
|
365
|
+
numOfActiveSpeakerStreams: 0,
|
|
366
|
+
numOfScreenShareStreams: NUM_STREAMS,
|
|
367
|
+
},
|
|
368
|
+
video: {
|
|
369
|
+
preferLiveVideo: false,
|
|
370
|
+
initialLayoutId: 'empty',
|
|
371
|
+
layouts: {
|
|
372
|
+
empty: {},
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
378
|
+
fakeReceiveSlotManager,
|
|
379
|
+
fakeMediaRequestManagers,
|
|
380
|
+
config
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
remoteMediaManager.on(Event.ScreenShareAudioCreated, (audio: RemoteMediaGroup) => {
|
|
384
|
+
createdAudioGroup = audio;
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
remoteMediaManager.start();
|
|
388
|
+
|
|
389
|
+
await testUtils.flushPromises();
|
|
390
|
+
|
|
391
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, NUM_STREAMS);
|
|
392
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.AudioSlides);
|
|
393
|
+
|
|
394
|
+
assert.isNotNull(createdAudioGroup);
|
|
395
|
+
if (createdAudioGroup) {
|
|
396
|
+
assert.strictEqual(createdAudioGroup.getRemoteMedia().length, NUM_STREAMS);
|
|
397
|
+
assert.isTrue(
|
|
398
|
+
createdAudioGroup
|
|
399
|
+
.getRemoteMedia()
|
|
400
|
+
.every((remoteMedia) => remoteMedia.mediaType === MediaType.AudioSlides)
|
|
401
|
+
);
|
|
402
|
+
assert.strictEqual(createdAudioGroup.getRemoteMedia('pinned').length, 0);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareAudio.addRequest);
|
|
406
|
+
assert.calledWith(
|
|
407
|
+
fakeMediaRequestManagers.screenShareAudio.addRequest,
|
|
408
|
+
sinon.match({
|
|
409
|
+
policyInfo: sinon.match({
|
|
410
|
+
policy: 'active-speaker',
|
|
411
|
+
priority: 255,
|
|
412
|
+
}),
|
|
413
|
+
receiveSlots: Array(NUM_STREAMS).fill(fakeScreenShareAudioSlot),
|
|
414
|
+
codecInfo: undefined,
|
|
415
|
+
})
|
|
416
|
+
);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('creates a single receive slot for screen share video if any layout has screen share', async () => {
|
|
420
|
+
// create a config with 2 layouts that use screen share
|
|
421
|
+
const config: Configuration = {
|
|
422
|
+
audio: {
|
|
423
|
+
numOfActiveSpeakerStreams: 0,
|
|
424
|
+
numOfScreenShareStreams: 0,
|
|
425
|
+
},
|
|
426
|
+
video: {
|
|
427
|
+
preferLiveVideo: false,
|
|
428
|
+
initialLayoutId: 'first',
|
|
429
|
+
layouts: {
|
|
430
|
+
first: {
|
|
431
|
+
screenShareVideo: { size: 'small'}
|
|
432
|
+
},
|
|
433
|
+
second: {
|
|
434
|
+
screenShareVideo: { size: 'medium'}
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
441
|
+
fakeReceiveSlotManager,
|
|
442
|
+
fakeMediaRequestManagers,
|
|
443
|
+
config
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
await remoteMediaManager.start();
|
|
447
|
+
|
|
448
|
+
// even though 2 layouts use screen share, only 1 video screen share slot should be created
|
|
449
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 1);
|
|
450
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoSlides);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('does not create any receive slot for screen share video if none of the layouts have screen share', async () => {
|
|
454
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
455
|
+
|
|
456
|
+
config.audio.numOfActiveSpeakerStreams = 0;
|
|
457
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
458
|
+
|
|
459
|
+
// delete the only layout that uses screen share
|
|
460
|
+
delete config.video.layouts.ScreenShareView;
|
|
461
|
+
|
|
462
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
463
|
+
fakeReceiveSlotManager,
|
|
464
|
+
fakeMediaRequestManagers,
|
|
465
|
+
config
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
await remoteMediaManager.start();
|
|
469
|
+
|
|
470
|
+
// we don't expect any audio and for video there should be no VideoSlides, so all the calls should be just for VideoMain
|
|
471
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
|
|
307
475
|
});
|
|
308
476
|
|
|
309
477
|
describe('constructor', () => {
|
|
@@ -325,7 +493,6 @@ describe('RemoteMediaManager', () => {
|
|
|
325
493
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
326
494
|
|
|
327
495
|
config.video.layouts.test = {
|
|
328
|
-
screenShareVideo: {size: null},
|
|
329
496
|
activeSpeakerVideoPaneGroups: [
|
|
330
497
|
{
|
|
331
498
|
id: 'someDuplicate',
|
|
@@ -361,7 +528,6 @@ describe('RemoteMediaManager', () => {
|
|
|
361
528
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
362
529
|
|
|
363
530
|
config.video.layouts.test = {
|
|
364
|
-
screenShareVideo: {size: null},
|
|
365
531
|
activeSpeakerVideoPaneGroups: [
|
|
366
532
|
{
|
|
367
533
|
id: 'group1',
|
|
@@ -397,7 +563,6 @@ describe('RemoteMediaManager', () => {
|
|
|
397
563
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
398
564
|
|
|
399
565
|
config.video.layouts.test = {
|
|
400
|
-
screenShareVideo: {size: null},
|
|
401
566
|
memberVideoPanes: [
|
|
402
567
|
{id: 'paneA', size: 'best', csi: 123},
|
|
403
568
|
{id: 'paneB', size: 'large', csi: 222},
|
|
@@ -414,6 +579,7 @@ describe('RemoteMediaManager', () => {
|
|
|
414
579
|
);
|
|
415
580
|
}, 'invalid config: duplicate member video pane id: paneB');
|
|
416
581
|
});
|
|
582
|
+
|
|
417
583
|
});
|
|
418
584
|
|
|
419
585
|
describe('stop', () => {
|
|
@@ -421,12 +587,17 @@ describe('RemoteMediaManager', () => {
|
|
|
421
587
|
let audioStopStub;
|
|
422
588
|
let videoActiveSpeakerGroupStopStub;
|
|
423
589
|
const memberVideoPaneStopStubs: any[] = [];
|
|
590
|
+
let screenShareAudioStopStub;
|
|
591
|
+
let screenShareVideoStopStub;
|
|
424
592
|
|
|
425
|
-
// change the initial layout to one that has both active speakers and
|
|
593
|
+
// change the initial layout to one that has both active speakers and receiver selected videos
|
|
426
594
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
427
595
|
|
|
428
596
|
config.video.initialLayoutId = 'Stage';
|
|
429
597
|
|
|
598
|
+
// and also modify it to have screen share so we can test that too
|
|
599
|
+
config.video.layouts['Stage'].screenShareVideo = {size: 'medium'};
|
|
600
|
+
|
|
430
601
|
remoteMediaManager = new RemoteMediaManager(
|
|
431
602
|
fakeReceiveSlotManager,
|
|
432
603
|
fakeMediaRequestManagers,
|
|
@@ -437,6 +608,10 @@ describe('RemoteMediaManager', () => {
|
|
|
437
608
|
audioStopStub = sinon.stub(audio, 'stop');
|
|
438
609
|
});
|
|
439
610
|
|
|
611
|
+
remoteMediaManager.on(Event.ScreenShareAudioCreated, (audio: RemoteMediaGroup) => {
|
|
612
|
+
screenShareAudioStopStub = sinon.stub(audio, 'stop');
|
|
613
|
+
});
|
|
614
|
+
|
|
440
615
|
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
441
616
|
// The "Stage" layout that we're using has only 1 active speaker group called "thumbnails"
|
|
442
617
|
videoActiveSpeakerGroupStopStub = sinon.stub(
|
|
@@ -447,12 +622,14 @@ describe('RemoteMediaManager', () => {
|
|
|
447
622
|
Object.values(layoutInfo.memberVideoPanes).forEach((pane) => {
|
|
448
623
|
memberVideoPaneStopStubs.push(sinon.stub(pane, 'stop'));
|
|
449
624
|
});
|
|
625
|
+
|
|
626
|
+
screenShareVideoStopStub = sinon.stub(layoutInfo.screenShareVideo, 'stop');
|
|
450
627
|
});
|
|
451
628
|
|
|
452
629
|
await remoteMediaManager.start();
|
|
453
630
|
|
|
454
|
-
// we're using the default config that requires 3 main audio slots
|
|
455
|
-
assert.callCount(fakeReceiveSlotManager.allocateSlot,
|
|
631
|
+
// we're using the default config that requires 3 main audio slots, 10 video slots (for Stage2x2With6ThumbnailsLayout), 1 screenshare audio, 1 screenshare video
|
|
632
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 15);
|
|
456
633
|
|
|
457
634
|
// our layout has 4 member video panes, we should have a stub for each of these panes' stop methods
|
|
458
635
|
assert.strictEqual(memberVideoPaneStopStubs.length, 4);
|
|
@@ -462,16 +639,20 @@ describe('RemoteMediaManager', () => {
|
|
|
462
639
|
remoteMediaManager.stop();
|
|
463
640
|
|
|
464
641
|
// check that all slots have been released
|
|
465
|
-
assert.callCount(fakeReceiveSlotManager.releaseSlot,
|
|
642
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 15);
|
|
466
643
|
|
|
467
644
|
// and that all RemoteMedia and RemoteMediaGroups have been stopped
|
|
468
645
|
assert.calledOnce(audioStopStub);
|
|
469
646
|
assert.calledWith(audioStopStub, true);
|
|
647
|
+
assert.calledOnce(screenShareAudioStopStub);
|
|
648
|
+
assert.calledWith(screenShareAudioStopStub, true);
|
|
470
649
|
assert.calledOnce(videoActiveSpeakerGroupStopStub);
|
|
471
650
|
memberVideoPaneStopStubs.forEach((stub) => {
|
|
472
651
|
assert.calledOnce(stub);
|
|
473
652
|
});
|
|
474
653
|
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
654
|
+
assert.calledOnce(screenShareVideoStopStub);
|
|
655
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.commit);
|
|
475
656
|
});
|
|
476
657
|
|
|
477
658
|
it('can be called multiple times', async () => {
|
|
@@ -511,9 +692,53 @@ describe('RemoteMediaManager', () => {
|
|
|
511
692
|
await remoteMediaManager.setLayout('Stage');
|
|
512
693
|
|
|
513
694
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 9);
|
|
514
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
695
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
515
696
|
});
|
|
516
697
|
|
|
698
|
+
it('logs layout changes - receiver selected', async () => {
|
|
699
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
700
|
+
|
|
701
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
702
|
+
fakeReceiveSlotManager,
|
|
703
|
+
fakeMediaRequestManagers,
|
|
704
|
+
config
|
|
705
|
+
);
|
|
706
|
+
|
|
707
|
+
await remoteMediaManager.start();
|
|
708
|
+
|
|
709
|
+
resetHistory();
|
|
710
|
+
|
|
711
|
+
await remoteMediaManager.setLayout('Stage');
|
|
712
|
+
|
|
713
|
+
assert.calledWith(
|
|
714
|
+
logger.log,
|
|
715
|
+
'RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=0, activeSpeaker=6, receiverSelected=4\ngroup: thumbnails\nfake video slot fake video slot fake video slot fake video slot fake video slot fake video slot\nreceiverSelected:\n stage-1: fake video slot\n stage-2: fake video slot\n stage-3: fake video slot\n stage-4: fake video slot\n'
|
|
716
|
+
);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('logs layout changes - active speaker', async () => {
|
|
720
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
721
|
+
config.video.initialLayoutId = 'OnePlusFive'
|
|
722
|
+
|
|
723
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
724
|
+
fakeReceiveSlotManager,
|
|
725
|
+
fakeMediaRequestManagers,
|
|
726
|
+
config
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
await remoteMediaManager.start();
|
|
730
|
+
|
|
731
|
+
resetHistory();
|
|
732
|
+
|
|
733
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
734
|
+
|
|
735
|
+
assert.calledWith(
|
|
736
|
+
logger.log,
|
|
737
|
+
'RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=0, activeSpeaker=9, receiverSelected=0\ngroup: main\nfake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot\nreceiverSelected:\n'
|
|
738
|
+
);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
|
|
517
742
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
518
743
|
// start with "AllEqual" layout that needs just 9 video slots
|
|
519
744
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
@@ -538,10 +763,137 @@ describe('RemoteMediaManager', () => {
|
|
|
538
763
|
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
539
764
|
const slot = call.args[0];
|
|
540
765
|
|
|
541
|
-
assert.strictEqual(slot.mediaType,
|
|
766
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
542
767
|
});
|
|
543
768
|
});
|
|
544
769
|
|
|
770
|
+
it('releases slots and reallocates slots when switching to layouts in correct order', async () => {
|
|
771
|
+
|
|
772
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
773
|
+
let count = 0;
|
|
774
|
+
|
|
775
|
+
fakeReceiveSlotManager.allocateSlot = sinon.stub().callsFake((mediaType) => {
|
|
776
|
+
switch (mediaType) {
|
|
777
|
+
case MediaType.AudioMain:
|
|
778
|
+
return Promise.resolve(fakeAudioSlot);
|
|
779
|
+
case MediaType.VideoMain:
|
|
780
|
+
return Promise.resolve(new FakeSlot(MediaType.VideoMain, `fake video ${count++}`));
|
|
781
|
+
case MediaType.AudioSlides:
|
|
782
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
783
|
+
case MediaType.VideoSlides:
|
|
784
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
785
|
+
}
|
|
786
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
787
|
+
})
|
|
788
|
+
|
|
789
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
790
|
+
fakeReceiveSlotManager,
|
|
791
|
+
fakeMediaRequestManagers,
|
|
792
|
+
config
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
await remoteMediaManager.start();
|
|
796
|
+
|
|
797
|
+
resetHistory();
|
|
798
|
+
|
|
799
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
800
|
+
"fake video 0",
|
|
801
|
+
"fake video 1",
|
|
802
|
+
"fake video 2",
|
|
803
|
+
"fake video 3",
|
|
804
|
+
"fake video 4",
|
|
805
|
+
"fake video 5",
|
|
806
|
+
"fake video 6",
|
|
807
|
+
"fake video 7",
|
|
808
|
+
"fake video 8",
|
|
809
|
+
]);
|
|
810
|
+
|
|
811
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
812
|
+
"fake video 0",
|
|
813
|
+
"fake video 1",
|
|
814
|
+
"fake video 2",
|
|
815
|
+
"fake video 3",
|
|
816
|
+
"fake video 4",
|
|
817
|
+
"fake video 5",
|
|
818
|
+
"fake video 6",
|
|
819
|
+
"fake video 7",
|
|
820
|
+
"fake video 8",
|
|
821
|
+
])
|
|
822
|
+
|
|
823
|
+
// switch to "OnePlusFive" layout that requires 3 less video slots (6)
|
|
824
|
+
await remoteMediaManager.setLayout('OnePlusFive');
|
|
825
|
+
|
|
826
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
827
|
+
|
|
828
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
829
|
+
"fake video 0",
|
|
830
|
+
"fake video 1",
|
|
831
|
+
"fake video 2",
|
|
832
|
+
"fake video 3",
|
|
833
|
+
"fake video 4",
|
|
834
|
+
"fake video 5"
|
|
835
|
+
]);
|
|
836
|
+
|
|
837
|
+
// we're checking that the slots are in the same order as in the previous layout
|
|
838
|
+
// first one goes into main
|
|
839
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["mainBigOne"].slots.map((slot: any) => slot.id), [
|
|
840
|
+
"fake video 0",
|
|
841
|
+
])
|
|
842
|
+
// and rest go in the pips
|
|
843
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["secondarySetOfSmallPanes"].slots.map((slot: any) => slot.id), [
|
|
844
|
+
"fake video 1",
|
|
845
|
+
"fake video 2",
|
|
846
|
+
"fake video 3",
|
|
847
|
+
"fake video 4",
|
|
848
|
+
"fake video 5"
|
|
849
|
+
])
|
|
850
|
+
|
|
851
|
+
// verify that 3 main video slots were released
|
|
852
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 3);
|
|
853
|
+
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
854
|
+
const slot = call.args[0];
|
|
855
|
+
|
|
856
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
860
|
+
|
|
861
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
862
|
+
|
|
863
|
+
// checking that slots are in the same order as in previous layout + 3 new ones
|
|
864
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
865
|
+
"fake video 0",
|
|
866
|
+
"fake video 1",
|
|
867
|
+
"fake video 2",
|
|
868
|
+
"fake video 3",
|
|
869
|
+
"fake video 4",
|
|
870
|
+
"fake video 5",
|
|
871
|
+
"fake video 10",
|
|
872
|
+
"fake video 11",
|
|
873
|
+
"fake video 12",
|
|
874
|
+
]);
|
|
875
|
+
|
|
876
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
877
|
+
"fake video 0",
|
|
878
|
+
"fake video 1",
|
|
879
|
+
"fake video 2",
|
|
880
|
+
"fake video 3",
|
|
881
|
+
"fake video 4",
|
|
882
|
+
"fake video 5",
|
|
883
|
+
"fake video 10",
|
|
884
|
+
"fake video 11",
|
|
885
|
+
"fake video 12"
|
|
886
|
+
])
|
|
887
|
+
|
|
888
|
+
// verify that 3 main video slots were allocated
|
|
889
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 3);
|
|
890
|
+
fakeReceiveSlotManager.allocateSlot.getCalls().forEach((call) => {
|
|
891
|
+
const mediaType = call.args[0];
|
|
892
|
+
|
|
893
|
+
assert.strictEqual(mediaType, MediaType.VideoMain);
|
|
894
|
+
});
|
|
895
|
+
});
|
|
896
|
+
|
|
545
897
|
it('stops all current video remoteMedia instances when switching to new layout', async () => {
|
|
546
898
|
const audioStopStubs = [];
|
|
547
899
|
const videoStopStubs = [];
|
|
@@ -600,6 +952,104 @@ describe('RemoteMediaManager', () => {
|
|
|
600
952
|
});
|
|
601
953
|
});
|
|
602
954
|
|
|
955
|
+
it('emits Event.VideoLayoutChanged with correct data', async () => {
|
|
956
|
+
// setup the initial layout to be empty and a testLayout that has screen share, active speaker groups and member video panes
|
|
957
|
+
const config: Configuration = {
|
|
958
|
+
audio: {
|
|
959
|
+
numOfActiveSpeakerStreams: 0,
|
|
960
|
+
numOfScreenShareStreams: 0,
|
|
961
|
+
},
|
|
962
|
+
video: {
|
|
963
|
+
preferLiveVideo: true,
|
|
964
|
+
initialLayoutId: 'empty',
|
|
965
|
+
layouts: {
|
|
966
|
+
empty: {},
|
|
967
|
+
testLayout: {
|
|
968
|
+
screenShareVideo: {size: 'very small'},
|
|
969
|
+
activeSpeakerVideoPaneGroups: [
|
|
970
|
+
{
|
|
971
|
+
id: 'big',
|
|
972
|
+
numPanes: 10,
|
|
973
|
+
priority: 255,
|
|
974
|
+
size: 'large',
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
id: 'small',
|
|
978
|
+
numPanes: 3,
|
|
979
|
+
priority: 254,
|
|
980
|
+
size: 'medium',
|
|
981
|
+
},
|
|
982
|
+
],
|
|
983
|
+
memberVideoPanes: [
|
|
984
|
+
{id: 'pane 1', size: 'best', csi: 555},
|
|
985
|
+
{id: 'pane 2', size: 'best', csi: undefined},
|
|
986
|
+
],
|
|
987
|
+
},
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
993
|
+
fakeReceiveSlotManager,
|
|
994
|
+
fakeMediaRequestManagers,
|
|
995
|
+
config
|
|
996
|
+
);
|
|
997
|
+
|
|
998
|
+
await remoteMediaManager.start();
|
|
999
|
+
|
|
1000
|
+
resetHistory();
|
|
1001
|
+
|
|
1002
|
+
let receivedLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1003
|
+
|
|
1004
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo) => {
|
|
1005
|
+
receivedLayoutInfo = layoutInfo;
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
// switch to the test layout
|
|
1009
|
+
await remoteMediaManager.setLayout('testLayout');
|
|
1010
|
+
|
|
1011
|
+
assert.isNotNull(receivedLayoutInfo);
|
|
1012
|
+
|
|
1013
|
+
if (receivedLayoutInfo) {
|
|
1014
|
+
assert.strictEqual(receivedLayoutInfo.layoutId, 'testLayout');
|
|
1015
|
+
|
|
1016
|
+
// check screen share video
|
|
1017
|
+
assert.isTrue(!!receivedLayoutInfo.screenShareVideo);
|
|
1018
|
+
assert.strictEqual(receivedLayoutInfo.screenShareVideo.mediaType, MediaType.VideoSlides);
|
|
1019
|
+
|
|
1020
|
+
// check member videos
|
|
1021
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.memberVideoPanes).length, 2);
|
|
1022
|
+
Object.values(receivedLayoutInfo.memberVideoPanes).forEach((remoteMedia) =>
|
|
1023
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1024
|
+
);
|
|
1025
|
+
|
|
1026
|
+
// check the 2 active speaker groups
|
|
1027
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.activeSpeakerVideoPanes).length, 2);
|
|
1028
|
+
|
|
1029
|
+
// "big" group
|
|
1030
|
+
assert.strictEqual(
|
|
1031
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big.getRemoteMedia().length,
|
|
1032
|
+
10
|
|
1033
|
+
);
|
|
1034
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big
|
|
1035
|
+
.getRemoteMedia()
|
|
1036
|
+
.forEach((remoteMedia) =>
|
|
1037
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1038
|
+
);
|
|
1039
|
+
|
|
1040
|
+
// "small" group
|
|
1041
|
+
assert.strictEqual(
|
|
1042
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small.getRemoteMedia().length,
|
|
1043
|
+
3
|
|
1044
|
+
);
|
|
1045
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small
|
|
1046
|
+
.getRemoteMedia()
|
|
1047
|
+
.forEach((remoteMedia) =>
|
|
1048
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
|
|
603
1053
|
describe('switching between different receiver selected layouts', () => {
|
|
604
1054
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
605
1055
|
let slotCounter: number;
|
|
@@ -620,7 +1070,7 @@ describe('RemoteMediaManager', () => {
|
|
|
620
1070
|
slotCounter += 1;
|
|
621
1071
|
const newSlotId = `fake video slot ${slotCounter}`;
|
|
622
1072
|
|
|
623
|
-
fakeSlots[newSlotId] = new FakeSlot(
|
|
1073
|
+
fakeSlots[newSlotId] = new FakeSlot(MediaType.VideoMain, newSlotId);
|
|
624
1074
|
return fakeSlots[newSlotId];
|
|
625
1075
|
});
|
|
626
1076
|
|
|
@@ -652,12 +1102,12 @@ describe('RemoteMediaManager', () => {
|
|
|
652
1102
|
// This test starts with a layout that has 5 receiver selected video slots
|
|
653
1103
|
// and switches to a different layout that has fewer slots, but 2 of them match CSIs
|
|
654
1104
|
// from the initial layout. We want to verify that these 2 slots get re-used correctly.
|
|
1105
|
+
// There are no screen share or audio slots being used in this test.
|
|
1106
|
+
delete config.video.layouts.ScreenShareView;
|
|
655
1107
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
656
|
-
config.
|
|
657
|
-
config.screenShare.video = false;
|
|
1108
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
658
1109
|
config.video.initialLayoutId = 'biggerLayout';
|
|
659
1110
|
config.video.layouts['biggerLayout'] = {
|
|
660
|
-
screenShareVideo: {size: null},
|
|
661
1111
|
memberVideoPanes: [
|
|
662
1112
|
{id: '1', size: 'best', csi: 100},
|
|
663
1113
|
{id: '2', size: 'best', csi: 200},
|
|
@@ -667,7 +1117,6 @@ describe('RemoteMediaManager', () => {
|
|
|
667
1117
|
],
|
|
668
1118
|
};
|
|
669
1119
|
config.video.layouts['smallerLayout'] = {
|
|
670
|
-
screenShareVideo: {size: null},
|
|
671
1120
|
memberVideoPanes: [
|
|
672
1121
|
{id: '1', size: 'medium', csi: 200}, // this csi matches pane '2' from biggerLayout
|
|
673
1122
|
{id: '2', size: 'medium', csi: 123},
|
|
@@ -717,16 +1166,15 @@ describe('RemoteMediaManager', () => {
|
|
|
717
1166
|
// This test starts with a layout that has video slot with a specific CSI
|
|
718
1167
|
// and switches to a different layout that 2 panes with that same CSI.
|
|
719
1168
|
// We want to verify that the slot gets reused, but also that a 2nd slot is allocated.
|
|
1169
|
+
// There are no screen share or audio slots being used in this test.
|
|
1170
|
+
delete config.video.layouts.ScreenShareView;
|
|
720
1171
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
721
|
-
config.
|
|
722
|
-
config.screenShare.video = false;
|
|
1172
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
723
1173
|
config.video.initialLayoutId = 'initialEmptyLayout';
|
|
724
1174
|
config.video.layouts['initialEmptyLayout'] = {
|
|
725
|
-
screenShareVideo: {size: null},
|
|
726
1175
|
memberVideoPanes: [{id: '2', size: 'medium', csi: 456}],
|
|
727
1176
|
};
|
|
728
1177
|
config.video.layouts['layoutWithDuplicateCSIs'] = {
|
|
729
|
-
screenShareVideo: {size: null},
|
|
730
1178
|
memberVideoPanes: [
|
|
731
1179
|
{id: '1', size: 'medium', csi: 123},
|
|
732
1180
|
{id: '2', size: 'medium', csi: 456},
|
|
@@ -899,16 +1347,18 @@ describe('RemoteMediaManager', () => {
|
|
|
899
1347
|
});
|
|
900
1348
|
|
|
901
1349
|
it('cancels all media requests for the previous layout when switching to a new one', async () => {
|
|
1350
|
+
// setup the initial layout to have screen share, active speaker groups and member video panes
|
|
902
1351
|
const config: Configuration = {
|
|
903
1352
|
audio: {
|
|
904
1353
|
numOfActiveSpeakerStreams: 0,
|
|
1354
|
+
numOfScreenShareStreams: 0,
|
|
905
1355
|
},
|
|
906
1356
|
video: {
|
|
907
1357
|
preferLiveVideo: true,
|
|
908
1358
|
initialLayoutId: 'initial',
|
|
909
1359
|
layouts: {
|
|
910
1360
|
initial: {
|
|
911
|
-
screenShareVideo: {size:
|
|
1361
|
+
screenShareVideo: {size: 'best'},
|
|
912
1362
|
activeSpeakerVideoPaneGroups: [
|
|
913
1363
|
{
|
|
914
1364
|
id: 'big',
|
|
@@ -928,15 +1378,9 @@ describe('RemoteMediaManager', () => {
|
|
|
928
1378
|
{id: 'pane 2', size: 'best', csi: 234},
|
|
929
1379
|
],
|
|
930
1380
|
},
|
|
931
|
-
other: {
|
|
932
|
-
screenShareVideo: {size: null},
|
|
933
|
-
},
|
|
1381
|
+
other: {},
|
|
934
1382
|
},
|
|
935
1383
|
},
|
|
936
|
-
screenShare: {
|
|
937
|
-
audio: false,
|
|
938
|
-
video: false,
|
|
939
|
-
},
|
|
940
1384
|
};
|
|
941
1385
|
|
|
942
1386
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -959,9 +1403,15 @@ describe('RemoteMediaManager', () => {
|
|
|
959
1403
|
|
|
960
1404
|
return `receiver selected request ${receiverSelectedRequestCounter}`;
|
|
961
1405
|
});
|
|
1406
|
+
// setup the mock for screen share addRequest - this one should be called just once
|
|
1407
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest.callsFake(() => {
|
|
1408
|
+
return 'video screen share request id';
|
|
1409
|
+
});
|
|
962
1410
|
|
|
963
1411
|
await remoteMediaManager.start();
|
|
964
1412
|
|
|
1413
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.addRequest);
|
|
1414
|
+
|
|
965
1415
|
resetHistory();
|
|
966
1416
|
|
|
967
1417
|
// switch to "other" layout
|
|
@@ -979,11 +1429,45 @@ describe('RemoteMediaManager', () => {
|
|
|
979
1429
|
fakeMediaRequestManagers.video.cancelRequest,
|
|
980
1430
|
'receiver selected request 2'
|
|
981
1431
|
);
|
|
1432
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.cancelRequest);
|
|
1433
|
+
assert.calledWith(
|
|
1434
|
+
fakeMediaRequestManagers.screenShareVideo.cancelRequest,
|
|
1435
|
+
'video screen share request id'
|
|
1436
|
+
);
|
|
982
1437
|
|
|
983
1438
|
// new layout has no videos, so no new requests should be sent out
|
|
984
|
-
// check that 2 correct active speaker media requests were sent out
|
|
985
1439
|
assert.callCount(fakeMediaRequestManagers.video.addRequest, 0);
|
|
986
1440
|
});
|
|
1441
|
+
|
|
1442
|
+
it('sends media request for screen share if layout contains screen share', async () => {
|
|
1443
|
+
const allEqualMediaRequestId = 'fake request id';
|
|
1444
|
+
|
|
1445
|
+
fakeMediaRequestManagers.video.addRequest.returns(allEqualMediaRequestId);
|
|
1446
|
+
|
|
1447
|
+
await remoteMediaManager.start();
|
|
1448
|
+
|
|
1449
|
+
resetHistory();
|
|
1450
|
+
|
|
1451
|
+
// switch to a layout that contains a screen share video pane
|
|
1452
|
+
await remoteMediaManager.setLayout('ScreenShareView');
|
|
1453
|
+
|
|
1454
|
+
// check that a correct active speaker media request for screen share has been sent out
|
|
1455
|
+
assert.callCount(fakeMediaRequestManagers.screenShareVideo.addRequest, 1);
|
|
1456
|
+
assert.calledWith(
|
|
1457
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest,
|
|
1458
|
+
sinon.match({
|
|
1459
|
+
policyInfo: sinon.match({
|
|
1460
|
+
policy: 'active-speaker',
|
|
1461
|
+
priority: 255,
|
|
1462
|
+
}),
|
|
1463
|
+
receiveSlots: [fakeScreenShareVideoSlot],
|
|
1464
|
+
codecInfo: sinon.match({
|
|
1465
|
+
codec: 'h264',
|
|
1466
|
+
maxFs: 3600,
|
|
1467
|
+
}),
|
|
1468
|
+
})
|
|
1469
|
+
);
|
|
1470
|
+
});
|
|
987
1471
|
});
|
|
988
1472
|
});
|
|
989
1473
|
|
|
@@ -1123,7 +1607,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1123
1607
|
|
|
1124
1608
|
// new slot should be allocated
|
|
1125
1609
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1126
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1610
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1127
1611
|
|
|
1128
1612
|
// and a media request sent out
|
|
1129
1613
|
assert.calledOnce(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1152,7 +1636,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1152
1636
|
|
|
1153
1637
|
// new slot should be allocated
|
|
1154
1638
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1155
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1639
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1156
1640
|
|
|
1157
1641
|
// but no media requests sent out
|
|
1158
1642
|
assert.notCalled(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1181,7 +1665,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1181
1665
|
await remoteMediaManager.start();
|
|
1182
1666
|
await remoteMediaManager.setLayout('Stage');
|
|
1183
1667
|
|
|
1184
|
-
const fakeNewSlot = new FakeSlot(
|
|
1668
|
+
const fakeNewSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
1185
1669
|
const fakeRequestId = 'fake request id';
|
|
1186
1670
|
|
|
1187
1671
|
fakeReceiveSlotManager.allocateSlot.resolves(fakeNewSlot);
|