@webex/plugin-meetings 3.0.0-beta.2 → 3.0.0-beta.200
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -7
- package/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 +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +216 -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 +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +1048 -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 +10 -24
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +11 -24
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +12 -25
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +10 -24
- 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 +10 -24
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +9 -23
- 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 +10 -24
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +10 -24
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +9 -43
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +5 -25
- 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 +37 -60
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +28 -23
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +8 -13
- package/dist/config.js.map +1 -1
- package/dist/constants.js +250 -66
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +14 -0
- package/dist/controls-options-manager/constants.js.map +1 -0
- package/dist/controls-options-manager/enums.js +27 -0
- package/dist/controls-options-manager/enums.js.map +1 -0
- package/dist/controls-options-manager/index.js +297 -0
- package/dist/controls-options-manager/index.js.map +1 -0
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +319 -0
- package/dist/controls-options-manager/util.js.map +1 -0
- package/dist/index.js +108 -17
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +101 -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 +532 -240
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +3 -37
- 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 +284 -154
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +110 -92
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +95 -226
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +99 -194
- 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 +83 -14
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3478 -3563
- 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 +247 -183
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +344 -344
- 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 +529 -588
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +6 -25
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +62 -39
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +328 -283
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +3 -15
- 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 +26 -19
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +795 -574
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +26 -41
- 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 +126 -85
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +147 -88
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +13 -12
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +178 -204
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +113 -68
- 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/constants.js +4 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +11 -558
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +264 -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 +76 -95
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +62 -76
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +66 -43
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +502 -442
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +40 -59
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +21 -45
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +1 -31
- 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 +192 -191
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +15 -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 +109 -0
- package/dist/reactions/reactions.js.map +1 -0
- package/dist/reactions/reactions.type.js +36 -0
- package/dist/reactions/reactions.type.js.map +1 -0
- package/dist/reconnection-manager/index.js +384 -476
- 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 +363 -0
- package/dist/recording-controller/index.js.map +1 -0
- package/dist/recording-controller/util.js +64 -0
- package/dist/recording-controller/util.js.map +1 -0
- package/dist/roap/index.js +58 -91
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +137 -135
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +148 -100
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +115 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.js +1 -95
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +385 -460
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +143 -87
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +22 -47
- package/dist/transcription/index.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/breakout.d.ts +8 -0
- package/dist/types/breakouts/collection.d.ts +5 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/index.d.ts +5 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/browser-detection.d.ts +9 -0
- package/dist/types/common/collection.d.ts +48 -0
- package/dist/types/common/config.d.ts +2 -0
- package/dist/types/common/errors/captcha-error.d.ts +15 -0
- package/dist/types/common/errors/intent-to-join.d.ts +16 -0
- package/dist/types/common/errors/join-meeting.d.ts +17 -0
- package/dist/types/common/errors/media.d.ts +15 -0
- package/dist/types/common/errors/parameter.d.ts +15 -0
- package/dist/types/common/errors/password-error.d.ts +15 -0
- package/dist/types/common/errors/permission.d.ts +14 -0
- package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
- package/dist/types/common/errors/reconnection.d.ts +15 -0
- package/dist/types/common/errors/stats.d.ts +15 -0
- package/dist/types/common/errors/webex-errors.d.ts +69 -0
- package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/types/common/events/events-scope.d.ts +17 -0
- package/dist/types/common/events/events.d.ts +12 -0
- package/dist/types/common/events/trigger-proxy.d.ts +2 -0
- package/dist/types/common/events/util.d.ts +2 -0
- package/dist/types/common/logs/logger-config.d.ts +2 -0
- package/dist/types/common/logs/logger-proxy.d.ts +2 -0
- package/dist/types/common/logs/request.d.ts +34 -0
- package/dist/types/common/queue.d.ts +34 -0
- package/dist/types/config.d.ts +72 -0
- package/dist/types/constants.d.ts +1016 -0
- package/dist/types/controls-options-manager/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/enums.d.ts +15 -0
- package/dist/types/controls-options-manager/index.d.ts +136 -0
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/controlsUtils.d.ts +2 -0
- package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/types/locus-info/fullState.d.ts +2 -0
- package/dist/types/locus-info/hostUtils.d.ts +2 -0
- package/dist/types/locus-info/index.d.ts +322 -0
- package/dist/types/locus-info/infoUtils.d.ts +2 -0
- package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/types/locus-info/parser.d.ts +271 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/index.d.ts +34 -0
- package/dist/types/media/properties.d.ts +93 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +153 -0
- package/dist/types/meeting/index.d.ts +1471 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
- package/dist/types/meeting/muteState.d.ts +184 -0
- package/dist/types/meeting/request.d.ts +257 -0
- package/dist/types/meeting/request.type.d.ts +11 -0
- package/dist/types/meeting/state.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +78 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +62 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
- package/dist/types/meeting-info/request.d.ts +22 -0
- package/dist/types/meeting-info/util.d.ts +2 -0
- package/dist/types/meeting-info/utilv2.d.ts +2 -0
- package/dist/types/meetings/collection.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +367 -0
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/meetings/request.d.ts +27 -0
- package/dist/types/meetings/util.d.ts +18 -0
- package/dist/types/member/index.d.ts +159 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/member/util.d.ts +2 -0
- package/dist/types/members/collection.d.ts +29 -0
- package/dist/types/members/index.d.ts +353 -0
- package/dist/types/members/request.d.ts +114 -0
- package/dist/types/members/types.d.ts +24 -0
- package/dist/types/members/util.d.ts +210 -0
- package/dist/types/metrics/constants.d.ts +55 -0
- package/dist/types/metrics/index.d.ts +45 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
- package/dist/types/multistream/receiveSlot.d.ts +68 -0
- package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/types/multistream/remoteMedia.d.ts +72 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/types/personal-meeting-room/index.d.ts +47 -0
- package/dist/types/personal-meeting-room/request.d.ts +14 -0
- package/dist/types/personal-meeting-room/util.d.ts +2 -0
- package/dist/types/reachability/index.d.ts +152 -0
- package/dist/types/reachability/request.d.ts +37 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +126 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +208 -0
- package/dist/types/recording-controller/util.d.ts +14 -0
- package/dist/types/roap/index.d.ts +77 -0
- package/dist/types/roap/request.d.ts +36 -0
- package/dist/types/roap/turnDiscovery.d.ts +91 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +46 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +200 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
- package/dist/types/transcription/index.d.ts +64 -0
- package/internal-README.md +7 -6
- package/package.json +29 -21
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +220 -0
- package/src/breakouts/breakout.ts +188 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +925 -0
- package/src/breakouts/request.ts +55 -0
- package/src/breakouts/utils.ts +57 -0
- package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
- package/src/common/collection.ts +9 -7
- package/src/common/{config.js → config.ts} +1 -1
- package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
- package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
- package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
- package/src/common/errors/{media.js → media.ts} +11 -7
- package/src/common/errors/parameter.ts +11 -7
- package/src/common/errors/{password-error.js → password-error.ts} +11 -7
- package/src/common/errors/{permission.js → permission.ts} +10 -6
- package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
- package/src/common/errors/{stats.js → stats.ts} +11 -7
- package/src/common/errors/{webex-errors.js → webex-errors.ts} +14 -9
- package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
- package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
- package/src/common/events/{events.js → events.ts} +5 -1
- package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
- package/src/common/events/{util.js → util.ts} +2 -3
- package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
- package/src/common/logs/logger-proxy.ts +44 -0
- package/src/common/logs/{request.js → request.ts} +22 -9
- package/src/common/queue.ts +22 -9
- package/src/{config.js → config.ts} +17 -17
- package/src/constants.ts +197 -22
- package/src/controls-options-manager/constants.ts +5 -0
- package/src/controls-options-manager/enums.ts +18 -0
- package/src/controls-options-manager/index.ts +278 -0
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +300 -0
- package/src/index.ts +39 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +222 -0
- package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
- package/src/locus-info/{fullState.js → fullState.ts} +16 -12
- package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
- package/src/locus-info/{index.js → index.ts} +518 -111
- package/src/locus-info/{infoUtils.js → infoUtils.ts} +19 -8
- package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +65 -17
- package/src/locus-info/{parser.js → parser.ts} +271 -98
- package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
- package/src/media/index.ts +456 -0
- package/src/media/{properties.js → properties.ts} +80 -102
- package/src/media/{util.js → util.ts} +2 -2
- package/src/mediaQualityMetrics/config.ts +384 -0
- package/src/meeting/in-meeting-actions.ts +171 -3
- package/src/meeting/index.ts +7070 -0
- package/src/meeting/locusMediaRequest.ts +309 -0
- package/src/meeting/muteState.ts +450 -0
- package/src/meeting/{request.js → request.ts} +354 -214
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/{state.js → state.ts} +50 -35
- package/src/meeting/util.ts +615 -0
- package/src/meeting-info/{collection.js → collection.ts} +6 -2
- package/src/meeting-info/index.ts +183 -0
- package/src/meeting-info/meeting-info-v2.ts +407 -0
- package/src/meeting-info/{request.js → request.ts} +14 -4
- package/src/meeting-info/{util.js → util.ts} +60 -51
- package/src/meeting-info/{utilv2.js → utilv2.ts} +77 -60
- package/src/meetings/{collection.js → collection.ts} +26 -3
- package/src/meetings/index.ts +1467 -0
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/{request.js → request.ts} +34 -25
- package/src/meetings/{util.js → util.ts} +137 -36
- package/src/member/{index.js → index.ts} +151 -56
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +383 -0
- package/src/members/{collection.js → collection.ts} +10 -2
- package/src/members/{index.js → index.ts} +323 -145
- package/src/members/request.ts +255 -0
- package/src/members/types.ts +28 -0
- package/src/members/util.ts +339 -0
- package/src/metrics/{constants.js → constants.ts} +2 -6
- package/src/metrics/index.ts +73 -0
- package/src/multistream/mediaRequestManager.ts +337 -61
- package/src/multistream/receiveSlot.ts +69 -26
- package/src/multistream/receiveSlotManager.ts +66 -42
- package/src/multistream/remoteMedia.ts +40 -5
- package/src/multistream/remoteMediaGroup.ts +63 -3
- package/src/multistream/remoteMediaManager.ts +263 -66
- package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
- package/src/personal-meeting-room/{index.js → index.ts} +28 -19
- package/src/personal-meeting-room/{request.js → request.ts} +13 -4
- package/src/personal-meeting-room/{util.js → util.ts} +4 -4
- package/src/reachability/{index.js → index.ts} +157 -94
- package/src/reachability/request.ts +46 -35
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.ts +104 -0
- package/src/reactions/reactions.type.ts +62 -0
- package/src/reconnection-manager/{index.js → index.ts} +254 -136
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +333 -0
- package/src/recording-controller/util.ts +75 -0
- package/src/roap/{index.js → index.ts} +86 -78
- package/src/roap/request.ts +163 -0
- package/src/roap/turnDiscovery.ts +111 -49
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +96 -0
- package/src/statsAnalyzer/global.ts +37 -0
- package/src/statsAnalyzer/index.ts +1272 -0
- package/src/statsAnalyzer/mqaUtil.ts +291 -0
- package/src/transcription/{index.js → index.ts} +46 -39
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +804 -526
- package/test/integration/spec/space-meeting.js +391 -204
- package/test/integration/spec/transcription.js +7 -8
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +237 -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 +89 -0
- package/test/unit/spec/breakouts/index.ts +1790 -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/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +287 -0
- package/test/unit/spec/controls-options-manager/util.js +582 -0
- package/test/unit/spec/fixture/locus.js +93 -90
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +325 -32
- package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
- package/test/unit/spec/locus-info/index.js +1176 -18
- package/test/unit/spec/locus-info/infoUtils.js +41 -32
- 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 +65 -31
- package/test/unit/spec/locus-info/selfConstant.js +120 -103
- package/test/unit/spec/locus-info/selfUtils.js +296 -12
- package/test/unit/spec/media/index.ts +162 -68
- package/test/unit/spec/media/properties.ts +9 -9
- package/test/unit/spec/meeting/in-meeting-actions.ts +82 -3
- package/test/unit/spec/meeting/index.js +4569 -1773
- package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
- package/test/unit/spec/meeting/muteState.js +382 -211
- package/test/unit/spec/meeting/request.js +444 -78
- package/test/unit/spec/meeting/utils.js +517 -192
- package/test/unit/spec/meeting-info/index.js +181 -0
- 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 +1254 -330
- package/test/unit/spec/meetings/utils.js +220 -14
- package/test/unit/spec/member/index.js +58 -5
- package/test/unit/spec/member/util.js +494 -26
- package/test/unit/spec/members/index.js +423 -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 +12 -66
- package/test/unit/spec/multistream/mediaRequestManager.ts +1013 -106
- package/test/unit/spec/multistream/receiveSlot.ts +77 -18
- package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
- package/test/unit/spec/multistream/remoteMedia.ts +40 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +730 -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 +155 -9
- package/test/unit/spec/recording-controller/index.js +307 -0
- package/test/unit/spec/recording-controller/util.js +229 -0
- package/test/unit/spec/roap/index.ts +28 -52
- package/test/unit/spec/roap/request.ts +225 -0
- package/test/unit/spec/roap/turnDiscovery.ts +92 -50
- package/test/unit/spec/rtcMetrics/index.ts +60 -0
- 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 +46 -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 -327
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -301
- package/dist/metrics/config.js.map +0 -1
- package/dist/multistream/multistreamMedia.js +0 -116
- package/dist/multistream/multistreamMedia.js.map +0 -1
- package/dist/peer-connection-manager/util.js +0 -124
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/src/common/logs/logger-proxy.js +0 -33
- package/src/index.js +0 -15
- package/src/locus-info/controlsUtils.js +0 -102
- package/src/media/index.js +0 -459
- package/src/media/internal-media-core-wrapper.ts +0 -9
- package/src/mediaQualityMetrics/config.js +0 -382
- package/src/meeting/effectsState.js +0 -205
- package/src/meeting/index.js +0 -6284
- package/src/meeting/muteState.js +0 -318
- package/src/meeting/util.js +0 -506
- package/src/meeting-info/index.js +0 -131
- package/src/meeting-info/meeting-info-v2.js +0 -255
- package/src/meetings/index.js +0 -1015
- package/src/member/util.js +0 -254
- package/src/members/request.js +0 -131
- package/src/members/util.js +0 -258
- package/src/metrics/config.js +0 -324
- package/src/metrics/index.js +0 -530
- package/src/multistream/multistreamMedia.ts +0 -92
- package/src/peer-connection-manager/util.ts +0 -117
- package/src/roap/request.js +0 -127
- package/src/statsAnalyzer/global.js +0 -133
- package/src/statsAnalyzer/index.js +0 -1006
- package/src/statsAnalyzer/mqaUtil.js +0 -173
- package/test/unit/spec/meeting/effectsState.js +0 -291
- package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
- /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
|
@@ -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
|
|
354
|
+
}
|
|
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);
|
|
305
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);
|
|
306
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,41 @@ 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
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) => stubs.push(sinon.stub(group, 'setPreferLiveVideo')));
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
await remoteMediaManager.start();
|
|
686
|
+
resetHistory();
|
|
687
|
+
assert(stubs.length > 0);
|
|
688
|
+
await remoteMediaManager.setPreferLiveVideo(true);
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
stubs.forEach((stub) => {
|
|
692
|
+
assert.calledWith(stub, true, false)
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
expect(config.video.preferLiveVideo).to.equal(true);
|
|
696
|
+
|
|
697
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
|
|
485
701
|
describe('setLayout', () => {
|
|
486
702
|
it('rejects if called with invalid layoutId', async () => {
|
|
487
703
|
await assert.isRejected(remoteMediaManager.setLayout('invalid value'));
|
|
@@ -511,9 +727,53 @@ describe('RemoteMediaManager', () => {
|
|
|
511
727
|
await remoteMediaManager.setLayout('Stage');
|
|
512
728
|
|
|
513
729
|
assert.callCount(fakeReceiveSlotManager.allocateSlot, 9);
|
|
514
|
-
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot,
|
|
730
|
+
assert.alwaysCalledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
it('logs layout changes - receiver selected', async () => {
|
|
734
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
735
|
+
|
|
736
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
737
|
+
fakeReceiveSlotManager,
|
|
738
|
+
fakeMediaRequestManagers,
|
|
739
|
+
config
|
|
740
|
+
);
|
|
741
|
+
|
|
742
|
+
await remoteMediaManager.start();
|
|
743
|
+
|
|
744
|
+
resetHistory();
|
|
745
|
+
|
|
746
|
+
await remoteMediaManager.setLayout('Stage');
|
|
747
|
+
|
|
748
|
+
assert.calledWith(
|
|
749
|
+
logger.log,
|
|
750
|
+
'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'
|
|
751
|
+
);
|
|
515
752
|
});
|
|
516
753
|
|
|
754
|
+
it('logs layout changes - active speaker', async () => {
|
|
755
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
756
|
+
config.video.initialLayoutId = 'OnePlusFive'
|
|
757
|
+
|
|
758
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
759
|
+
fakeReceiveSlotManager,
|
|
760
|
+
fakeMediaRequestManagers,
|
|
761
|
+
config
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
await remoteMediaManager.start();
|
|
765
|
+
|
|
766
|
+
resetHistory();
|
|
767
|
+
|
|
768
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
769
|
+
|
|
770
|
+
assert.calledWith(
|
|
771
|
+
logger.log,
|
|
772
|
+
'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'
|
|
773
|
+
);
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
|
|
517
777
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
518
778
|
// start with "AllEqual" layout that needs just 9 video slots
|
|
519
779
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
@@ -538,10 +798,293 @@ describe('RemoteMediaManager', () => {
|
|
|
538
798
|
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
539
799
|
const slot = call.args[0];
|
|
540
800
|
|
|
541
|
-
assert.strictEqual(slot.mediaType,
|
|
801
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
542
802
|
});
|
|
543
803
|
});
|
|
544
804
|
|
|
805
|
+
it('releases slots and reallocates slots when switching to layouts in correct order', async () => {
|
|
806
|
+
|
|
807
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
808
|
+
let count = 0;
|
|
809
|
+
|
|
810
|
+
fakeReceiveSlotManager.allocateSlot = sinon.stub().callsFake((mediaType) => {
|
|
811
|
+
switch (mediaType) {
|
|
812
|
+
case MediaType.AudioMain:
|
|
813
|
+
return Promise.resolve(fakeAudioSlot);
|
|
814
|
+
case MediaType.VideoMain:
|
|
815
|
+
return Promise.resolve(new FakeSlot(MediaType.VideoMain, `fake video ${count++}`));
|
|
816
|
+
case MediaType.AudioSlides:
|
|
817
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
818
|
+
case MediaType.VideoSlides:
|
|
819
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
820
|
+
}
|
|
821
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
822
|
+
})
|
|
823
|
+
|
|
824
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
825
|
+
fakeReceiveSlotManager,
|
|
826
|
+
fakeMediaRequestManagers,
|
|
827
|
+
config
|
|
828
|
+
);
|
|
829
|
+
|
|
830
|
+
await remoteMediaManager.start();
|
|
831
|
+
|
|
832
|
+
resetHistory();
|
|
833
|
+
|
|
834
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
835
|
+
"fake video 0",
|
|
836
|
+
"fake video 1",
|
|
837
|
+
"fake video 2",
|
|
838
|
+
"fake video 3",
|
|
839
|
+
"fake video 4",
|
|
840
|
+
"fake video 5",
|
|
841
|
+
"fake video 6",
|
|
842
|
+
"fake video 7",
|
|
843
|
+
"fake video 8",
|
|
844
|
+
]);
|
|
845
|
+
|
|
846
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
847
|
+
"fake video 0",
|
|
848
|
+
"fake video 1",
|
|
849
|
+
"fake video 2",
|
|
850
|
+
"fake video 3",
|
|
851
|
+
"fake video 4",
|
|
852
|
+
"fake video 5",
|
|
853
|
+
"fake video 6",
|
|
854
|
+
"fake video 7",
|
|
855
|
+
"fake video 8",
|
|
856
|
+
])
|
|
857
|
+
|
|
858
|
+
// switch to "OnePlusFive" layout that requires 3 less video slots (6)
|
|
859
|
+
await remoteMediaManager.setLayout('OnePlusFive');
|
|
860
|
+
|
|
861
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
862
|
+
|
|
863
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
864
|
+
"fake video 0",
|
|
865
|
+
"fake video 1",
|
|
866
|
+
"fake video 2",
|
|
867
|
+
"fake video 3",
|
|
868
|
+
"fake video 4",
|
|
869
|
+
"fake video 5"
|
|
870
|
+
]);
|
|
871
|
+
|
|
872
|
+
// we're checking that the slots are in the same order as in the previous layout
|
|
873
|
+
// first one goes into main
|
|
874
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["mainBigOne"].slots.map((slot: any) => slot.id), [
|
|
875
|
+
"fake video 0",
|
|
876
|
+
])
|
|
877
|
+
// and rest go in the pips
|
|
878
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["secondarySetOfSmallPanes"].slots.map((slot: any) => slot.id), [
|
|
879
|
+
"fake video 1",
|
|
880
|
+
"fake video 2",
|
|
881
|
+
"fake video 3",
|
|
882
|
+
"fake video 4",
|
|
883
|
+
"fake video 5"
|
|
884
|
+
])
|
|
885
|
+
|
|
886
|
+
// verify that 3 main video slots were released
|
|
887
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 3);
|
|
888
|
+
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
889
|
+
const slot = call.args[0];
|
|
890
|
+
|
|
891
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
895
|
+
|
|
896
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
897
|
+
|
|
898
|
+
// checking that slots are in the same order as in previous layout + 3 new ones
|
|
899
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
900
|
+
"fake video 0",
|
|
901
|
+
"fake video 1",
|
|
902
|
+
"fake video 2",
|
|
903
|
+
"fake video 3",
|
|
904
|
+
"fake video 4",
|
|
905
|
+
"fake video 5",
|
|
906
|
+
"fake video 10",
|
|
907
|
+
"fake video 11",
|
|
908
|
+
"fake video 12",
|
|
909
|
+
]);
|
|
910
|
+
|
|
911
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
912
|
+
"fake video 0",
|
|
913
|
+
"fake video 1",
|
|
914
|
+
"fake video 2",
|
|
915
|
+
"fake video 3",
|
|
916
|
+
"fake video 4",
|
|
917
|
+
"fake video 5",
|
|
918
|
+
"fake video 10",
|
|
919
|
+
"fake video 11",
|
|
920
|
+
"fake video 12"
|
|
921
|
+
])
|
|
922
|
+
|
|
923
|
+
// verify that 3 main video slots were allocated
|
|
924
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 3);
|
|
925
|
+
fakeReceiveSlotManager.allocateSlot.getCalls().forEach((call) => {
|
|
926
|
+
const mediaType = call.args[0];
|
|
927
|
+
|
|
928
|
+
assert.strictEqual(mediaType, MediaType.VideoMain);
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
it('stops all current video remoteMedia instances when switching to new layout', async () => {
|
|
933
|
+
const audioStopStubs = [];
|
|
934
|
+
const videoStopStubs = [];
|
|
935
|
+
|
|
936
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
937
|
+
|
|
938
|
+
// start with the stage layout because it has both active speaker and receiver selected panes
|
|
939
|
+
config.video.initialLayoutId = 'Stage';
|
|
940
|
+
|
|
941
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
942
|
+
fakeReceiveSlotManager,
|
|
943
|
+
fakeMediaRequestManagers,
|
|
944
|
+
config
|
|
945
|
+
);
|
|
946
|
+
|
|
947
|
+
// mock all stop() methods for all remote audio objects we get with AudioCreated event
|
|
948
|
+
remoteMediaManager.on(Event.AudioCreated, (audio: RemoteMediaGroup) => {
|
|
949
|
+
audio
|
|
950
|
+
.getRemoteMedia()
|
|
951
|
+
.forEach((remoteAudio) => audioStopStubs.push(sinon.stub(remoteAudio, 'stop')));
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
// mock all stop() methods for all remote video objects we get with VideoLayoutChanged event
|
|
955
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
956
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) =>
|
|
957
|
+
group
|
|
958
|
+
.getRemoteMedia()
|
|
959
|
+
.forEach((remoteMedia) => videoStopStubs.push(sinon.stub(remoteMedia, 'stop')))
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
Object.values(layoutInfo.memberVideoPanes).forEach((pane) => {
|
|
963
|
+
videoStopStubs.push(sinon.stub(pane, 'stop'));
|
|
964
|
+
});
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
await remoteMediaManager.start();
|
|
968
|
+
|
|
969
|
+
// sanity check that we've got all our stop() mocks setup correctly
|
|
970
|
+
assert.strictEqual(audioStopStubs.length, 3);
|
|
971
|
+
assert.strictEqual(videoStopStubs.length, 10); // 10 = 6 thumbnail panes + 4 stage panes
|
|
972
|
+
|
|
973
|
+
// next, we'll change the layout, we don't care about the new video panes from the new layout, so unregister the event listeners
|
|
974
|
+
remoteMediaManager.removeAllListeners();
|
|
975
|
+
|
|
976
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
977
|
+
|
|
978
|
+
// check that NONE of the audio RemoteMedia instances were stopped
|
|
979
|
+
audioStopStubs.forEach((audioStopStub) => {
|
|
980
|
+
assert.notCalled(audioStopStub);
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
// check that ALL of the video RemoteMedia instances were stopped
|
|
984
|
+
videoStopStubs.forEach((videoStopStub) => {
|
|
985
|
+
assert.calledOnce(videoStopStub);
|
|
986
|
+
assert.calledWith(videoStopStub, false);
|
|
987
|
+
});
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
it('emits Event.VideoLayoutChanged with correct data', async () => {
|
|
991
|
+
// setup the initial layout to be empty and a testLayout that has screen share, active speaker groups and member video panes
|
|
992
|
+
const config: Configuration = {
|
|
993
|
+
audio: {
|
|
994
|
+
numOfActiveSpeakerStreams: 0,
|
|
995
|
+
numOfScreenShareStreams: 0,
|
|
996
|
+
},
|
|
997
|
+
video: {
|
|
998
|
+
preferLiveVideo: true,
|
|
999
|
+
initialLayoutId: 'empty',
|
|
1000
|
+
layouts: {
|
|
1001
|
+
empty: {},
|
|
1002
|
+
testLayout: {
|
|
1003
|
+
screenShareVideo: {size: 'very small'},
|
|
1004
|
+
activeSpeakerVideoPaneGroups: [
|
|
1005
|
+
{
|
|
1006
|
+
id: 'big',
|
|
1007
|
+
numPanes: 10,
|
|
1008
|
+
priority: 255,
|
|
1009
|
+
size: 'large',
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
id: 'small',
|
|
1013
|
+
numPanes: 3,
|
|
1014
|
+
priority: 254,
|
|
1015
|
+
size: 'medium',
|
|
1016
|
+
},
|
|
1017
|
+
],
|
|
1018
|
+
memberVideoPanes: [
|
|
1019
|
+
{id: 'pane 1', size: 'best', csi: 555},
|
|
1020
|
+
{id: 'pane 2', size: 'best', csi: undefined},
|
|
1021
|
+
],
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
1028
|
+
fakeReceiveSlotManager,
|
|
1029
|
+
fakeMediaRequestManagers,
|
|
1030
|
+
config
|
|
1031
|
+
);
|
|
1032
|
+
|
|
1033
|
+
await remoteMediaManager.start();
|
|
1034
|
+
|
|
1035
|
+
resetHistory();
|
|
1036
|
+
|
|
1037
|
+
let receivedLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1038
|
+
|
|
1039
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo) => {
|
|
1040
|
+
receivedLayoutInfo = layoutInfo;
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
// switch to the test layout
|
|
1044
|
+
await remoteMediaManager.setLayout('testLayout');
|
|
1045
|
+
|
|
1046
|
+
assert.isNotNull(receivedLayoutInfo);
|
|
1047
|
+
|
|
1048
|
+
if (receivedLayoutInfo) {
|
|
1049
|
+
assert.strictEqual(receivedLayoutInfo.layoutId, 'testLayout');
|
|
1050
|
+
|
|
1051
|
+
// check screen share video
|
|
1052
|
+
assert.isTrue(!!receivedLayoutInfo.screenShareVideo);
|
|
1053
|
+
assert.strictEqual(receivedLayoutInfo.screenShareVideo.mediaType, MediaType.VideoSlides);
|
|
1054
|
+
|
|
1055
|
+
// check member videos
|
|
1056
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.memberVideoPanes).length, 2);
|
|
1057
|
+
Object.values(receivedLayoutInfo.memberVideoPanes).forEach((remoteMedia) =>
|
|
1058
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1059
|
+
);
|
|
1060
|
+
|
|
1061
|
+
// check the 2 active speaker groups
|
|
1062
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.activeSpeakerVideoPanes).length, 2);
|
|
1063
|
+
|
|
1064
|
+
// "big" group
|
|
1065
|
+
assert.strictEqual(
|
|
1066
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big.getRemoteMedia().length,
|
|
1067
|
+
10
|
|
1068
|
+
);
|
|
1069
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big
|
|
1070
|
+
.getRemoteMedia()
|
|
1071
|
+
.forEach((remoteMedia) =>
|
|
1072
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1073
|
+
);
|
|
1074
|
+
|
|
1075
|
+
// "small" group
|
|
1076
|
+
assert.strictEqual(
|
|
1077
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small.getRemoteMedia().length,
|
|
1078
|
+
3
|
|
1079
|
+
);
|
|
1080
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small
|
|
1081
|
+
.getRemoteMedia()
|
|
1082
|
+
.forEach((remoteMedia) =>
|
|
1083
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
|
|
545
1088
|
describe('switching between different receiver selected layouts', () => {
|
|
546
1089
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
547
1090
|
let slotCounter: number;
|
|
@@ -562,7 +1105,7 @@ describe('RemoteMediaManager', () => {
|
|
|
562
1105
|
slotCounter += 1;
|
|
563
1106
|
const newSlotId = `fake video slot ${slotCounter}`;
|
|
564
1107
|
|
|
565
|
-
fakeSlots[newSlotId] = new FakeSlot(
|
|
1108
|
+
fakeSlots[newSlotId] = new FakeSlot(MediaType.VideoMain, newSlotId);
|
|
566
1109
|
return fakeSlots[newSlotId];
|
|
567
1110
|
});
|
|
568
1111
|
|
|
@@ -594,12 +1137,12 @@ describe('RemoteMediaManager', () => {
|
|
|
594
1137
|
// This test starts with a layout that has 5 receiver selected video slots
|
|
595
1138
|
// and switches to a different layout that has fewer slots, but 2 of them match CSIs
|
|
596
1139
|
// from the initial layout. We want to verify that these 2 slots get re-used correctly.
|
|
1140
|
+
// There are no screen share or audio slots being used in this test.
|
|
1141
|
+
delete config.video.layouts.ScreenShareView;
|
|
597
1142
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
598
|
-
config.
|
|
599
|
-
config.screenShare.video = false;
|
|
1143
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
600
1144
|
config.video.initialLayoutId = 'biggerLayout';
|
|
601
1145
|
config.video.layouts['biggerLayout'] = {
|
|
602
|
-
screenShareVideo: {size: null},
|
|
603
1146
|
memberVideoPanes: [
|
|
604
1147
|
{id: '1', size: 'best', csi: 100},
|
|
605
1148
|
{id: '2', size: 'best', csi: 200},
|
|
@@ -609,7 +1152,6 @@ describe('RemoteMediaManager', () => {
|
|
|
609
1152
|
],
|
|
610
1153
|
};
|
|
611
1154
|
config.video.layouts['smallerLayout'] = {
|
|
612
|
-
screenShareVideo: {size: null},
|
|
613
1155
|
memberVideoPanes: [
|
|
614
1156
|
{id: '1', size: 'medium', csi: 200}, // this csi matches pane '2' from biggerLayout
|
|
615
1157
|
{id: '2', size: 'medium', csi: 123},
|
|
@@ -659,16 +1201,15 @@ describe('RemoteMediaManager', () => {
|
|
|
659
1201
|
// This test starts with a layout that has video slot with a specific CSI
|
|
660
1202
|
// and switches to a different layout that 2 panes with that same CSI.
|
|
661
1203
|
// We want to verify that the slot gets reused, but also that a 2nd slot is allocated.
|
|
1204
|
+
// There are no screen share or audio slots being used in this test.
|
|
1205
|
+
delete config.video.layouts.ScreenShareView;
|
|
662
1206
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
663
|
-
config.
|
|
664
|
-
config.screenShare.video = false;
|
|
1207
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
665
1208
|
config.video.initialLayoutId = 'initialEmptyLayout';
|
|
666
1209
|
config.video.layouts['initialEmptyLayout'] = {
|
|
667
|
-
screenShareVideo: {size: null},
|
|
668
1210
|
memberVideoPanes: [{id: '2', size: 'medium', csi: 456}],
|
|
669
1211
|
};
|
|
670
1212
|
config.video.layouts['layoutWithDuplicateCSIs'] = {
|
|
671
|
-
screenShareVideo: {size: null},
|
|
672
1213
|
memberVideoPanes: [
|
|
673
1214
|
{id: '1', size: 'medium', csi: 123},
|
|
674
1215
|
{id: '2', size: 'medium', csi: 456},
|
|
@@ -841,16 +1382,18 @@ describe('RemoteMediaManager', () => {
|
|
|
841
1382
|
});
|
|
842
1383
|
|
|
843
1384
|
it('cancels all media requests for the previous layout when switching to a new one', async () => {
|
|
1385
|
+
// setup the initial layout to have screen share, active speaker groups and member video panes
|
|
844
1386
|
const config: Configuration = {
|
|
845
1387
|
audio: {
|
|
846
1388
|
numOfActiveSpeakerStreams: 0,
|
|
1389
|
+
numOfScreenShareStreams: 0,
|
|
847
1390
|
},
|
|
848
1391
|
video: {
|
|
849
1392
|
preferLiveVideo: true,
|
|
850
1393
|
initialLayoutId: 'initial',
|
|
851
1394
|
layouts: {
|
|
852
1395
|
initial: {
|
|
853
|
-
screenShareVideo: {size:
|
|
1396
|
+
screenShareVideo: {size: 'best'},
|
|
854
1397
|
activeSpeakerVideoPaneGroups: [
|
|
855
1398
|
{
|
|
856
1399
|
id: 'big',
|
|
@@ -870,15 +1413,9 @@ describe('RemoteMediaManager', () => {
|
|
|
870
1413
|
{id: 'pane 2', size: 'best', csi: 234},
|
|
871
1414
|
],
|
|
872
1415
|
},
|
|
873
|
-
other: {
|
|
874
|
-
screenShareVideo: {size: null},
|
|
875
|
-
},
|
|
1416
|
+
other: {},
|
|
876
1417
|
},
|
|
877
1418
|
},
|
|
878
|
-
screenShare: {
|
|
879
|
-
audio: false,
|
|
880
|
-
video: false,
|
|
881
|
-
},
|
|
882
1419
|
};
|
|
883
1420
|
|
|
884
1421
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -901,9 +1438,15 @@ describe('RemoteMediaManager', () => {
|
|
|
901
1438
|
|
|
902
1439
|
return `receiver selected request ${receiverSelectedRequestCounter}`;
|
|
903
1440
|
});
|
|
1441
|
+
// setup the mock for screen share addRequest - this one should be called just once
|
|
1442
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest.callsFake(() => {
|
|
1443
|
+
return 'video screen share request id';
|
|
1444
|
+
});
|
|
904
1445
|
|
|
905
1446
|
await remoteMediaManager.start();
|
|
906
1447
|
|
|
1448
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.addRequest);
|
|
1449
|
+
|
|
907
1450
|
resetHistory();
|
|
908
1451
|
|
|
909
1452
|
// switch to "other" layout
|
|
@@ -921,11 +1464,45 @@ describe('RemoteMediaManager', () => {
|
|
|
921
1464
|
fakeMediaRequestManagers.video.cancelRequest,
|
|
922
1465
|
'receiver selected request 2'
|
|
923
1466
|
);
|
|
1467
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.cancelRequest);
|
|
1468
|
+
assert.calledWith(
|
|
1469
|
+
fakeMediaRequestManagers.screenShareVideo.cancelRequest,
|
|
1470
|
+
'video screen share request id'
|
|
1471
|
+
);
|
|
924
1472
|
|
|
925
1473
|
// new layout has no videos, so no new requests should be sent out
|
|
926
|
-
// check that 2 correct active speaker media requests were sent out
|
|
927
1474
|
assert.callCount(fakeMediaRequestManagers.video.addRequest, 0);
|
|
928
1475
|
});
|
|
1476
|
+
|
|
1477
|
+
it('sends media request for screen share if layout contains screen share', async () => {
|
|
1478
|
+
const allEqualMediaRequestId = 'fake request id';
|
|
1479
|
+
|
|
1480
|
+
fakeMediaRequestManagers.video.addRequest.returns(allEqualMediaRequestId);
|
|
1481
|
+
|
|
1482
|
+
await remoteMediaManager.start();
|
|
1483
|
+
|
|
1484
|
+
resetHistory();
|
|
1485
|
+
|
|
1486
|
+
// switch to a layout that contains a screen share video pane
|
|
1487
|
+
await remoteMediaManager.setLayout('ScreenShareView');
|
|
1488
|
+
|
|
1489
|
+
// check that a correct active speaker media request for screen share has been sent out
|
|
1490
|
+
assert.callCount(fakeMediaRequestManagers.screenShareVideo.addRequest, 1);
|
|
1491
|
+
assert.calledWith(
|
|
1492
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest,
|
|
1493
|
+
sinon.match({
|
|
1494
|
+
policyInfo: sinon.match({
|
|
1495
|
+
policy: 'active-speaker',
|
|
1496
|
+
priority: 255,
|
|
1497
|
+
}),
|
|
1498
|
+
receiveSlots: [fakeScreenShareVideoSlot],
|
|
1499
|
+
codecInfo: sinon.match({
|
|
1500
|
+
codec: 'h264',
|
|
1501
|
+
maxFs: 3600,
|
|
1502
|
+
}),
|
|
1503
|
+
})
|
|
1504
|
+
);
|
|
1505
|
+
});
|
|
929
1506
|
});
|
|
930
1507
|
});
|
|
931
1508
|
|
|
@@ -1065,7 +1642,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1065
1642
|
|
|
1066
1643
|
// new slot should be allocated
|
|
1067
1644
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1068
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1645
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1069
1646
|
|
|
1070
1647
|
// and a media request sent out
|
|
1071
1648
|
assert.calledOnce(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1094,7 +1671,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1094
1671
|
|
|
1095
1672
|
// new slot should be allocated
|
|
1096
1673
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1097
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1674
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1098
1675
|
|
|
1099
1676
|
// but no media requests sent out
|
|
1100
1677
|
assert.notCalled(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1123,7 +1700,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1123
1700
|
await remoteMediaManager.start();
|
|
1124
1701
|
await remoteMediaManager.setLayout('Stage');
|
|
1125
1702
|
|
|
1126
|
-
const fakeNewSlot = new FakeSlot(
|
|
1703
|
+
const fakeNewSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
1127
1704
|
const fakeRequestId = 'fake request id';
|
|
1128
1705
|
|
|
1129
1706
|
fakeReceiveSlotManager.allocateSlot.resolves(fakeNewSlot);
|
|
@@ -1147,6 +1724,94 @@ describe('RemoteMediaManager', () => {
|
|
|
1147
1724
|
});
|
|
1148
1725
|
});
|
|
1149
1726
|
|
|
1727
|
+
describe('setActiveSpeakerCsis', () => {
|
|
1728
|
+
it('calls setActiveSpeakerCsis on the correct remote media group', async () => {
|
|
1729
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1730
|
+
let setCsisStub;
|
|
1731
|
+
|
|
1732
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1733
|
+
currentLayoutInfo = layoutInfo;
|
|
1734
|
+
setCsisStub = sinon.stub(layoutInfo.activeSpeakerVideoPanes.main, 'setActiveSpeakerCsis');
|
|
1735
|
+
});
|
|
1736
|
+
|
|
1737
|
+
await remoteMediaManager.start();
|
|
1738
|
+
resetHistory();
|
|
1739
|
+
|
|
1740
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1741
|
+
|
|
1742
|
+
if (currentLayoutInfo) {
|
|
1743
|
+
const remoteVideo = currentLayoutInfo.activeSpeakerVideoPanes.main.getRemoteMedia()[0];
|
|
1744
|
+
|
|
1745
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: remoteVideo}]);
|
|
1746
|
+
|
|
1747
|
+
assert.calledOnce(setCsisStub);
|
|
1748
|
+
assert.calledWith(setCsisStub, [{remoteMedia: remoteVideo}], false);
|
|
1749
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1750
|
+
}
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
it('does not call setActiveSpeakerCsis on the incorrect media group', async () => {
|
|
1754
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1755
|
+
let setCsisStub;
|
|
1756
|
+
|
|
1757
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1758
|
+
currentLayoutInfo = layoutInfo;
|
|
1759
|
+
setCsisStub = sinon.stub(layoutInfo.activeSpeakerVideoPanes.main, 'setActiveSpeakerCsis');
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
await remoteMediaManager.start();
|
|
1763
|
+
resetHistory();
|
|
1764
|
+
|
|
1765
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1766
|
+
|
|
1767
|
+
if (currentLayoutInfo) {
|
|
1768
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: {}}]);
|
|
1769
|
+
|
|
1770
|
+
assert.notCalled(setCsisStub);
|
|
1771
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1772
|
+
}
|
|
1773
|
+
});
|
|
1774
|
+
|
|
1775
|
+
it('checking when there is more than one group', async () => {
|
|
1776
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1777
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
1778
|
+
let stubs = [];
|
|
1779
|
+
|
|
1780
|
+
config.video.initialLayoutId = 'OnePlusFive';
|
|
1781
|
+
|
|
1782
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
1783
|
+
fakeReceiveSlotManager,
|
|
1784
|
+
fakeMediaRequestManagers,
|
|
1785
|
+
config
|
|
1786
|
+
);
|
|
1787
|
+
|
|
1788
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1789
|
+
currentLayoutInfo = layoutInfo;
|
|
1790
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) => stubs.push(sinon.stub(group, 'setActiveSpeakerCsis')));
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1793
|
+
await remoteMediaManager.start();
|
|
1794
|
+
resetHistory();
|
|
1795
|
+
|
|
1796
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1797
|
+
|
|
1798
|
+
if (currentLayoutInfo) {
|
|
1799
|
+
|
|
1800
|
+
const remoteMedia1 = currentLayoutInfo.activeSpeakerVideoPanes.mainBigOne.getRemoteMedia()[0];
|
|
1801
|
+
const remoteMedia2 = currentLayoutInfo.activeSpeakerVideoPanes.secondarySetOfSmallPanes.getRemoteMedia()[0];
|
|
1802
|
+
|
|
1803
|
+
const remoteMediaCsis = [{remoteMedia: remoteMedia1}, {remoteMedia: remoteMedia2}];
|
|
1804
|
+
|
|
1805
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: remoteMedia1}, {remoteMedia: remoteMedia2}]);
|
|
1806
|
+
|
|
1807
|
+
stubs.forEach((stub, index) => {
|
|
1808
|
+
assert.calledWith(stub, [remoteMediaCsis[index]], false)
|
|
1809
|
+
});
|
|
1810
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1811
|
+
}
|
|
1812
|
+
});
|
|
1813
|
+
});
|
|
1814
|
+
|
|
1150
1815
|
describe('pinActiveSpeakerVideoPane() and isPinned()', () => {
|
|
1151
1816
|
it('throws if called on a pane not belonging to an active speaker group', async () => {
|
|
1152
1817
|
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|