@webex/plugin-meetings 3.0.0-beta.3 → 3.0.0-beta.300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/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/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- 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/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- 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 +54 -48
- 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 +41 -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 +9 -15
- package/dist/config.js.map +1 -1
- package/dist/constants.js +315 -68
- 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 +114 -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 +561 -246
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +10 -38
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +68 -38
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +314 -163
- 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 +103 -231
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +137 -222
- 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 +93 -14
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4624 -3740
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +249 -184
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +400 -346
- 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 +598 -586
- 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 +87 -39
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +349 -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 +143 -234
- 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 +813 -596
- 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 +183 -156
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +135 -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 +158 -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 +194 -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 +324 -259
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +14 -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 +263 -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 +536 -439
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/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 +322 -200
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +20 -26
- 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 +388 -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 +362 -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 +99 -94
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +131 -135
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +151 -101
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/global.js +1 -95
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +416 -497
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +145 -88
- 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/no-meeting-info.d.ts +14 -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/reclaim-host-role-errors.d.ts +60 -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 +93 -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 +36 -0
- package/dist/types/common/queue.d.ts +34 -0
- package/dist/types/config.d.ts +71 -0
- package/dist/types/constants.d.ts +1066 -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 +273 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/index.d.ts +34 -0
- package/dist/types/media/properties.d.ts +93 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +163 -0
- package/dist/types/meeting/index.d.ts +1676 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +184 -0
- package/dist/types/meeting/request.d.ts +290 -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 +102 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +69 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +123 -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 +160 -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 +25 -0
- package/dist/types/members/util.d.ts +215 -0
- package/dist/types/metrics/constants.d.ts +65 -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 +285 -0
- package/dist/types/multistream/sendSlotManager.d.ts +61 -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 +194 -0
- package/dist/types/reachability/request.d.ts +39 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +126 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +207 -0
- package/dist/types/recording-controller/util.d.ts +14 -0
- package/dist/types/roap/index.d.ts +78 -0
- package/dist/types/roap/request.d.ts +39 -0
- package/dist/types/roap/turnDiscovery.d.ts +92 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +201 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
- package/dist/types/transcription/index.d.ts +64 -0
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/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/no-meeting-info.ts +24 -0
- 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/reclaim-host-role-errors.ts +134 -0
- 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} +51 -8
- 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} +26 -9
- package/src/common/queue.ts +22 -9
- package/src/{config.js → config.ts} +18 -19
- package/src/constants.ts +260 -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 +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +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} +557 -119
- package/src/locus-info/{infoUtils.js → infoUtils.ts} +29 -10
- package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +81 -17
- package/src/locus-info/{parser.js → parser.ts} +303 -104
- package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
- package/src/media/index.ts +458 -0
- package/src/media/properties.ts +283 -0
- package/src/media/{util.js → util.ts} +2 -2
- package/src/mediaQualityMetrics/config.ts +384 -0
- package/src/meeting/in-meeting-actions.ts +191 -3
- package/src/meeting/index.ts +7882 -0
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +451 -0
- package/src/meeting/{request.js → request.ts} +421 -220
- package/src/meeting/request.type.ts +13 -0
- package/src/meeting/{state.js → state.ts} +50 -35
- package/src/meeting/util.ts +697 -0
- package/src/meeting-info/{collection.js → collection.ts} +6 -2
- package/src/meeting-info/index.ts +210 -0
- package/src/meeting-info/meeting-info-v2.ts +429 -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} +78 -71
- package/src/meetings/{collection.js → collection.ts} +26 -3
- package/src/meetings/index.ts +1470 -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} +132 -37
- package/src/member/{index.js → index.ts} +160 -56
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +397 -0
- package/src/members/{collection.js → collection.ts} +10 -2
- package/src/members/{index.js → index.ts} +351 -146
- package/src/members/request.ts +255 -0
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +353 -0
- package/src/metrics/{constants.js → constants.ts} +12 -6
- package/src/metrics/index.ts +73 -0
- package/src/multistream/mediaRequestManager.ts +337 -63
- 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 +300 -66
- package/src/multistream/sendSlotManager.ts +170 -0
- 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.ts +671 -0
- package/src/reachability/request.ts +50 -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} +258 -138
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +332 -0
- package/src/recording-controller/util.ts +75 -0
- package/src/roap/{index.js → index.ts} +127 -79
- package/src/roap/request.ts +153 -0
- package/src/roap/turnDiscovery.ts +109 -47
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/global.ts +37 -0
- package/src/statsAnalyzer/index.ts +1250 -0
- package/src/statsAnalyzer/mqaUtil.ts +292 -0
- package/src/transcription/{index.js → index.ts} +46 -39
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +233 -0
- package/test/integration/spec/journey.js +790 -530
- 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 +1390 -17
- package/test/unit/spec/locus-info/infoUtils.js +71 -40
- package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
- package/test/unit/spec/locus-info/lib/SeqCmp.json +529 -685
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +119 -44
- 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 +128 -77
- package/test/unit/spec/media/properties.ts +11 -11
- package/test/unit/spec/meeting/in-meeting-actions.ts +92 -3
- package/test/unit/spec/meeting/index.js +7433 -2752
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +420 -211
- package/test/unit/spec/meeting/request.js +545 -79
- package/test/unit/spec/meeting/utils.js +722 -174
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +624 -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 +1365 -377
- package/test/unit/spec/meetings/utils.js +216 -14
- package/test/unit/spec/member/index.js +61 -7
- package/test/unit/spec/member/util.js +526 -26
- package/test/unit/spec/members/index.js +536 -55
- package/test/unit/spec/members/request.js +228 -40
- package/test/unit/spec/members/utils.js +217 -4
- package/test/unit/spec/metrics/index.js +12 -66
- package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
- 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 +738 -65
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- 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 +598 -26
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +181 -12
- 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 +179 -64
- package/test/unit/spec/roap/request.ts +232 -0
- package/test/unit/spec/roap/turnDiscovery.ts +123 -58
- package/test/unit/spec/rtcMetrics/index.ts +73 -0
- package/test/unit/spec/stats-analyzer/index.js +199 -60
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- 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/media/properties.js +0 -289
- 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/reachability/index.js +0 -464
- 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
|
|
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,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,61 @@ 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#setLayout --> new layout selected: Stage'
|
|
751
|
+
);
|
|
752
|
+
assert.calledWith(
|
|
753
|
+
logger.log,
|
|
754
|
+
'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: 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'
|
|
755
|
+
);
|
|
515
756
|
});
|
|
516
757
|
|
|
758
|
+
it('logs layout changes - active speaker', async () => {
|
|
759
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
760
|
+
config.video.initialLayoutId = 'OnePlusFive'
|
|
761
|
+
|
|
762
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
763
|
+
fakeReceiveSlotManager,
|
|
764
|
+
fakeMediaRequestManagers,
|
|
765
|
+
config
|
|
766
|
+
);
|
|
767
|
+
|
|
768
|
+
await remoteMediaManager.start();
|
|
769
|
+
|
|
770
|
+
resetHistory();
|
|
771
|
+
|
|
772
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
773
|
+
|
|
774
|
+
assert.calledWith(
|
|
775
|
+
logger.log,
|
|
776
|
+
'RemoteMediaManager#setLayout --> new layout selected: AllEqual'
|
|
777
|
+
);
|
|
778
|
+
assert.calledWith(
|
|
779
|
+
logger.log,
|
|
780
|
+
'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: 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'
|
|
781
|
+
);
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
|
|
517
785
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
518
786
|
// start with "AllEqual" layout that needs just 9 video slots
|
|
519
787
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
@@ -538,10 +806,293 @@ describe('RemoteMediaManager', () => {
|
|
|
538
806
|
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
539
807
|
const slot = call.args[0];
|
|
540
808
|
|
|
541
|
-
assert.strictEqual(slot.mediaType,
|
|
809
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
542
810
|
});
|
|
543
811
|
});
|
|
544
812
|
|
|
813
|
+
it('releases slots and reallocates slots when switching to layouts in correct order', async () => {
|
|
814
|
+
|
|
815
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
816
|
+
let count = 0;
|
|
817
|
+
|
|
818
|
+
fakeReceiveSlotManager.allocateSlot = sinon.stub().callsFake((mediaType) => {
|
|
819
|
+
switch (mediaType) {
|
|
820
|
+
case MediaType.AudioMain:
|
|
821
|
+
return Promise.resolve(fakeAudioSlot);
|
|
822
|
+
case MediaType.VideoMain:
|
|
823
|
+
return Promise.resolve(new FakeSlot(MediaType.VideoMain, `fake video ${count++}`));
|
|
824
|
+
case MediaType.AudioSlides:
|
|
825
|
+
return Promise.resolve(fakeScreenShareAudioSlot);
|
|
826
|
+
case MediaType.VideoSlides:
|
|
827
|
+
return Promise.resolve(fakeScreenShareVideoSlot);
|
|
828
|
+
}
|
|
829
|
+
throw new Error(`invalid mediaType: ${mediaType}`);
|
|
830
|
+
})
|
|
831
|
+
|
|
832
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
833
|
+
fakeReceiveSlotManager,
|
|
834
|
+
fakeMediaRequestManagers,
|
|
835
|
+
config
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
await remoteMediaManager.start();
|
|
839
|
+
|
|
840
|
+
resetHistory();
|
|
841
|
+
|
|
842
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
843
|
+
"fake video 0",
|
|
844
|
+
"fake video 1",
|
|
845
|
+
"fake video 2",
|
|
846
|
+
"fake video 3",
|
|
847
|
+
"fake video 4",
|
|
848
|
+
"fake video 5",
|
|
849
|
+
"fake video 6",
|
|
850
|
+
"fake video 7",
|
|
851
|
+
"fake video 8",
|
|
852
|
+
]);
|
|
853
|
+
|
|
854
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
855
|
+
"fake video 0",
|
|
856
|
+
"fake video 1",
|
|
857
|
+
"fake video 2",
|
|
858
|
+
"fake video 3",
|
|
859
|
+
"fake video 4",
|
|
860
|
+
"fake video 5",
|
|
861
|
+
"fake video 6",
|
|
862
|
+
"fake video 7",
|
|
863
|
+
"fake video 8",
|
|
864
|
+
])
|
|
865
|
+
|
|
866
|
+
// switch to "OnePlusFive" layout that requires 3 less video slots (6)
|
|
867
|
+
await remoteMediaManager.setLayout('OnePlusFive');
|
|
868
|
+
|
|
869
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
870
|
+
|
|
871
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
872
|
+
"fake video 0",
|
|
873
|
+
"fake video 1",
|
|
874
|
+
"fake video 2",
|
|
875
|
+
"fake video 3",
|
|
876
|
+
"fake video 4",
|
|
877
|
+
"fake video 5"
|
|
878
|
+
]);
|
|
879
|
+
|
|
880
|
+
// we're checking that the slots are in the same order as in the previous layout
|
|
881
|
+
// first one goes into main
|
|
882
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["mainBigOne"].slots.map((slot: any) => slot.id), [
|
|
883
|
+
"fake video 0",
|
|
884
|
+
])
|
|
885
|
+
// and rest go in the pips
|
|
886
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["secondarySetOfSmallPanes"].slots.map((slot: any) => slot.id), [
|
|
887
|
+
"fake video 1",
|
|
888
|
+
"fake video 2",
|
|
889
|
+
"fake video 3",
|
|
890
|
+
"fake video 4",
|
|
891
|
+
"fake video 5"
|
|
892
|
+
])
|
|
893
|
+
|
|
894
|
+
// verify that 3 main video slots were released
|
|
895
|
+
assert.callCount(fakeReceiveSlotManager.releaseSlot, 3);
|
|
896
|
+
fakeReceiveSlotManager.releaseSlot.getCalls().forEach((call) => {
|
|
897
|
+
const slot = call.args[0];
|
|
898
|
+
|
|
899
|
+
assert.strictEqual(slot.mediaType, MediaType.VideoMain);
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
903
|
+
|
|
904
|
+
assert.deepEqual(remoteMediaManager.slots.video.unused, []);
|
|
905
|
+
|
|
906
|
+
// checking that slots are in the same order as in previous layout + 3 new ones
|
|
907
|
+
assert.deepEqual(remoteMediaManager.slots.video.activeSpeaker.map((slot: any) => slot.id), [
|
|
908
|
+
"fake video 0",
|
|
909
|
+
"fake video 1",
|
|
910
|
+
"fake video 2",
|
|
911
|
+
"fake video 3",
|
|
912
|
+
"fake video 4",
|
|
913
|
+
"fake video 5",
|
|
914
|
+
"fake video 10",
|
|
915
|
+
"fake video 11",
|
|
916
|
+
"fake video 12",
|
|
917
|
+
]);
|
|
918
|
+
|
|
919
|
+
assert.deepEqual(remoteMediaManager.receiveSlotAllocations.activeSpeaker["main"].slots.map((slot: any) => slot.id), [
|
|
920
|
+
"fake video 0",
|
|
921
|
+
"fake video 1",
|
|
922
|
+
"fake video 2",
|
|
923
|
+
"fake video 3",
|
|
924
|
+
"fake video 4",
|
|
925
|
+
"fake video 5",
|
|
926
|
+
"fake video 10",
|
|
927
|
+
"fake video 11",
|
|
928
|
+
"fake video 12"
|
|
929
|
+
])
|
|
930
|
+
|
|
931
|
+
// verify that 3 main video slots were allocated
|
|
932
|
+
assert.callCount(fakeReceiveSlotManager.allocateSlot, 3);
|
|
933
|
+
fakeReceiveSlotManager.allocateSlot.getCalls().forEach((call) => {
|
|
934
|
+
const mediaType = call.args[0];
|
|
935
|
+
|
|
936
|
+
assert.strictEqual(mediaType, MediaType.VideoMain);
|
|
937
|
+
});
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
it('stops all current video remoteMedia instances when switching to new layout', async () => {
|
|
941
|
+
const audioStopStubs = [];
|
|
942
|
+
const videoStopStubs = [];
|
|
943
|
+
|
|
944
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
945
|
+
|
|
946
|
+
// start with the stage layout because it has both active speaker and receiver selected panes
|
|
947
|
+
config.video.initialLayoutId = 'Stage';
|
|
948
|
+
|
|
949
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
950
|
+
fakeReceiveSlotManager,
|
|
951
|
+
fakeMediaRequestManagers,
|
|
952
|
+
config
|
|
953
|
+
);
|
|
954
|
+
|
|
955
|
+
// mock all stop() methods for all remote audio objects we get with AudioCreated event
|
|
956
|
+
remoteMediaManager.on(Event.AudioCreated, (audio: RemoteMediaGroup) => {
|
|
957
|
+
audio
|
|
958
|
+
.getRemoteMedia()
|
|
959
|
+
.forEach((remoteAudio) => audioStopStubs.push(sinon.stub(remoteAudio, 'stop')));
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
// mock all stop() methods for all remote video objects we get with VideoLayoutChanged event
|
|
963
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
964
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) =>
|
|
965
|
+
group
|
|
966
|
+
.getRemoteMedia()
|
|
967
|
+
.forEach((remoteMedia) => videoStopStubs.push(sinon.stub(remoteMedia, 'stop')))
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
Object.values(layoutInfo.memberVideoPanes).forEach((pane) => {
|
|
971
|
+
videoStopStubs.push(sinon.stub(pane, 'stop'));
|
|
972
|
+
});
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
await remoteMediaManager.start();
|
|
976
|
+
|
|
977
|
+
// sanity check that we've got all our stop() mocks setup correctly
|
|
978
|
+
assert.strictEqual(audioStopStubs.length, 3);
|
|
979
|
+
assert.strictEqual(videoStopStubs.length, 10); // 10 = 6 thumbnail panes + 4 stage panes
|
|
980
|
+
|
|
981
|
+
// next, we'll change the layout, we don't care about the new video panes from the new layout, so unregister the event listeners
|
|
982
|
+
remoteMediaManager.removeAllListeners();
|
|
983
|
+
|
|
984
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
985
|
+
|
|
986
|
+
// check that NONE of the audio RemoteMedia instances were stopped
|
|
987
|
+
audioStopStubs.forEach((audioStopStub) => {
|
|
988
|
+
assert.notCalled(audioStopStub);
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// check that ALL of the video RemoteMedia instances were stopped
|
|
992
|
+
videoStopStubs.forEach((videoStopStub) => {
|
|
993
|
+
assert.calledOnce(videoStopStub);
|
|
994
|
+
assert.calledWith(videoStopStub, false);
|
|
995
|
+
});
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
it('emits Event.VideoLayoutChanged with correct data', async () => {
|
|
999
|
+
// setup the initial layout to be empty and a testLayout that has screen share, active speaker groups and member video panes
|
|
1000
|
+
const config: Configuration = {
|
|
1001
|
+
audio: {
|
|
1002
|
+
numOfActiveSpeakerStreams: 0,
|
|
1003
|
+
numOfScreenShareStreams: 0,
|
|
1004
|
+
},
|
|
1005
|
+
video: {
|
|
1006
|
+
preferLiveVideo: true,
|
|
1007
|
+
initialLayoutId: 'empty',
|
|
1008
|
+
layouts: {
|
|
1009
|
+
empty: {},
|
|
1010
|
+
testLayout: {
|
|
1011
|
+
screenShareVideo: {size: 'very small'},
|
|
1012
|
+
activeSpeakerVideoPaneGroups: [
|
|
1013
|
+
{
|
|
1014
|
+
id: 'big',
|
|
1015
|
+
numPanes: 10,
|
|
1016
|
+
priority: 255,
|
|
1017
|
+
size: 'large',
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
id: 'small',
|
|
1021
|
+
numPanes: 3,
|
|
1022
|
+
priority: 254,
|
|
1023
|
+
size: 'medium',
|
|
1024
|
+
},
|
|
1025
|
+
],
|
|
1026
|
+
memberVideoPanes: [
|
|
1027
|
+
{id: 'pane 1', size: 'best', csi: 555},
|
|
1028
|
+
{id: 'pane 2', size: 'best', csi: undefined},
|
|
1029
|
+
],
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
},
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
1036
|
+
fakeReceiveSlotManager,
|
|
1037
|
+
fakeMediaRequestManagers,
|
|
1038
|
+
config
|
|
1039
|
+
);
|
|
1040
|
+
|
|
1041
|
+
await remoteMediaManager.start();
|
|
1042
|
+
|
|
1043
|
+
resetHistory();
|
|
1044
|
+
|
|
1045
|
+
let receivedLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1046
|
+
|
|
1047
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo) => {
|
|
1048
|
+
receivedLayoutInfo = layoutInfo;
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
// switch to the test layout
|
|
1052
|
+
await remoteMediaManager.setLayout('testLayout');
|
|
1053
|
+
|
|
1054
|
+
assert.isNotNull(receivedLayoutInfo);
|
|
1055
|
+
|
|
1056
|
+
if (receivedLayoutInfo) {
|
|
1057
|
+
assert.strictEqual(receivedLayoutInfo.layoutId, 'testLayout');
|
|
1058
|
+
|
|
1059
|
+
// check screen share video
|
|
1060
|
+
assert.isTrue(!!receivedLayoutInfo.screenShareVideo);
|
|
1061
|
+
assert.strictEqual(receivedLayoutInfo.screenShareVideo.mediaType, MediaType.VideoSlides);
|
|
1062
|
+
|
|
1063
|
+
// check member videos
|
|
1064
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.memberVideoPanes).length, 2);
|
|
1065
|
+
Object.values(receivedLayoutInfo.memberVideoPanes).forEach((remoteMedia) =>
|
|
1066
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1067
|
+
);
|
|
1068
|
+
|
|
1069
|
+
// check the 2 active speaker groups
|
|
1070
|
+
assert.strictEqual(Object.keys(receivedLayoutInfo.activeSpeakerVideoPanes).length, 2);
|
|
1071
|
+
|
|
1072
|
+
// "big" group
|
|
1073
|
+
assert.strictEqual(
|
|
1074
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big.getRemoteMedia().length,
|
|
1075
|
+
10
|
|
1076
|
+
);
|
|
1077
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.big
|
|
1078
|
+
.getRemoteMedia()
|
|
1079
|
+
.forEach((remoteMedia) =>
|
|
1080
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1081
|
+
);
|
|
1082
|
+
|
|
1083
|
+
// "small" group
|
|
1084
|
+
assert.strictEqual(
|
|
1085
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small.getRemoteMedia().length,
|
|
1086
|
+
3
|
|
1087
|
+
);
|
|
1088
|
+
receivedLayoutInfo.activeSpeakerVideoPanes.small
|
|
1089
|
+
.getRemoteMedia()
|
|
1090
|
+
.forEach((remoteMedia) =>
|
|
1091
|
+
assert.strictEqual(remoteMedia.mediaType, MediaType.VideoMain)
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
|
|
545
1096
|
describe('switching between different receiver selected layouts', () => {
|
|
546
1097
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
547
1098
|
let slotCounter: number;
|
|
@@ -562,7 +1113,7 @@ describe('RemoteMediaManager', () => {
|
|
|
562
1113
|
slotCounter += 1;
|
|
563
1114
|
const newSlotId = `fake video slot ${slotCounter}`;
|
|
564
1115
|
|
|
565
|
-
fakeSlots[newSlotId] = new FakeSlot(
|
|
1116
|
+
fakeSlots[newSlotId] = new FakeSlot(MediaType.VideoMain, newSlotId);
|
|
566
1117
|
return fakeSlots[newSlotId];
|
|
567
1118
|
});
|
|
568
1119
|
|
|
@@ -594,12 +1145,12 @@ describe('RemoteMediaManager', () => {
|
|
|
594
1145
|
// This test starts with a layout that has 5 receiver selected video slots
|
|
595
1146
|
// and switches to a different layout that has fewer slots, but 2 of them match CSIs
|
|
596
1147
|
// from the initial layout. We want to verify that these 2 slots get re-used correctly.
|
|
1148
|
+
// There are no screen share or audio slots being used in this test.
|
|
1149
|
+
delete config.video.layouts.ScreenShareView;
|
|
597
1150
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
598
|
-
config.
|
|
599
|
-
config.screenShare.video = false;
|
|
1151
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
600
1152
|
config.video.initialLayoutId = 'biggerLayout';
|
|
601
1153
|
config.video.layouts['biggerLayout'] = {
|
|
602
|
-
screenShareVideo: {size: null},
|
|
603
1154
|
memberVideoPanes: [
|
|
604
1155
|
{id: '1', size: 'best', csi: 100},
|
|
605
1156
|
{id: '2', size: 'best', csi: 200},
|
|
@@ -609,7 +1160,6 @@ describe('RemoteMediaManager', () => {
|
|
|
609
1160
|
],
|
|
610
1161
|
};
|
|
611
1162
|
config.video.layouts['smallerLayout'] = {
|
|
612
|
-
screenShareVideo: {size: null},
|
|
613
1163
|
memberVideoPanes: [
|
|
614
1164
|
{id: '1', size: 'medium', csi: 200}, // this csi matches pane '2' from biggerLayout
|
|
615
1165
|
{id: '2', size: 'medium', csi: 123},
|
|
@@ -659,16 +1209,15 @@ describe('RemoteMediaManager', () => {
|
|
|
659
1209
|
// This test starts with a layout that has video slot with a specific CSI
|
|
660
1210
|
// and switches to a different layout that 2 panes with that same CSI.
|
|
661
1211
|
// We want to verify that the slot gets reused, but also that a 2nd slot is allocated.
|
|
1212
|
+
// There are no screen share or audio slots being used in this test.
|
|
1213
|
+
delete config.video.layouts.ScreenShareView;
|
|
662
1214
|
config.audio.numOfActiveSpeakerStreams = 0;
|
|
663
|
-
config.
|
|
664
|
-
config.screenShare.video = false;
|
|
1215
|
+
config.audio.numOfScreenShareStreams = 0;
|
|
665
1216
|
config.video.initialLayoutId = 'initialEmptyLayout';
|
|
666
1217
|
config.video.layouts['initialEmptyLayout'] = {
|
|
667
|
-
screenShareVideo: {size: null},
|
|
668
1218
|
memberVideoPanes: [{id: '2', size: 'medium', csi: 456}],
|
|
669
1219
|
};
|
|
670
1220
|
config.video.layouts['layoutWithDuplicateCSIs'] = {
|
|
671
|
-
screenShareVideo: {size: null},
|
|
672
1221
|
memberVideoPanes: [
|
|
673
1222
|
{id: '1', size: 'medium', csi: 123},
|
|
674
1223
|
{id: '2', size: 'medium', csi: 456},
|
|
@@ -841,16 +1390,18 @@ describe('RemoteMediaManager', () => {
|
|
|
841
1390
|
});
|
|
842
1391
|
|
|
843
1392
|
it('cancels all media requests for the previous layout when switching to a new one', async () => {
|
|
1393
|
+
// setup the initial layout to have screen share, active speaker groups and member video panes
|
|
844
1394
|
const config: Configuration = {
|
|
845
1395
|
audio: {
|
|
846
1396
|
numOfActiveSpeakerStreams: 0,
|
|
1397
|
+
numOfScreenShareStreams: 0,
|
|
847
1398
|
},
|
|
848
1399
|
video: {
|
|
849
1400
|
preferLiveVideo: true,
|
|
850
1401
|
initialLayoutId: 'initial',
|
|
851
1402
|
layouts: {
|
|
852
1403
|
initial: {
|
|
853
|
-
screenShareVideo: {size:
|
|
1404
|
+
screenShareVideo: {size: 'best'},
|
|
854
1405
|
activeSpeakerVideoPaneGroups: [
|
|
855
1406
|
{
|
|
856
1407
|
id: 'big',
|
|
@@ -870,15 +1421,9 @@ describe('RemoteMediaManager', () => {
|
|
|
870
1421
|
{id: 'pane 2', size: 'best', csi: 234},
|
|
871
1422
|
],
|
|
872
1423
|
},
|
|
873
|
-
other: {
|
|
874
|
-
screenShareVideo: {size: null},
|
|
875
|
-
},
|
|
1424
|
+
other: {},
|
|
876
1425
|
},
|
|
877
1426
|
},
|
|
878
|
-
screenShare: {
|
|
879
|
-
audio: false,
|
|
880
|
-
video: false,
|
|
881
|
-
},
|
|
882
1427
|
};
|
|
883
1428
|
|
|
884
1429
|
remoteMediaManager = new RemoteMediaManager(
|
|
@@ -901,9 +1446,15 @@ describe('RemoteMediaManager', () => {
|
|
|
901
1446
|
|
|
902
1447
|
return `receiver selected request ${receiverSelectedRequestCounter}`;
|
|
903
1448
|
});
|
|
1449
|
+
// setup the mock for screen share addRequest - this one should be called just once
|
|
1450
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest.callsFake(() => {
|
|
1451
|
+
return 'video screen share request id';
|
|
1452
|
+
});
|
|
904
1453
|
|
|
905
1454
|
await remoteMediaManager.start();
|
|
906
1455
|
|
|
1456
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.addRequest);
|
|
1457
|
+
|
|
907
1458
|
resetHistory();
|
|
908
1459
|
|
|
909
1460
|
// switch to "other" layout
|
|
@@ -921,11 +1472,45 @@ describe('RemoteMediaManager', () => {
|
|
|
921
1472
|
fakeMediaRequestManagers.video.cancelRequest,
|
|
922
1473
|
'receiver selected request 2'
|
|
923
1474
|
);
|
|
1475
|
+
assert.calledOnce(fakeMediaRequestManagers.screenShareVideo.cancelRequest);
|
|
1476
|
+
assert.calledWith(
|
|
1477
|
+
fakeMediaRequestManagers.screenShareVideo.cancelRequest,
|
|
1478
|
+
'video screen share request id'
|
|
1479
|
+
);
|
|
924
1480
|
|
|
925
1481
|
// 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
1482
|
assert.callCount(fakeMediaRequestManagers.video.addRequest, 0);
|
|
928
1483
|
});
|
|
1484
|
+
|
|
1485
|
+
it('sends media request for screen share if layout contains screen share', async () => {
|
|
1486
|
+
const allEqualMediaRequestId = 'fake request id';
|
|
1487
|
+
|
|
1488
|
+
fakeMediaRequestManagers.video.addRequest.returns(allEqualMediaRequestId);
|
|
1489
|
+
|
|
1490
|
+
await remoteMediaManager.start();
|
|
1491
|
+
|
|
1492
|
+
resetHistory();
|
|
1493
|
+
|
|
1494
|
+
// switch to a layout that contains a screen share video pane
|
|
1495
|
+
await remoteMediaManager.setLayout('ScreenShareView');
|
|
1496
|
+
|
|
1497
|
+
// check that a correct active speaker media request for screen share has been sent out
|
|
1498
|
+
assert.callCount(fakeMediaRequestManagers.screenShareVideo.addRequest, 1);
|
|
1499
|
+
assert.calledWith(
|
|
1500
|
+
fakeMediaRequestManagers.screenShareVideo.addRequest,
|
|
1501
|
+
sinon.match({
|
|
1502
|
+
policyInfo: sinon.match({
|
|
1503
|
+
policy: 'active-speaker',
|
|
1504
|
+
priority: 255,
|
|
1505
|
+
}),
|
|
1506
|
+
receiveSlots: [fakeScreenShareVideoSlot],
|
|
1507
|
+
codecInfo: sinon.match({
|
|
1508
|
+
codec: 'h264',
|
|
1509
|
+
maxFs: 3600,
|
|
1510
|
+
}),
|
|
1511
|
+
})
|
|
1512
|
+
);
|
|
1513
|
+
});
|
|
929
1514
|
});
|
|
930
1515
|
});
|
|
931
1516
|
|
|
@@ -1065,7 +1650,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1065
1650
|
|
|
1066
1651
|
// new slot should be allocated
|
|
1067
1652
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1068
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1653
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1069
1654
|
|
|
1070
1655
|
// and a media request sent out
|
|
1071
1656
|
assert.calledOnce(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1094,7 +1679,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1094
1679
|
|
|
1095
1680
|
// new slot should be allocated
|
|
1096
1681
|
assert.calledOnce(fakeReceiveSlotManager.allocateSlot);
|
|
1097
|
-
assert.calledWith(fakeReceiveSlotManager.allocateSlot,
|
|
1682
|
+
assert.calledWith(fakeReceiveSlotManager.allocateSlot, MediaType.VideoMain);
|
|
1098
1683
|
|
|
1099
1684
|
// but no media requests sent out
|
|
1100
1685
|
assert.notCalled(fakeMediaRequestManagers.video.addRequest);
|
|
@@ -1123,7 +1708,7 @@ describe('RemoteMediaManager', () => {
|
|
|
1123
1708
|
await remoteMediaManager.start();
|
|
1124
1709
|
await remoteMediaManager.setLayout('Stage');
|
|
1125
1710
|
|
|
1126
|
-
const fakeNewSlot = new FakeSlot(
|
|
1711
|
+
const fakeNewSlot = new FakeSlot(MediaType.VideoMain, 'fake video slot');
|
|
1127
1712
|
const fakeRequestId = 'fake request id';
|
|
1128
1713
|
|
|
1129
1714
|
fakeReceiveSlotManager.allocateSlot.resolves(fakeNewSlot);
|
|
@@ -1147,6 +1732,94 @@ describe('RemoteMediaManager', () => {
|
|
|
1147
1732
|
});
|
|
1148
1733
|
});
|
|
1149
1734
|
|
|
1735
|
+
describe('setActiveSpeakerCsis', () => {
|
|
1736
|
+
it('calls setActiveSpeakerCsis on the correct remote media group', async () => {
|
|
1737
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1738
|
+
let setCsisStub;
|
|
1739
|
+
|
|
1740
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1741
|
+
currentLayoutInfo = layoutInfo;
|
|
1742
|
+
setCsisStub = sinon.stub(layoutInfo.activeSpeakerVideoPanes.main, 'setActiveSpeakerCsis');
|
|
1743
|
+
});
|
|
1744
|
+
|
|
1745
|
+
await remoteMediaManager.start();
|
|
1746
|
+
resetHistory();
|
|
1747
|
+
|
|
1748
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1749
|
+
|
|
1750
|
+
if (currentLayoutInfo) {
|
|
1751
|
+
const remoteVideo = currentLayoutInfo.activeSpeakerVideoPanes.main.getRemoteMedia()[0];
|
|
1752
|
+
|
|
1753
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: remoteVideo}]);
|
|
1754
|
+
|
|
1755
|
+
assert.calledOnce(setCsisStub);
|
|
1756
|
+
assert.calledWith(setCsisStub, [{remoteMedia: remoteVideo}], false);
|
|
1757
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1758
|
+
}
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
it('does not call setActiveSpeakerCsis on the incorrect media group', async () => {
|
|
1762
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1763
|
+
let setCsisStub;
|
|
1764
|
+
|
|
1765
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1766
|
+
currentLayoutInfo = layoutInfo;
|
|
1767
|
+
setCsisStub = sinon.stub(layoutInfo.activeSpeakerVideoPanes.main, 'setActiveSpeakerCsis');
|
|
1768
|
+
});
|
|
1769
|
+
|
|
1770
|
+
await remoteMediaManager.start();
|
|
1771
|
+
resetHistory();
|
|
1772
|
+
|
|
1773
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1774
|
+
|
|
1775
|
+
if (currentLayoutInfo) {
|
|
1776
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: {}}]);
|
|
1777
|
+
|
|
1778
|
+
assert.notCalled(setCsisStub);
|
|
1779
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
|
|
1783
|
+
it('checking when there is more than one group', async () => {
|
|
1784
|
+
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|
|
1785
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
1786
|
+
let stubs = [];
|
|
1787
|
+
|
|
1788
|
+
config.video.initialLayoutId = 'OnePlusFive';
|
|
1789
|
+
|
|
1790
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
1791
|
+
fakeReceiveSlotManager,
|
|
1792
|
+
fakeMediaRequestManagers,
|
|
1793
|
+
config
|
|
1794
|
+
);
|
|
1795
|
+
|
|
1796
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
1797
|
+
currentLayoutInfo = layoutInfo;
|
|
1798
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) => stubs.push(sinon.stub(group, 'setActiveSpeakerCsis')));
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
await remoteMediaManager.start();
|
|
1802
|
+
resetHistory();
|
|
1803
|
+
|
|
1804
|
+
assert.isNotNull(currentLayoutInfo);
|
|
1805
|
+
|
|
1806
|
+
if (currentLayoutInfo) {
|
|
1807
|
+
|
|
1808
|
+
const remoteMedia1 = currentLayoutInfo.activeSpeakerVideoPanes.mainBigOne.getRemoteMedia()[0];
|
|
1809
|
+
const remoteMedia2 = currentLayoutInfo.activeSpeakerVideoPanes.secondarySetOfSmallPanes.getRemoteMedia()[0];
|
|
1810
|
+
|
|
1811
|
+
const remoteMediaCsis = [{remoteMedia: remoteMedia1}, {remoteMedia: remoteMedia2}];
|
|
1812
|
+
|
|
1813
|
+
remoteMediaManager.setActiveSpeakerCsis([{remoteMedia: remoteMedia1}, {remoteMedia: remoteMedia2}]);
|
|
1814
|
+
|
|
1815
|
+
stubs.forEach((stub, index) => {
|
|
1816
|
+
assert.calledWith(stub, [remoteMediaCsis[index]], false)
|
|
1817
|
+
});
|
|
1818
|
+
assert.calledOnce(fakeMediaRequestManagers.video.commit);
|
|
1819
|
+
}
|
|
1820
|
+
});
|
|
1821
|
+
});
|
|
1822
|
+
|
|
1150
1823
|
describe('pinActiveSpeakerVideoPane() and isPinned()', () => {
|
|
1151
1824
|
it('throws if called on a pane not belonging to an active speaker group', async () => {
|
|
1152
1825
|
let currentLayoutInfo: VideoLayoutChangedEventData | null = null;
|