@webex/plugin-meetings 3.0.0-beta.14 → 3.0.0-beta.141
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 +1012 -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 +204 -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 +300 -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 +398 -216
- 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 +89 -124
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +94 -92
- 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 +2576 -2455
- 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 +296 -342
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js +0 -1
- package/dist/meeting/request.type.js.map +1 -1
- 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 +170 -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 +14 -40
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +481 -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 -462
- 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 +994 -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 +104 -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 +48 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +267 -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 +888 -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 +22 -11
- package/src/common/logs/request.ts +11 -8
- package/src/config.ts +16 -12
- package/src/constants.ts +154 -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 +286 -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 +47 -69
- package/src/locus-info/selfUtils.ts +175 -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 +2809 -1589
- package/src/meeting/locusMediaRequest.ts +309 -0
- package/src/meeting/muteState.ts +290 -72
- package/src/meeting/request.ts +229 -182
- package/src/meeting/request.type.ts +10 -8
- 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 +771 -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 +210 -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 +11 -3
- package/src/multistream/remoteMediaManager.ts +245 -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 -112
- 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 -65
- package/src/roap/turnDiscovery.ts +101 -48
- package/src/statsAnalyzer/global.ts +8 -104
- package/src/statsAnalyzer/index.ts +624 -377
- 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 +1685 -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 +518 -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 +615 -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 +221 -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 +3077 -923
- 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 +408 -85
- 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 +676 -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 +52 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +585 -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 () => {
|
|
@@ -482,6 +663,42 @@ describe('RemoteMediaManager', () => {
|
|
|
482
663
|
remoteMediaManager.stop();
|
|
483
664
|
});
|
|
484
665
|
});
|
|
666
|
+
|
|
667
|
+
describe('setPreferLiveVideo', () => {
|
|
668
|
+
|
|
669
|
+
it('sets preferLiveVideo', async () => {
|
|
670
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
671
|
+
let stubs = [];
|
|
672
|
+
|
|
673
|
+
config.video.initialLayoutId = 'OnePlusFive';
|
|
674
|
+
|
|
675
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
676
|
+
fakeReceiveSlotManager,
|
|
677
|
+
fakeMediaRequestManagers,
|
|
678
|
+
config
|
|
679
|
+
);
|
|
680
|
+
|
|
681
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
682
|
+
console.log(layoutInfo.activeSpeakerVideoPanes);
|
|
683
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) => stubs.push(sinon.stub(group, 'setPreferLiveVideo')));
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
await remoteMediaManager.start();
|
|
687
|
+
resetHistory();
|
|
688
|
+
assert(stubs.length > 0);
|
|
689
|
+
await remoteMediaManager.setPreferLiveVideo(true);
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
stubs.forEach((stub) => {
|
|
693
|
+
assert.calledWith(stub, true, false)
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
expect(config.video.preferLiveVideo).to.equal(true);
|
|
697
|
+
|
|
698
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
|
|
485
702
|
describe('setLayout', () => {
|
|
486
703
|
it('rejects if called with invalid layoutId', async () => {
|
|
487
704
|
await assert.isRejected(remoteMediaManager.setLayout('invalid value'));
|
|
@@ -511,9 +728,53 @@ describe('RemoteMediaManager', () => {
|
|
|
511
728
|
await remoteMediaManager.setLayout('Stage');
|
|
512
729
|
|
|
513
730
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 9);
|
|
514
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
731
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
it('logs layout changes - receiver selected', async () => {
|
|
735
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
736
|
+
|
|
737
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
738
|
+
fakeReceiveSlotManager,
|
|
739
|
+
fakeMediaRequestManagers,
|
|
740
|
+
config
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
await remoteMediaManager.start();
|
|
744
|
+
|
|
745
|
+
resetHistory();
|
|
746
|
+
|
|
747
|
+
await remoteMediaManager.setLayout('Stage');
|
|
748
|
+
|
|
749
|
+
assert.calledWith(
|
|
750
|
+
logger.log,
|
|
751
|
+
'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'
|
|
752
|
+
);
|
|
515
753
|
});
|
|
516
754
|
|
|
755
|
+
it('logs layout changes - active speaker', async () => {
|
|
756
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
757
|
+
config.video.initialLayoutId = 'OnePlusFive'
|
|
758
|
+
|
|
759
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
760
|
+
fakeReceiveSlotManager,
|
|
761
|
+
fakeMediaRequestManagers,
|
|
762
|
+
config
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
await remoteMediaManager.start();
|
|
766
|
+
|
|
767
|
+
resetHistory();
|
|
768
|
+
|
|
769
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
770
|
+
|
|
771
|
+
assert.calledWith(
|
|
772
|
+
logger.log,
|
|
773
|
+
'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'
|
|
774
|
+
);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
|
|
517
778
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
518
779
|
// start with "AllEqual" layout that needs just 9 video slots
|
|
519
780
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
@@ -538,10 +799,137 @@ describe('RemoteMediaManager', () => {
|
|
|
538
799
|
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
539
800
|
const slot = call.args[0];
|
|
540
801
|
|
|
541
|
-
assert.strictEqual(slot.mediaType,
|
|
802
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
542
803
|
});
|
|
543
804
|
});
|
|
544
805
|
|
|
806
|
+
it('releases slots and reallocates slots when switching to layouts in correct order', async () => {
|
|
807
|
+
|
|
808
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
809
|
+
let count = 0;
|
|
810
|
+
|
|
811
|
+
fakeReceiveSlotManager.allocateSlot = sinon.stub().callsFake((mediaType) => {
|
|
812
|
+
switch (mediaType) {
|
|
813
|
+
case MediaType.AudioMain:
|
|
814
|
+
return Promise.resolve(fakeAudioSlot);
|
|
815
|
+
case MediaType.VideoMain:
|
|
816
|
+
return Promise.resolve(new FakeSlot(MediaType.VideoMain, `fake video ${count++}`));
|
|
817
|
+
case MediaType.AudioSlides:
|
|
818
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
819
|
+
case MediaType.VideoSlides:
|
|
820
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
821
|
+
}
|
|
822
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
823
|
+
})
|
|
824
|
+
|
|
825
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
826
|
+
fakeReceiveSlotManager,
|
|
827
|
+
fakeMediaRequestManagers,
|
|
828
|
+
config
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
await remoteMediaManager.start();
|
|
832
|
+
|
|
833
|
+
resetHistory();
|
|
834
|
+
|
|
835
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
836
|
+
"fake video 0",
|
|
837
|
+
"fake video 1",
|
|
838
|
+
"fake video 2",
|
|
839
|
+
"fake video 3",
|
|
840
|
+
"fake video 4",
|
|
841
|
+
"fake video 5",
|
|
842
|
+
"fake video 6",
|
|
843
|
+
"fake video 7",
|
|
844
|
+
"fake video 8",
|
|
845
|
+
]);
|
|
846
|
+
|
|
847
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
848
|
+
"fake video 0",
|
|
849
|
+
"fake video 1",
|
|
850
|
+
"fake video 2",
|
|
851
|
+
"fake video 3",
|
|
852
|
+
"fake video 4",
|
|
853
|
+
"fake video 5",
|
|
854
|
+
"fake video 6",
|
|
855
|
+
"fake video 7",
|
|
856
|
+
"fake video 8",
|
|
857
|
+
])
|
|
858
|
+
|
|
859
|
+
// switch to "OnePlusFive" layout that requires 3 less video slots (6)
|
|
860
|
+
await remoteMediaManager.setLayout('OnePlusFive');
|
|
861
|
+
|
|
862
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
863
|
+
|
|
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
|
+
]);
|
|
872
|
+
|
|
873
|
+
// we're checking that the slots are in the same order as in the previous layout
|
|
874
|
+
// first one goes into main
|
|
875
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["mainBigOne"].slots.map((slot: any) => slot.id), [
|
|
876
|
+
"fake video 0",
|
|
877
|
+
])
|
|
878
|
+
// and rest go in the pips
|
|
879
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["secondarySetOfSmallPanes"].slots.map((slot: any) => slot.id), [
|
|
880
|
+
"fake video 1",
|
|
881
|
+
"fake video 2",
|
|
882
|
+
"fake video 3",
|
|
883
|
+
"fake video 4",
|
|
884
|
+
"fake video 5"
|
|
885
|
+
])
|
|
886
|
+
|
|
887
|
+
// verify that 3 main video slots were released
|
|
888
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 3);
|
|
889
|
+
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
890
|
+
const slot = call.args[0];
|
|
891
|
+
|
|
892
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
896
|
+
|
|
897
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
898
|
+
|
|
899
|
+
// checking that slots are in the same order as in previous layout + 3 new ones
|
|
900
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
901
|
+
"fake video 0",
|
|
902
|
+
"fake video 1",
|
|
903
|
+
"fake video 2",
|
|
904
|
+
"fake video 3",
|
|
905
|
+
"fake video 4",
|
|
906
|
+
"fake video 5",
|
|
907
|
+
"fake video 10",
|
|
908
|
+
"fake video 11",
|
|
909
|
+
"fake video 12",
|
|
910
|
+
]);
|
|
911
|
+
|
|
912
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
913
|
+
"fake video 0",
|
|
914
|
+
"fake video 1",
|
|
915
|
+
"fake video 2",
|
|
916
|
+
"fake video 3",
|
|
917
|
+
"fake video 4",
|
|
918
|
+
"fake video 5",
|
|
919
|
+
"fake video 10",
|
|
920
|
+
"fake video 11",
|
|
921
|
+
"fake video 12"
|
|
922
|
+
])
|
|
923
|
+
|
|
924
|
+
// verify that 3 main video slots were allocated
|
|
925
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 3);
|
|
926
|
+
fakeReceiveSlotManager.allocateSlot.getCalls().forEach((call) => {
|
|
927
|
+
const mediaType = call.args[0];
|
|
928
|
+
|
|
929
|
+
assert.strictEqual(mediaType, MediaType.VideoMain);
|
|
930
|
+
});
|
|
931
|
+
});
|
|
932
|
+
|
|
545
933
|
it('stops all current video remoteMedia instances when switching to new layout', async () => {
|
|
546
934
|
const audioStopStubs = [];
|
|
547
935
|
const videoStopStubs = [];
|
|
@@ -600,6 +988,104 @@ describe('RemoteMediaManager', () => {
|
|
|
600
988
|
});
|
|
601
989
|
});
|
|
602
990
|
|
|
991
|
+
it('emits Event.VideoLayoutChanged with correct data', async () => {
|
|
992
|
+
// setup the initial layout to be empty and a testLayout that has screen share, active speaker groups and member video panes
|
|
993
|
+
const config: Configuration = {
|
|
994
|
+
audio: {
|
|
995
|
+
numOfActiveSpeakerStreams: 0,
|
|
996
|
+
numOfScreenShareStreams: 0,
|
|
997
|
+
},
|
|
998
|
+
video: {
|
|
999
|
+
preferLiveVideo: true,
|
|
1000
|
+
initialLayoutId: 'empty',
|
|
1001
|
+
layouts: {
|
|
1002
|
+
empty: {},
|
|
1003
|
+
testLayout: {
|
|
1004
|
+
screenShareVideo: {size: 'very small'},
|
|
1005
|
+
activeSpeakerVideoPaneGroups: [
|
|
1006
|
+
{
|
|
1007
|
+
id: 'big',
|
|
1008
|
+
numPanes: 10,
|
|
1009
|
+
priority: 255,
|
|
1010
|
+
size: 'large',
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
id: 'small',
|
|
1014
|
+
numPanes: 3,
|
|
1015
|
+
priority: 254,
|
|
1016
|
+
size: 'medium',
|
|
1017
|
+
},
|
|
1018
|
+
],
|
|
1019
|
+
memberVideoPanes: [
|
|
1020
|
+
{id: 'pane 1', size: 'best', csi: 555},
|
|
1021
|
+
{id: 'pane 2', size: 'best', csi: undefined},
|
|
1022
|
+
],
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
1025
|
+
},
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
1029
|
+
fakeReceiveSlotManager,
|
|
1030
|
+
fakeMediaRequestManagers,
|
|
1031
|
+
config
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
await remoteMediaManager.start();
|
|
1035
|
+
|
|
1036
|
+
resetHistory();
|
|
1037
|
+
|
|
1038
|
+
let receivedLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1039
|
+
|
|
1040
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo) => {
|
|
1041
|
+
receivedLayoutInfo = layoutInfo;
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
// switch to the test layout
|
|
1045
|
+
await remoteMediaManager.setLayout('testLayout');
|
|
1046
|
+
|
|
1047
|
+
assert.isNotNull(receivedLayoutInfo);
|
|
1048
|
+
|
|
1049
|
+
if (receivedLayoutInfo) {
|
|
1050
|
+
assert.strictEqual(receivedLayoutInfo.layoutId, 'testLayout');
|
|
1051
|
+
|
|
1052
|
+
// check screen share video
|
|
1053
|
+
assert.isTrue(!!receivedLayoutInfo.screenShareVideo);
|
|
1054
|
+
assert.strictEqual(receivedLayoutInfo.screenShareVideo.mediaType, MediaType.VideoSlides);
|
|
1055
|
+
|
|
1056
|
+
// check member videos
|
|
1057
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.memberVideoPanes).length, 2);
|
|
1058
|
+
Object.values(receivedLayoutInfo.memberVideoPanes).forEach((remoteMedia) =>
|
|
1059
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
// check the 2 active speaker groups
|
|
1063
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.activeSpeakerVideoPanes).length, 2);
|
|
1064
|
+
|
|
1065
|
+
// "big" group
|
|
1066
|
+
assert.strictEqual(
|
|
1067
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big.getRemoteMedia().length,
|
|
1068
|
+
10
|
|
1069
|
+
);
|
|
1070
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big
|
|
1071
|
+
.getRemoteMedia()
|
|
1072
|
+
.forEach((remoteMedia) =>
|
|
1073
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1074
|
+
);
|
|
1075
|
+
|
|
1076
|
+
// "small" group
|
|
1077
|
+
assert.strictEqual(
|
|
1078
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small.getRemoteMedia().length,
|
|
1079
|
+
3
|
|
1080
|
+
);
|
|
1081
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small
|
|
1082
|
+
.getRemoteMedia()
|
|
1083
|
+
.forEach((remoteMedia) =>
|
|
1084
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
|
|
603
1089
|
describe('switching between different receiver selected layouts', () => {
|
|
604
1090
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
605
1091
|
let slotCounter: number;
|
|
@@ -620,7 +1106,7 @@ describe('RemoteMediaManager', () => {
|
|
|
620
1106
|
slotCounter += 1;
|
|
621
1107
|
const newSlotId = `fake video slot ${slotCounter}`;
|
|
622
1108
|
|
|
623
|
-
fakeSlots[newSlotId] = new FakeSlot(
|
|
1109
|
+
fakeSlots[newSlotId] = new FakeSlot(MediaType.VideoMain, newSlotId);
|
|
624
1110
|
return fakeSlots[newSlotId];
|
|
625
1111
|
});
|
|
626
1112
|
|
|
@@ -652,12 +1138,12 @@ describe('RemoteMediaManager', () => {
|
|
|
652
1138
|
// This test starts with a layout that has 5 receiver selected video slots
|
|
653
1139
|
// and switches to a different layout that has fewer slots, but 2 of them match CSIs
|
|
654
1140
|
// from the initial layout. We want to verify that these 2 slots get re-used correctly.
|
|
1141
|
+
// There are no screen share or audio slots being used in this test.
|
|
1142
|
+
delete config.video.layouts.ScreenShareView;
|
|
655
1143
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
656
|
-
config.
|
|
657
|
-
config.screenShare.video = false;
|
|
1144
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
658
1145
|
config.video.initialLayoutId = 'biggerLayout';
|
|
659
1146
|
config.video.layouts['biggerLayout'] = {
|
|
660
|
-
screenShareVideo: {size: null},
|
|
661
1147
|
memberVideoPanes: [
|
|
662
1148
|
{id: '1', size: 'best', csi: 100},
|
|
663
1149
|
{id: '2', size: 'best', csi: 200},
|
|
@@ -667,7 +1153,6 @@ describe('RemoteMediaManager', () => {
|
|
|
667
1153
|
],
|
|
668
1154
|
};
|
|
669
1155
|
config.video.layouts['smallerLayout'] = {
|
|
670
|
-
screenShareVideo: {size: null},
|
|
671
1156
|
memberVideoPanes: [
|
|
672
1157
|
{id: '1', size: 'medium', csi: 200}, // this csi matches pane '2' from biggerLayout
|
|
673
1158
|
{id: '2', size: 'medium', csi: 123},
|
|
@@ -717,16 +1202,15 @@ describe('RemoteMediaManager', () => {
|
|
|
717
1202
|
// This test starts with a layout that has video slot with a specific CSI
|
|
718
1203
|
// and switches to a different layout that 2 panes with that same CSI.
|
|
719
1204
|
// We want to verify that the slot gets reused, but also that a 2nd slot is allocated.
|
|
1205
|
+
// There are no screen share or audio slots being used in this test.
|
|
1206
|
+
delete config.video.layouts.ScreenShareView;
|
|
720
1207
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
721
|
-
config.
|
|
722
|
-
config.screenShare.video = false;
|
|
1208
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
723
1209
|
config.video.initialLayoutId = 'initialEmptyLayout';
|
|
724
1210
|
config.video.layouts['initialEmptyLayout'] = {
|
|
725
|
-
screenShareVideo: {size: null},
|
|
726
1211
|
memberVideoPanes: [{id: '2', size: 'medium', csi: 456}],
|
|
727
1212
|
};
|
|
728
1213
|
config.video.layouts['layoutWithDuplicateCSIs'] = {
|
|
729
|
-
screenShareVideo: {size: null},
|
|
730
1214
|
memberVideoPanes: [
|
|
731
1215
|
{id: '1', size: 'medium', csi: 123},
|
|
732
1216
|
{id: '2', size: 'medium', csi: 456},
|
|
@@ -899,16 +1383,18 @@ describe('RemoteMediaManager', () => {
|
|
|
899
1383
|
});
|
|
900
1384
|
|
|
901
1385
|
it('cancels all media requests for the previous layout when switching to a new one', async () => {
|
|
1386
|
+
// setup the initial layout to have screen share, active speaker groups and member video panes
|
|
902
1387
|
const config: Configuration = {
|
|
903
1388
|
audio: {
|
|
904
1389
|
numOfActiveSpeakerStreams: 0,
|
|
1390
|
+
numOfScreenShareStreams: 0,
|
|
905
1391
|
},
|
|
906
1392
|
video: {
|
|
907
1393
|
preferLiveVideo: true,
|
|
908
1394
|
initialLayoutId: 'initial',
|
|
909
1395
|
layouts: {
|
|
910
1396
|
initial: {
|
|
911
|
-
screenShareVideo: {size:
|
|
1397
|
+
screenShareVideo: {size: 'best'},
|
|
912
1398
|
activeSpeakerVideoPaneGroups: [
|
|
913
1399
|
{
|
|
914
1400
|
id: 'big',
|
|
@@ -928,15 +1414,9 @@ describe('RemoteMediaManager', () => {
|
|
|
928
1414
|
{id: 'pane 2', size: 'best', csi: 234},
|
|
929
1415
|
],
|
|
930
1416
|
},
|
|
931
|
-
other: {
|
|
932
|
-
screenShareVideo: {size: null},
|
|
933
|
-
},
|
|
1417
|
+
other: {},
|
|
934
1418
|
},
|
|
935
1419
|
},
|
|
936
|
-
screenShare: {
|
|
937
|
-
audio: false,
|
|
938
|
-
video: false,
|
|
939
|
-
},
|
|
940
1420
|
};
|
|
941
1421
|
|
|
942
1422
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -959,9 +1439,15 @@ describe('RemoteMediaManager', () => {
|
|
|
959
1439
|
|
|
960
1440
|
return `receiver selected request ${receiverSelectedRequestCounter}`;
|
|
961
1441
|
});
|
|
1442
|
+
// setup the mock for screen share addRequest - this one should be called just once
|
|
1443
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest.callsFake(() => {
|
|
1444
|
+
return 'video screen share request id';
|
|
1445
|
+
});
|
|
962
1446
|
|
|
963
1447
|
await remoteMediaManager.start();
|
|
964
1448
|
|
|
1449
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.addRequest);
|
|
1450
|
+
|
|
965
1451
|
resetHistory();
|
|
966
1452
|
|
|
967
1453
|
// switch to "other" layout
|
|
@@ -979,11 +1465,45 @@ describe('RemoteMediaManager', () => {
|
|
|
979
1465
|
fakeMediaRequestManagers.video.cancelRequest,
|
|
980
1466
|
'receiver selected request 2'
|
|
981
1467
|
);
|
|
1468
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.cancelRequest);
|
|
1469
|
+
assert.calledWith(
|
|
1470
|
+
fakeMediaRequestManagers.screenShareVideo.cancelRequest,
|
|
1471
|
+
'video screen share request id'
|
|
1472
|
+
);
|
|
982
1473
|
|
|
983
1474
|
// 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
1475
|
assert.callCount(fakeMediaRequestManagers.video.addRequest, 0);
|
|
986
1476
|
});
|
|
1477
|
+
|
|
1478
|
+
it('sends media request for screen share if layout contains screen share', async () => {
|
|
1479
|
+
const allEqualMediaRequestId = 'fake request id';
|
|
1480
|
+
|
|
1481
|
+
fakeMediaRequestManagers.video.addRequest.returns(allEqualMediaRequestId);
|
|
1482
|
+
|
|
1483
|
+
await remoteMediaManager.start();
|
|
1484
|
+
|
|
1485
|
+
resetHistory();
|
|
1486
|
+
|
|
1487
|
+
// switch to a layout that contains a screen share video pane
|
|
1488
|
+
await remoteMediaManager.setLayout('ScreenShareView');
|
|
1489
|
+
|
|
1490
|
+
// check that a correct active speaker media request for screen share has been sent out
|
|
1491
|
+
assert.callCount(fakeMediaRequestManagers.screenShareVideo.addRequest, 1);
|
|
1492
|
+
assert.calledWith(
|
|
1493
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest,
|
|
1494
|
+
sinon.match({
|
|
1495
|
+
policyInfo: sinon.match({
|
|
1496
|
+
policy: 'active-speaker',
|
|
1497
|
+
priority: 255,
|
|
1498
|
+
}),
|
|
1499
|
+
receiveSlots: [fakeScreenShareVideoSlot],
|
|
1500
|
+
codecInfo: sinon.match({
|
|
1501
|
+
codec: 'h264',
|
|
1502
|
+
maxFs: 3600,
|
|
1503
|
+
}),
|
|
1504
|
+
})
|
|
1505
|
+
);
|
|
1506
|
+
});
|
|
987
1507
|
});
|
|
988
1508
|
});
|
|
989
1509
|
|
|
@@ -1123,7 +1643,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1123
1643
|
|
|
1124
1644
|
// new slot should be allocated
|
|
1125
1645
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1126
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1646
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1127
1647
|
|
|
1128
1648
|
// and a media request sent out
|
|
1129
1649
|
assert.calledOnce(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1152,7 +1672,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1152
1672
|
|
|
1153
1673
|
// new slot should be allocated
|
|
1154
1674
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1155
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1675
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1156
1676
|
|
|
1157
1677
|
// but no media requests sent out
|
|
1158
1678
|
assert.notCalled(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1181,7 +1701,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1181
1701
|
await remoteMediaManager.start();
|
|
1182
1702
|
await remoteMediaManager.setLayout('Stage');
|
|
1183
1703
|
|
|
1184
|
-
const fakeNewSlot = new FakeSlot(
|
|
1704
|
+
const fakeNewSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
1185
1705
|
const fakeRequestId = 'fake request id';
|
|
1186
1706
|
|
|
1187
1707
|
fakeReceiveSlotManager.allocateSlot.resolves(fakeNewSlot);
|