@webex/plugin-meetings 3.0.0-test.1 → 3.1.0
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/.eslintrc.js +6 -0
- package/babel.config.js +3 -0
- package/dist/annotation/constants.js +12 -20
- package/dist/annotation/constants.js.map +1 -1
- package/dist/annotation/index.js +25 -10
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +2 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/collection.js +1 -2
- package/dist/breakouts/collection.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +1 -2
- package/dist/breakouts/edit-lock-error.js.map +1 -1
- package/dist/breakouts/events.js +1 -2
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +13 -14
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +1 -2
- package/dist/breakouts/request.js.map +1 -1
- package/dist/breakouts/utils.js +3 -6
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +1 -2
- package/dist/common/errors/no-meeting-info.js.map +1 -1
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.js +6 -10
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
- package/dist/common/errors/reconnection-in-progress.js +1 -2
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +1 -2
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +1 -2
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +14 -15
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +1 -2
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +1 -2
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +1 -2
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +1 -2
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +1 -2
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -2
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/{types/common → common}/logs/request.d.ts +1 -1
- package/dist/common/logs/request.js +3 -4
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +2 -4
- package/dist/common/queue.js.map +1 -1
- package/dist/{types/config.d.ts → config.d.ts} +1 -0
- package/dist/config.js +4 -3
- package/dist/config.js.map +1 -1
- package/dist/{types/constants.d.ts → constants.d.ts} +10 -5
- package/dist/constants.js +207 -380
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +3 -6
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +7 -10
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +27 -32
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +1 -2
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +4 -3
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interpretation/collection.js +1 -2
- package/dist/interpretation/collection.js.map +1 -1
- package/dist/interpretation/index.js +4 -5
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +2 -3
- package/dist/interpretation/siLanguage.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +12 -13
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -4
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +1 -2
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +1 -2
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +23 -27
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +3 -4
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +16 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +6 -10
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +12 -6
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/media/MediaConnectionAwaiter.js +163 -0
- package/dist/media/MediaConnectionAwaiter.js.map +1 -0
- package/dist/media/index.js +9 -5
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +7 -28
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -2
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +9 -18
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +14 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/{types/meeting → meeting}/index.d.ts +71 -16
- package/dist/meeting/index.js +1411 -1036
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +4 -5
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +2 -4
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/{types/meeting → meeting}/request.d.ts +3 -0
- package/dist/meeting/request.js +45 -36
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/{types/meeting → meeting}/util.d.ts +1 -0
- package/dist/meeting/util.js +13 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +16 -0
- package/dist/meeting/voicea-meeting.js +169 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +5 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +27 -29
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +8 -8
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +15 -9
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +5 -6
- package/dist/meetings/collection.js.map +1 -1
- package/dist/{types/meetings → meetings}/index.d.ts +11 -2
- package/dist/meetings/index.js +44 -17
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +2 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +1 -4
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +1 -3
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +6 -8
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +1 -2
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +8 -7
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +2 -3
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +3 -4
- package/dist/members/types.js.map +1 -1
- package/dist/{types/members → members}/util.d.ts +1 -1
- package/dist/members/util.js +3 -4
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -2
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +3 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/{types/multistream → multistream}/mediaRequestManager.d.ts +1 -2
- package/dist/multistream/mediaRequestManager.js +9 -11
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +3 -5
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +7 -9
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/{types/multistream → multistream}/remoteMediaGroup.d.ts +1 -1
- package/dist/multistream/remoteMediaGroup.js +7 -6
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/{types/multistream → multistream}/remoteMediaManager.d.ts +1 -2
- package/dist/multistream/remoteMediaManager.js +32 -29
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/{types/multistream → multistream}/sendSlotManager.d.ts +1 -2
- package/dist/multistream/sendSlotManager.js +9 -6
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +1 -2
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +2 -3
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -3
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +1 -2
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/{types/reachability → reachability}/clusterReachability.d.ts +1 -0
- package/dist/reachability/clusterReachability.js +35 -20
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/{types/reachability → reachability}/index.d.ts +4 -0
- package/dist/reachability/index.js +41 -12
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +25 -20
- package/dist/reachability/request.js.map +1 -1
- package/dist/{types/reachability → reachability}/util.d.ts +7 -0
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reactions/constants.js +1 -2
- package/dist/reactions/constants.js.map +1 -1
- package/dist/reactions/reactions.js +2 -4
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js +6 -8
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +18 -11
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +43 -51
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +1 -2
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/{types/roap → roap}/index.d.ts +10 -2
- package/dist/roap/index.js +17 -3
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +10 -10
- package/dist/roap/request.js.map +1 -1
- package/dist/{types/roap → roap}/turnDiscovery.d.ts +64 -17
- package/dist/roap/turnDiscovery.js +316 -134
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +1 -2
- package/dist/rtcMetrics/constants.js.map +1 -1
- package/dist/rtcMetrics/index.js +4 -6
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/global.js +1 -2
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +123 -96
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +24 -31
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.js +1 -2
- package/dist/webinar/collection.js.map +1 -1
- package/dist/webinar/index.js +2 -3
- package/dist/webinar/index.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +44 -25
- package/process +1 -0
- package/src/config.ts +3 -4
- package/src/constants.ts +13 -4
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/selfUtils.ts +5 -0
- package/src/media/MediaConnectionAwaiter.ts +174 -0
- package/src/media/index.ts +3 -1
- package/src/media/properties.ts +6 -31
- package/src/meeting/index.ts +526 -227
- package/src/meeting/request.ts +18 -2
- package/src/meeting/util.ts +6 -1
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/meeting-info-v2.ts +5 -11
- package/src/meeting-info/util.ts +12 -9
- package/src/meeting-info/utilv2.ts +26 -15
- package/src/meetings/index.ts +18 -0
- package/src/member/index.ts +0 -1
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/multistream/remoteMediaGroup.ts +1 -1
- package/src/multistream/remoteMediaManager.ts +1 -2
- package/src/multistream/sendSlotManager.ts +1 -2
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/request.ts +15 -11
- package/src/reachability/util.ts +21 -0
- package/src/reconnection-manager/index.ts +1 -1
- package/src/roap/index.ts +25 -3
- package/src/roap/request.ts +2 -2
- package/src/roap/turnDiscovery.ts +244 -78
- package/src/statsAnalyzer/index.ts +63 -27
- package/test/integration/spec/journey.js +2 -2
- package/test/unit/spec/breakouts/breakout.ts +2 -1
- package/test/unit/spec/breakouts/index.ts +7 -4
- package/test/unit/spec/interpretation/index.ts +4 -1
- package/test/unit/spec/locus-info/index.js +27 -18
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
- package/test/unit/spec/locus-info/selfUtils.js +41 -11
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
- package/test/unit/spec/media/index.ts +94 -78
- package/test/unit/spec/media/properties.ts +16 -70
- package/test/unit/spec/meeting/index.js +757 -141
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +58 -11
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +20 -15
- package/test/unit/spec/meeting-info/utilv2.js +6 -0
- package/test/unit/spec/meetings/index.js +101 -13
- package/test/unit/spec/metrics/index.js +1 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +0 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -1
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/request.js +15 -7
- package/test/unit/spec/reachability/util.ts +32 -2
- package/test/unit/spec/reconnection-manager/index.js +28 -0
- package/test/unit/spec/recording-controller/index.js +0 -1
- package/test/unit/spec/roap/index.ts +61 -6
- package/test/unit/spec/roap/turnDiscovery.ts +299 -17
- package/test/unit/spec/stats-analyzer/index.js +179 -0
- /package/dist/{types/annotation → annotation}/annotation.types.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/constants.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/breakout.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/collection.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/edit-lock-error.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/events.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/request.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/utils.d.ts +0 -0
- /package/dist/{types/common → common}/browser-detection.d.ts +0 -0
- /package/dist/{types/common → common}/collection.d.ts +0 -0
- /package/dist/{types/common → common}/config.d.ts +0 -0
- /package/dist/{types/common → common}/errors/captcha-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/intent-to-join.d.ts +0 -0
- /package/dist/{types/common → common}/errors/join-meeting.d.ts +0 -0
- /package/dist/{types/common → common}/errors/media.d.ts +0 -0
- /package/dist/{types/common → common}/errors/no-meeting-info.d.ts +0 -0
- /package/dist/{types/common → common}/errors/parameter.d.ts +0 -0
- /package/dist/{types/common → common}/errors/password-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/permission.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reclaim-host-role-errors.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection-in-progress.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection.d.ts +0 -0
- /package/dist/{types/common → common}/errors/stats.d.ts +0 -0
- /package/dist/{types/common → common}/errors/webex-errors.d.ts +0 -0
- /package/dist/{types/common → common}/errors/webex-meetings-error.d.ts +0 -0
- /package/dist/{types/common → common}/events/events-scope.d.ts +0 -0
- /package/dist/{types/common → common}/events/events.d.ts +0 -0
- /package/dist/{types/common → common}/events/trigger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/events/util.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-config.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/queue.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/constants.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/enums.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/index.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/types.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/util.d.ts +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/interceptors → interceptors}/index.d.ts +0 -0
- /package/dist/{types/interceptors → interceptors}/locusRetry.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/collection.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/index.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/siLanguage.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/controlsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/embeddedAppsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/fullState.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/hostUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/index.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/infoUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/mediaSharesUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/parser.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/selfUtils.d.ts +0 -0
- /package/dist/{types/media → media}/index.d.ts +0 -0
- /package/dist/{types/media → media}/properties.d.ts +0 -0
- /package/dist/{types/media → media}/util.d.ts +0 -0
- /package/dist/{types/mediaQualityMetrics → mediaQualityMetrics}/config.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/in-meeting-actions.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/locusMediaRequest.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/muteState.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/request.type.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/state.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/collection.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/index.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/meeting-info-v2.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/request.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/util.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/utilv2.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/collection.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/meetings.types.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/request.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/util.d.ts +0 -0
- /package/dist/{types/member → member}/index.d.ts +0 -0
- /package/dist/{types/member → member}/types.d.ts +0 -0
- /package/dist/{types/member → member}/util.d.ts +0 -0
- /package/dist/{types/members → members}/collection.d.ts +0 -0
- /package/dist/{types/members → members}/index.d.ts +0 -0
- /package/dist/{types/members → members}/request.d.ts +0 -0
- /package/dist/{types/members → members}/types.d.ts +0 -0
- /package/dist/{types/metrics → metrics}/constants.d.ts +0 -0
- /package/dist/{types/metrics → metrics}/index.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlot.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlotManager.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/remoteMedia.d.ts +0 -0
- /package/dist/{types/networkQualityMonitor → networkQualityMonitor}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/request.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/util.d.ts +0 -0
- /package/dist/{types/reachability → reachability}/request.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/constants.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.type.d.ts +0 -0
- /package/dist/{types/reconnection-manager → reconnection-manager}/index.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/enums.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/index.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/util.d.ts +0 -0
- /package/dist/{types/roap → roap}/request.d.ts +0 -0
- /package/dist/{types/rtcMetrics → rtcMetrics}/constants.d.ts +0 -0
- /package/dist/{types/rtcMetrics → rtcMetrics}/index.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/global.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/index.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/mqaUtil.d.ts +0 -0
- /package/dist/{types/transcription → transcription}/index.d.ts +0 -0
- /package/dist/{types/webinar → webinar}/collection.d.ts +0 -0
- /package/dist/{types/webinar → webinar}/index.d.ts +0 -0
package/src/meeting/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
2
|
import {cloneDeep, isEqual, isEmpty} from 'lodash';
|
|
3
|
-
import
|
|
3
|
+
import jwtDecode from 'jwt-decode';
|
|
4
4
|
// @ts-ignore - Fix this
|
|
5
5
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
6
6
|
// @ts-ignore - Types not available for @webex/common
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
ClientEventLeaveReason,
|
|
11
11
|
CallDiagnosticUtils,
|
|
12
12
|
} from '@webex/internal-plugin-metrics';
|
|
13
|
+
import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
14
|
+
|
|
13
15
|
import {
|
|
14
16
|
ConnectionState,
|
|
15
17
|
Errors,
|
|
@@ -33,6 +35,12 @@ import {
|
|
|
33
35
|
RemoteStream,
|
|
34
36
|
} from '@webex/media-helpers';
|
|
35
37
|
|
|
38
|
+
import {
|
|
39
|
+
EVENT_TRIGGERS as VOICEAEVENTS,
|
|
40
|
+
TURN_ON_CAPTION_STATUS,
|
|
41
|
+
} from '@webex/internal-plugin-voicea';
|
|
42
|
+
import {processNewCaptions} from './voicea-meeting';
|
|
43
|
+
|
|
36
44
|
import {
|
|
37
45
|
MeetingNotActiveError,
|
|
38
46
|
UserInLobbyError,
|
|
@@ -40,11 +48,17 @@ import {
|
|
|
40
48
|
UserNotJoinedError,
|
|
41
49
|
AddMediaFailed,
|
|
42
50
|
} from '../common/errors/webex-errors';
|
|
51
|
+
|
|
43
52
|
import {StatsAnalyzer, EVENTS as StatsAnalyzerEvents} from '../statsAnalyzer';
|
|
44
53
|
import NetworkQualityMonitor from '../networkQualityMonitor';
|
|
45
54
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
55
|
+
import EventsUtil from '../common/events/util';
|
|
46
56
|
import Trigger from '../common/events/trigger-proxy';
|
|
47
|
-
import Roap
|
|
57
|
+
import Roap, {
|
|
58
|
+
type TurnDiscoveryResult,
|
|
59
|
+
type TurnServerInfo,
|
|
60
|
+
type TurnDiscoverySkipReason,
|
|
61
|
+
} from '../roap/index';
|
|
48
62
|
import Media, {type BundlePolicy} from '../media';
|
|
49
63
|
import MediaProperties from '../media/properties';
|
|
50
64
|
import MeetingStateMachine from './state';
|
|
@@ -59,7 +73,6 @@ import MeetingsUtil from '../meetings/util';
|
|
|
59
73
|
import RecordingUtil from '../recording-controller/util';
|
|
60
74
|
import ControlsOptionsUtil from '../controls-options-manager/util';
|
|
61
75
|
import MediaUtil from '../media/util';
|
|
62
|
-
import Transcription from '../transcription';
|
|
63
76
|
import {Reactions, SkinTones} from '../reactions/reactions';
|
|
64
77
|
import PasswordError from '../common/errors/password-error';
|
|
65
78
|
import CaptchaError from '../common/errors/captcha-error';
|
|
@@ -97,7 +110,6 @@ import {
|
|
|
97
110
|
SHARE_STATUS,
|
|
98
111
|
SHARE_STOPPED_REASON,
|
|
99
112
|
VIDEO,
|
|
100
|
-
HTTP_VERBS,
|
|
101
113
|
SELF_ROLES,
|
|
102
114
|
INTERPRETATION,
|
|
103
115
|
SELF_POLICY,
|
|
@@ -106,6 +118,7 @@ import {
|
|
|
106
118
|
ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT,
|
|
107
119
|
RECONNECTION,
|
|
108
120
|
NAMED_MEDIA_GROUP_TYPE_AUDIO,
|
|
121
|
+
LANGUAGE_ENGLISH,
|
|
109
122
|
} from '../constants';
|
|
110
123
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
111
124
|
import ParameterError from '../common/errors/parameter';
|
|
@@ -114,7 +127,6 @@ import {
|
|
|
114
127
|
MeetingInfoV2CaptchaError,
|
|
115
128
|
MeetingInfoV2PolicyError,
|
|
116
129
|
} from '../meeting-info/meeting-info-v2';
|
|
117
|
-
import BrowserDetection from '../common/browser-detection';
|
|
118
130
|
import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
|
|
119
131
|
import SendSlotManager from '../multistream/sendSlotManager';
|
|
120
132
|
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
@@ -142,8 +154,6 @@ import ControlsOptionsManager from '../controls-options-manager';
|
|
|
142
154
|
import PermissionError from '../common/errors/permission';
|
|
143
155
|
import {LocusMediaRequest} from './locusMediaRequest';
|
|
144
156
|
|
|
145
|
-
const {isBrowser} = BrowserDetection();
|
|
146
|
-
|
|
147
157
|
const logRequest = (request: any, {logText = ''}) => {
|
|
148
158
|
LoggerProxy.logger.info(`${logText} - sending request`);
|
|
149
159
|
|
|
@@ -159,6 +169,36 @@ const logRequest = (request: any, {logText = ''}) => {
|
|
|
159
169
|
});
|
|
160
170
|
};
|
|
161
171
|
|
|
172
|
+
export type CaptionData = {
|
|
173
|
+
id: string;
|
|
174
|
+
isFinal: boolean;
|
|
175
|
+
translations: Array<string>;
|
|
176
|
+
text: string;
|
|
177
|
+
currentCaptionLanguage: string;
|
|
178
|
+
timestamp: string;
|
|
179
|
+
speaker: string;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export type Transcription = {
|
|
183
|
+
languageOptions: {
|
|
184
|
+
captionLanguages?: string; // list of supported caption languages from backend
|
|
185
|
+
maxLanguages?: number;
|
|
186
|
+
spokenLanguages?: Array<string>; // list of supported spoken languages from backend
|
|
187
|
+
currentCaptionLanguage?: string; // current caption language - default is english
|
|
188
|
+
requestedCaptionLanguage?: string; // requested caption language
|
|
189
|
+
currentSpokenLanguage?: string; // current spoken language - default is english
|
|
190
|
+
};
|
|
191
|
+
status: string;
|
|
192
|
+
isListening: boolean;
|
|
193
|
+
commandText: string;
|
|
194
|
+
captions: Array<CaptionData>;
|
|
195
|
+
showCaptionBox: boolean;
|
|
196
|
+
transcribingRequestStatus: string;
|
|
197
|
+
isCaptioning: boolean;
|
|
198
|
+
speakerProxy: Map<string, any>;
|
|
199
|
+
interimCaptions: Map<string, CaptionData>;
|
|
200
|
+
};
|
|
201
|
+
|
|
162
202
|
export type LocalStreams = {
|
|
163
203
|
microphone?: LocalMicrophoneStream;
|
|
164
204
|
camera?: LocalCameraStream;
|
|
@@ -588,8 +628,51 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
588
628
|
allowMediaInLobby: boolean;
|
|
589
629
|
localShareInstanceId: string;
|
|
590
630
|
remoteShareInstanceId: string;
|
|
591
|
-
turnDiscoverySkippedReason:
|
|
631
|
+
turnDiscoverySkippedReason: TurnDiscoverySkipReason;
|
|
592
632
|
turnServerUsed: boolean;
|
|
633
|
+
areVoiceaEventsSetup = false;
|
|
634
|
+
|
|
635
|
+
voiceaListenerCallbacks: object = {
|
|
636
|
+
[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]: (payload: Transcription['languageOptions']) => {
|
|
637
|
+
this.transcription.languageOptions = payload;
|
|
638
|
+
|
|
639
|
+
LoggerProxy.logger.debug(
|
|
640
|
+
`${EventsUtil.getScopeLog({
|
|
641
|
+
file: 'meeting/index',
|
|
642
|
+
function: 'setUpVoiceaListeners',
|
|
643
|
+
})}event#${EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION}`
|
|
644
|
+
);
|
|
645
|
+
|
|
646
|
+
// @ts-ignore
|
|
647
|
+
this.trigger(EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION, payload);
|
|
648
|
+
},
|
|
649
|
+
[VOICEAEVENTS.CAPTIONS_TURNED_ON]: () => {
|
|
650
|
+
this.transcription.status = TURN_ON_CAPTION_STATUS.ENABLED;
|
|
651
|
+
},
|
|
652
|
+
[VOICEAEVENTS.EVA_COMMAND]: (payload) => {
|
|
653
|
+
const {data} = payload;
|
|
654
|
+
|
|
655
|
+
this.transcription.isListening = !!data.isListening;
|
|
656
|
+
this.transcription.commandText = data.text ?? '';
|
|
657
|
+
},
|
|
658
|
+
[VOICEAEVENTS.NEW_CAPTION]: (data) => {
|
|
659
|
+
processNewCaptions({data, meeting: this});
|
|
660
|
+
|
|
661
|
+
LoggerProxy.logger.debug(
|
|
662
|
+
`${EventsUtil.getScopeLog({
|
|
663
|
+
file: 'meeting/index',
|
|
664
|
+
function: 'setUpVoiceaListeners',
|
|
665
|
+
})}event#${EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED}`
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
// @ts-ignore
|
|
669
|
+
this.trigger(EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED, {
|
|
670
|
+
captions: this.transcription.captions,
|
|
671
|
+
interimCaptions: this.transcription.interimCaptions,
|
|
672
|
+
});
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
|
|
593
676
|
private retriedWithTurnServer: boolean;
|
|
594
677
|
private sendSlotManager: SendSlotManager = new SendSlotManager(LoggerProxy);
|
|
595
678
|
private deferSDPAnswer?: Defer; // used for waiting for a response
|
|
@@ -1188,7 +1271,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1188
1271
|
* @private
|
|
1189
1272
|
* @memberof Meeting
|
|
1190
1273
|
*/
|
|
1191
|
-
this.transcription =
|
|
1274
|
+
this.transcription = {
|
|
1275
|
+
captions: [],
|
|
1276
|
+
isListening: false,
|
|
1277
|
+
commandText: '',
|
|
1278
|
+
languageOptions: {},
|
|
1279
|
+
showCaptionBox: false,
|
|
1280
|
+
transcribingRequestStatus: 'INACTIVE',
|
|
1281
|
+
isCaptioning: false,
|
|
1282
|
+
interimCaptions: {} as Map<string, CaptionData>,
|
|
1283
|
+
speakerProxy: {} as Map<string, any>,
|
|
1284
|
+
} as Transcription;
|
|
1192
1285
|
|
|
1193
1286
|
/**
|
|
1194
1287
|
* Password status. If it's PASSWORD_STATUS.REQUIRED then verifyPassword() needs to be called
|
|
@@ -1904,6 +1997,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1904
1997
|
* @memberof Meeting
|
|
1905
1998
|
*/
|
|
1906
1999
|
private setUpInterpretationListener() {
|
|
2000
|
+
// TODO: check if its getting used or not
|
|
1907
2001
|
this.simultaneousInterpretation.on(INTERPRETATION.EVENTS.SUPPORT_LANGUAGES_UPDATE, () => {
|
|
1908
2002
|
Trigger.trigger(
|
|
1909
2003
|
this,
|
|
@@ -1914,7 +2008,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1914
2008
|
EVENT_TRIGGERS.MEETING_INTERPRETATION_SUPPORT_LANGUAGES_UPDATE
|
|
1915
2009
|
);
|
|
1916
2010
|
});
|
|
1917
|
-
|
|
2011
|
+
// TODO: check if its getting used or not
|
|
1918
2012
|
this.simultaneousInterpretation.on(
|
|
1919
2013
|
INTERPRETATION.EVENTS.HANDOFF_REQUESTS_ARRIVED,
|
|
1920
2014
|
(payload) => {
|
|
@@ -1931,6 +2025,43 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1931
2025
|
);
|
|
1932
2026
|
}
|
|
1933
2027
|
|
|
2028
|
+
/**
|
|
2029
|
+
* Set up the listeners for captions
|
|
2030
|
+
* @returns {undefined}
|
|
2031
|
+
* @private
|
|
2032
|
+
* @memberof Meeting
|
|
2033
|
+
*/
|
|
2034
|
+
private setUpVoiceaListeners() {
|
|
2035
|
+
// @ts-ignore
|
|
2036
|
+
this.webex.internal.voicea.listenToEvents();
|
|
2037
|
+
|
|
2038
|
+
// @ts-ignore
|
|
2039
|
+
this.webex.internal.voicea.on(
|
|
2040
|
+
VOICEAEVENTS.VOICEA_ANNOUNCEMENT,
|
|
2041
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]
|
|
2042
|
+
);
|
|
2043
|
+
|
|
2044
|
+
// @ts-ignore
|
|
2045
|
+
this.webex.internal.voicea.on(
|
|
2046
|
+
VOICEAEVENTS.CAPTIONS_TURNED_ON,
|
|
2047
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.CAPTIONS_TURNED_ON]
|
|
2048
|
+
);
|
|
2049
|
+
|
|
2050
|
+
// @ts-ignore
|
|
2051
|
+
this.webex.internal.voicea.on(
|
|
2052
|
+
VOICEAEVENTS.EVA_COMMAND,
|
|
2053
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.EVA_COMMAND]
|
|
2054
|
+
);
|
|
2055
|
+
|
|
2056
|
+
// @ts-ignore
|
|
2057
|
+
this.webex.internal.voicea.on(
|
|
2058
|
+
VOICEAEVENTS.NEW_CAPTION,
|
|
2059
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]
|
|
2060
|
+
);
|
|
2061
|
+
|
|
2062
|
+
this.areVoiceaEventsSetup = true;
|
|
2063
|
+
}
|
|
2064
|
+
|
|
1934
2065
|
/**
|
|
1935
2066
|
* Set up the locus info listener for meetings disconnected due to inactivity
|
|
1936
2067
|
* @returns {undefined}
|
|
@@ -2220,7 +2351,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2220
2351
|
modifiedBy,
|
|
2221
2352
|
lastModified,
|
|
2222
2353
|
};
|
|
2223
|
-
|
|
2224
2354
|
Trigger.trigger(
|
|
2225
2355
|
this,
|
|
2226
2356
|
{
|
|
@@ -2251,19 +2381,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2251
2381
|
this.locusInfo.on(
|
|
2252
2382
|
LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
|
|
2253
2383
|
({caption, transcribing}) => {
|
|
2254
|
-
//
|
|
2255
|
-
if (
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2384
|
+
// user need to be joined to start the llm and receive transcription
|
|
2385
|
+
if (this.isJoined()) {
|
|
2386
|
+
// @ts-ignore - config coming from registerPlugin
|
|
2387
|
+
if (transcribing && !this.transcription) {
|
|
2388
|
+
this.startTranscription();
|
|
2389
|
+
} else if (!transcribing && this.transcription) {
|
|
2390
|
+
Trigger.trigger(
|
|
2391
|
+
this,
|
|
2392
|
+
{
|
|
2393
|
+
file: 'meeting/index',
|
|
2394
|
+
function: 'setupLocusControlsListener',
|
|
2395
|
+
},
|
|
2396
|
+
EVENT_TRIGGERS.MEETING_STOPPED_RECEIVING_TRANSCRIPTION,
|
|
2397
|
+
{caption, transcribing}
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2267
2400
|
}
|
|
2268
2401
|
}
|
|
2269
2402
|
);
|
|
@@ -2393,6 +2526,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2393
2526
|
{
|
|
2394
2527
|
annotationInfo: contentShare?.annotation,
|
|
2395
2528
|
meetingId: this.id,
|
|
2529
|
+
resourceType: contentShare?.resourceType,
|
|
2396
2530
|
}
|
|
2397
2531
|
);
|
|
2398
2532
|
}
|
|
@@ -2421,7 +2555,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2421
2555
|
contentShare.deviceUrlSharing === previousContentShare.deviceUrlSharing &&
|
|
2422
2556
|
whiteboardShare.beneficiaryId === previousWhiteboardShare?.beneficiaryId &&
|
|
2423
2557
|
whiteboardShare.disposition === previousWhiteboardShare?.disposition &&
|
|
2424
|
-
whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl
|
|
2558
|
+
whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl &&
|
|
2559
|
+
contentShare.resourceType === previousContentShare?.resourceType
|
|
2425
2560
|
) {
|
|
2426
2561
|
// nothing changed, so ignore
|
|
2427
2562
|
// (this happens when we steal presentation from remote)
|
|
@@ -2543,6 +2678,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2543
2678
|
url: contentShare.url,
|
|
2544
2679
|
shareInstanceId: this.remoteShareInstanceId,
|
|
2545
2680
|
annotationInfo: contentShare.annotation,
|
|
2681
|
+
resourceType: contentShare.resourceType,
|
|
2546
2682
|
}
|
|
2547
2683
|
);
|
|
2548
2684
|
};
|
|
@@ -2635,6 +2771,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2635
2771
|
url: contentShare.url,
|
|
2636
2772
|
shareInstanceId: this.remoteShareInstanceId,
|
|
2637
2773
|
annotationInfo: contentShare.annotation,
|
|
2774
|
+
resourceType: contentShare.resourceType,
|
|
2638
2775
|
}
|
|
2639
2776
|
);
|
|
2640
2777
|
this.members.locusMediaSharesUpdate(payload);
|
|
@@ -2922,7 +3059,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2922
3059
|
});
|
|
2923
3060
|
}
|
|
2924
3061
|
});
|
|
2925
|
-
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, (payload) => {
|
|
3062
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, async (payload) => {
|
|
2926
3063
|
this.stopKeepAlive();
|
|
2927
3064
|
|
|
2928
3065
|
if (payload) {
|
|
@@ -2944,6 +3081,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2944
3081
|
options: {meetingId: this.id},
|
|
2945
3082
|
});
|
|
2946
3083
|
}
|
|
3084
|
+
this.updateLLMConnection();
|
|
2947
3085
|
});
|
|
2948
3086
|
|
|
2949
3087
|
// @ts-ignore - check if MEDIA_INACTIVITY exists
|
|
@@ -3328,8 +3466,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3328
3466
|
this.owner =
|
|
3329
3467
|
locusMeetingObject?.info.owner || meetingInfo?.owner || meetingInfo?.hostId || this.owner;
|
|
3330
3468
|
this.permissionToken = meetingInfo?.permissionToken;
|
|
3331
|
-
this.
|
|
3332
|
-
|
|
3469
|
+
if (this.permissionToken) {
|
|
3470
|
+
this.setPermissionTokenPayload(meetingInfo?.permissionToken);
|
|
3471
|
+
this.setSelfUserPolicies();
|
|
3472
|
+
}
|
|
3333
3473
|
// Need to populate environment when sending CA event
|
|
3334
3474
|
this.environment = locusMeetingObject?.info.channel || meetingInfo?.channel;
|
|
3335
3475
|
}
|
|
@@ -3616,7 +3756,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3616
3756
|
* @returns {void}
|
|
3617
3757
|
*/
|
|
3618
3758
|
public setPermissionTokenPayload(permissionToken: string) {
|
|
3619
|
-
this.permissionTokenPayload =
|
|
3759
|
+
this.permissionTokenPayload = jwtDecode(permissionToken);
|
|
3620
3760
|
this.permissionTokenReceivedLocalTime = new Date().getTime();
|
|
3621
3761
|
}
|
|
3622
3762
|
|
|
@@ -4365,47 +4505,90 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4365
4505
|
* }
|
|
4366
4506
|
* })
|
|
4367
4507
|
*/
|
|
4368
|
-
public joinWithMedia(
|
|
4508
|
+
public async joinWithMedia(
|
|
4369
4509
|
options: {
|
|
4370
4510
|
joinOptions?: any;
|
|
4371
4511
|
mediaOptions?: AddMediaOptions;
|
|
4372
4512
|
} = {}
|
|
4373
4513
|
) {
|
|
4374
|
-
const {mediaOptions, joinOptions} = options;
|
|
4514
|
+
const {mediaOptions, joinOptions = {}} = options;
|
|
4375
4515
|
|
|
4376
4516
|
if (!mediaOptions?.allowMediaInLobby) {
|
|
4377
4517
|
return Promise.reject(
|
|
4378
4518
|
new ParameterError('joinWithMedia() can only be used with allowMediaInLobby set to true')
|
|
4379
4519
|
);
|
|
4380
4520
|
}
|
|
4521
|
+
this.allowMediaInLobby = true;
|
|
4381
4522
|
|
|
4382
4523
|
LoggerProxy.logger.info('Meeting:index#joinWithMedia called');
|
|
4383
4524
|
|
|
4384
|
-
|
|
4385
|
-
.then((joinResponse) =>
|
|
4386
|
-
this.addMedia(mediaOptions).then((mediaResponse) => ({
|
|
4387
|
-
join: joinResponse,
|
|
4388
|
-
media: mediaResponse,
|
|
4389
|
-
}))
|
|
4390
|
-
)
|
|
4391
|
-
.catch((error) => {
|
|
4392
|
-
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> ', error);
|
|
4525
|
+
let joined = false;
|
|
4393
4526
|
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
correlation_id: this.correlationId,
|
|
4398
|
-
locus_id: this.locusUrl.split('/').pop(),
|
|
4399
|
-
reason: error.message,
|
|
4400
|
-
stack: error.stack,
|
|
4401
|
-
},
|
|
4402
|
-
{
|
|
4403
|
-
type: error.name,
|
|
4404
|
-
}
|
|
4405
|
-
);
|
|
4527
|
+
try {
|
|
4528
|
+
let turnServerInfo;
|
|
4529
|
+
let turnDiscoverySkippedReason;
|
|
4406
4530
|
|
|
4407
|
-
|
|
4408
|
-
|
|
4531
|
+
// @ts-ignore
|
|
4532
|
+
joinOptions.reachability = await this.webex.meetings.reachability.getReachabilityResults();
|
|
4533
|
+
const turnDiscoveryRequest = await this.roap.generateTurnDiscoveryRequestMessage(this, true);
|
|
4534
|
+
|
|
4535
|
+
({turnDiscoverySkippedReason} = turnDiscoveryRequest);
|
|
4536
|
+
joinOptions.roapMessage = turnDiscoveryRequest.roapMessage;
|
|
4537
|
+
|
|
4538
|
+
const joinResponse = await this.join(joinOptions);
|
|
4539
|
+
|
|
4540
|
+
joined = true;
|
|
4541
|
+
|
|
4542
|
+
if (joinOptions.roapMessage) {
|
|
4543
|
+
({turnServerInfo, turnDiscoverySkippedReason} =
|
|
4544
|
+
await this.roap.handleTurnDiscoveryHttpResponse(this, joinResponse));
|
|
4545
|
+
|
|
4546
|
+
this.turnDiscoverySkippedReason = turnDiscoverySkippedReason;
|
|
4547
|
+
this.turnServerUsed = !!turnServerInfo;
|
|
4548
|
+
|
|
4549
|
+
if (turnServerInfo === undefined) {
|
|
4550
|
+
this.roap.abortTurnDiscovery();
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
|
|
4554
|
+
const mediaResponse = await this.addMedia(mediaOptions, turnServerInfo);
|
|
4555
|
+
|
|
4556
|
+
return {
|
|
4557
|
+
join: joinResponse,
|
|
4558
|
+
media: mediaResponse,
|
|
4559
|
+
};
|
|
4560
|
+
} catch (error) {
|
|
4561
|
+
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> ', error);
|
|
4562
|
+
|
|
4563
|
+
let leaveError;
|
|
4564
|
+
|
|
4565
|
+
this.roap.abortTurnDiscovery();
|
|
4566
|
+
|
|
4567
|
+
if (joined) {
|
|
4568
|
+
try {
|
|
4569
|
+
await this.leave({resourceId: joinOptions?.resourceId, reason: 'joinWithMedia failure'});
|
|
4570
|
+
} catch (e) {
|
|
4571
|
+
LoggerProxy.logger.error('Meeting:index#joinWithMedia --> leave error', e);
|
|
4572
|
+
leaveError = e;
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4576
|
+
Metrics.sendBehavioralMetric(
|
|
4577
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
4578
|
+
{
|
|
4579
|
+
correlation_id: this.correlationId,
|
|
4580
|
+
locus_id: this.locusUrl?.split('/').pop(), // if join fails, we may end up with no locusUrl
|
|
4581
|
+
reason: error.message,
|
|
4582
|
+
stack: error.stack,
|
|
4583
|
+
leaveErrorReason: leaveError?.message,
|
|
4584
|
+
},
|
|
4585
|
+
{
|
|
4586
|
+
type: error.name,
|
|
4587
|
+
}
|
|
4588
|
+
);
|
|
4589
|
+
|
|
4590
|
+
throw error;
|
|
4591
|
+
}
|
|
4409
4592
|
}
|
|
4410
4593
|
|
|
4411
4594
|
/**
|
|
@@ -4532,7 +4715,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4532
4715
|
}
|
|
4533
4716
|
|
|
4534
4717
|
LoggerProxy.logger.error(
|
|
4535
|
-
'Meeting:index#isTranscriptionSupported --> Webex Assistant is not supported'
|
|
4718
|
+
'Meeting:index#isTranscriptionSupported --> Webex Assistant is not enabled/supported'
|
|
4536
4719
|
);
|
|
4537
4720
|
|
|
4538
4721
|
return false;
|
|
@@ -4553,109 +4736,139 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4553
4736
|
}
|
|
4554
4737
|
|
|
4555
4738
|
/**
|
|
4556
|
-
*
|
|
4557
|
-
* @
|
|
4558
|
-
* @returns {
|
|
4739
|
+
* sets Caption language for the meeting
|
|
4740
|
+
* @param {string} language
|
|
4741
|
+
* @returns {Promise}
|
|
4559
4742
|
*/
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
${event}`
|
|
4567
|
-
);
|
|
4743
|
+
public setCaptionLanguage(language: string) {
|
|
4744
|
+
return new Promise((resolve, reject) => {
|
|
4745
|
+
if (!this.isTranscriptionSupported()) {
|
|
4746
|
+
LoggerProxy.logger.error(
|
|
4747
|
+
'Meeting:index#setCaptionLanguage --> Webex Assistant is not enabled/supported'
|
|
4748
|
+
);
|
|
4568
4749
|
|
|
4569
|
-
|
|
4570
|
-
|
|
4750
|
+
reject(new Error('Webex Assistant is not enabled/supported'));
|
|
4751
|
+
}
|
|
4571
4752
|
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4753
|
+
try {
|
|
4754
|
+
const voiceaListenerCaptionUpdate = (payload) => {
|
|
4755
|
+
// @ts-ignore
|
|
4756
|
+
this.webex.internal.voicea.off(
|
|
4757
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE,
|
|
4758
|
+
voiceaListenerCaptionUpdate
|
|
4759
|
+
);
|
|
4760
|
+
const {statusCode} = payload;
|
|
4579
4761
|
|
|
4580
|
-
|
|
4762
|
+
if (statusCode === 200) {
|
|
4763
|
+
this.transcription.languageOptions = {
|
|
4764
|
+
...this.transcription.languageOptions,
|
|
4765
|
+
currentCaptionLanguage: language,
|
|
4766
|
+
};
|
|
4767
|
+
resolve(language);
|
|
4768
|
+
} else {
|
|
4769
|
+
reject(payload);
|
|
4770
|
+
}
|
|
4771
|
+
};
|
|
4772
|
+
// @ts-ignore
|
|
4773
|
+
this.webex.internal.voicea.on(
|
|
4774
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE,
|
|
4775
|
+
voiceaListenerCaptionUpdate
|
|
4776
|
+
);
|
|
4777
|
+
// @ts-ignore
|
|
4778
|
+
this.webex.internal.voicea.requestLanguage(language);
|
|
4779
|
+
} catch (error) {
|
|
4780
|
+
LoggerProxy.logger.error(`Meeting:index#setCaptionLanguage --> ${error}`);
|
|
4581
4781
|
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
reason: 'unexpected error: transcription LLM web socket connection error had occured.',
|
|
4585
|
-
event,
|
|
4586
|
-
});
|
|
4782
|
+
reject(error);
|
|
4783
|
+
}
|
|
4587
4784
|
});
|
|
4588
4785
|
}
|
|
4589
4786
|
|
|
4590
4787
|
/**
|
|
4591
|
-
*
|
|
4592
|
-
* @
|
|
4593
|
-
* @returns {Promise
|
|
4788
|
+
* sets Spoken language for the meeting
|
|
4789
|
+
* @param {string} language
|
|
4790
|
+
* @returns {Promise}
|
|
4594
4791
|
*/
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4792
|
+
public setSpokenLanguage(language: string) {
|
|
4793
|
+
return new Promise((resolve, reject) => {
|
|
4794
|
+
if (!this.isTranscriptionSupported()) {
|
|
4795
|
+
LoggerProxy.logger.error(
|
|
4796
|
+
'Meeting:index#setCaptionLanguage --> Webex Assistant is not enabled/supported'
|
|
4797
|
+
);
|
|
4798
|
+
|
|
4799
|
+
reject(new Error('Webex Assistant is not enabled/supported'));
|
|
4800
|
+
}
|
|
4801
|
+
|
|
4802
|
+
try {
|
|
4803
|
+
const voiceaListenerLanguageUpdate = (payload) => {
|
|
4804
|
+
// @ts-ignore
|
|
4805
|
+
this.webex.internal.voicea.off(
|
|
4806
|
+
VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE,
|
|
4807
|
+
voiceaListenerLanguageUpdate
|
|
4808
|
+
);
|
|
4809
|
+
const {languageCode} = payload;
|
|
4810
|
+
|
|
4811
|
+
if (languageCode) {
|
|
4812
|
+
this.transcription.languageOptions = {
|
|
4813
|
+
...this.transcription.languageOptions,
|
|
4814
|
+
currentSpokenLanguage: languageCode,
|
|
4815
|
+
};
|
|
4816
|
+
resolve(languageCode);
|
|
4817
|
+
} else {
|
|
4818
|
+
reject(payload);
|
|
4819
|
+
}
|
|
4820
|
+
};
|
|
4600
4821
|
|
|
4601
|
-
try {
|
|
4602
|
-
const {datachannelUrl} = this.locusInfo.info;
|
|
4603
|
-
// @ts-ignore - fix type
|
|
4604
|
-
const {
|
|
4605
|
-
body: {webSocketUrl},
|
|
4606
4822
|
// @ts-ignore
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
});
|
|
4823
|
+
this.webex.internal.voicea.on(
|
|
4824
|
+
VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE,
|
|
4825
|
+
voiceaListenerLanguageUpdate
|
|
4826
|
+
);
|
|
4612
4827
|
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4828
|
+
// @ts-ignore
|
|
4829
|
+
this.webex.internal.voicea.setSpokenLanguage(language);
|
|
4830
|
+
} catch (error) {
|
|
4831
|
+
LoggerProxy.logger.error(`Meeting:index#setSpokenLanguage --> ${error}`);
|
|
4617
4832
|
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
this.members
|
|
4623
|
-
);
|
|
4833
|
+
reject(error);
|
|
4834
|
+
}
|
|
4835
|
+
});
|
|
4836
|
+
}
|
|
4624
4837
|
|
|
4838
|
+
/**
|
|
4839
|
+
* This method will enable the transcription for the current meeting if the meeting has enabled/supports Webex Assistant
|
|
4840
|
+
* @param {Object} options object with spokenlanguage setting
|
|
4841
|
+
* @public
|
|
4842
|
+
* @returns {Promise<void>} a promise to open the WebSocket connection
|
|
4843
|
+
*/
|
|
4844
|
+
public async startTranscription(options?: {spokenLanguage?: string}) {
|
|
4845
|
+
if (this.isJoined()) {
|
|
4625
4846
|
LoggerProxy.logger.info(
|
|
4626
|
-
|
|
4627
|
-
opened LLM web socket connection successfully.`
|
|
4847
|
+
'Meeting:index#startTranscription --> Attempting to enable transcription!'
|
|
4628
4848
|
);
|
|
4629
4849
|
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
}
|
|
4635
|
-
|
|
4636
|
-
// retrieve and pass the payload
|
|
4637
|
-
this.transcription.subscribe((payload) => {
|
|
4638
|
-
Trigger.trigger(
|
|
4639
|
-
this,
|
|
4640
|
-
{
|
|
4641
|
-
file: 'meeting/index',
|
|
4642
|
-
function: 'join',
|
|
4643
|
-
},
|
|
4644
|
-
EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION,
|
|
4645
|
-
payload
|
|
4646
|
-
);
|
|
4647
|
-
});
|
|
4850
|
+
try {
|
|
4851
|
+
if (!this.areVoiceaEventsSetup) {
|
|
4852
|
+
this.setUpVoiceaListeners();
|
|
4853
|
+
}
|
|
4648
4854
|
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4855
|
+
if (this.getCurUserType() === 'host') {
|
|
4856
|
+
// @ts-ignore
|
|
4857
|
+
await this.webex.internal.voicea.toggleTranscribing(true, options?.spokenLanguage);
|
|
4858
|
+
}
|
|
4859
|
+
} catch (error) {
|
|
4860
|
+
LoggerProxy.logger.error(`Meeting:index#startTranscription --> ${error}`);
|
|
4861
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE, {
|
|
4862
|
+
correlation_id: this.correlationId,
|
|
4863
|
+
reason: error.message,
|
|
4864
|
+
stack: error.stack,
|
|
4865
|
+
});
|
|
4866
|
+
}
|
|
4867
|
+
} else {
|
|
4868
|
+
LoggerProxy.logger.error(
|
|
4869
|
+
`Meeting:index#startTranscription --> meeting joined : ${this.isJoined()}`
|
|
4870
|
+
);
|
|
4871
|
+
throw new Error('Meeting is not joined');
|
|
4659
4872
|
}
|
|
4660
4873
|
}
|
|
4661
4874
|
|
|
@@ -4698,13 +4911,37 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4698
4911
|
};
|
|
4699
4912
|
|
|
4700
4913
|
/**
|
|
4701
|
-
*
|
|
4702
|
-
* the web socket connection properly
|
|
4914
|
+
* This method stops receiving transcription for the current meeting
|
|
4703
4915
|
* @returns {void}
|
|
4704
4916
|
*/
|
|
4705
|
-
|
|
4917
|
+
stopTranscription() {
|
|
4706
4918
|
if (this.transcription) {
|
|
4707
|
-
|
|
4919
|
+
// @ts-ignore
|
|
4920
|
+
this.webex.internal.voicea.off(
|
|
4921
|
+
VOICEAEVENTS.VOICEA_ANNOUNCEMENT,
|
|
4922
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]
|
|
4923
|
+
);
|
|
4924
|
+
|
|
4925
|
+
// @ts-ignore
|
|
4926
|
+
this.webex.internal.voicea.off(
|
|
4927
|
+
VOICEAEVENTS.CAPTIONS_TURNED_ON,
|
|
4928
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.CAPTIONS_TURNED_ON]
|
|
4929
|
+
);
|
|
4930
|
+
|
|
4931
|
+
// @ts-ignore
|
|
4932
|
+
this.webex.internal.voicea.off(
|
|
4933
|
+
VOICEAEVENTS.EVA_COMMAND,
|
|
4934
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.EVA_COMMAND]
|
|
4935
|
+
);
|
|
4936
|
+
|
|
4937
|
+
// @ts-ignore
|
|
4938
|
+
this.webex.internal.voicea.off(
|
|
4939
|
+
VOICEAEVENTS.NEW_CAPTION,
|
|
4940
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]
|
|
4941
|
+
);
|
|
4942
|
+
|
|
4943
|
+
this.areVoiceaEventsSetup = false;
|
|
4944
|
+
this.triggerStopReceivingTranscriptionEvent();
|
|
4708
4945
|
}
|
|
4709
4946
|
}
|
|
4710
4947
|
|
|
@@ -4717,12 +4954,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4717
4954
|
private triggerStopReceivingTranscriptionEvent() {
|
|
4718
4955
|
LoggerProxy.logger.info(`
|
|
4719
4956
|
Meeting:index#stopReceivingTranscription -->
|
|
4720
|
-
closed
|
|
4957
|
+
closed voicea event listeners successfully.`);
|
|
4721
4958
|
|
|
4722
4959
|
Trigger.trigger(
|
|
4723
4960
|
this,
|
|
4724
4961
|
{
|
|
4725
|
-
file: 'meeting',
|
|
4962
|
+
file: 'meeting/index',
|
|
4726
4963
|
function: 'triggerStopReceivingTranscriptionEvent',
|
|
4727
4964
|
},
|
|
4728
4965
|
EVENT_TRIGGERS.MEETING_STOPPED_RECEIVING_TRANSCRIPTION
|
|
@@ -4948,48 +5185,33 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4948
5185
|
.then((join) => {
|
|
4949
5186
|
// @ts-ignore - config coming from registerPlugin
|
|
4950
5187
|
if (this.config.enableAutomaticLLM) {
|
|
4951
|
-
this.updateLLMConnection()
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
stack: error.stack,
|
|
4958
|
-
});
|
|
4959
|
-
});
|
|
4960
|
-
}
|
|
5188
|
+
this.updateLLMConnection()
|
|
5189
|
+
.catch((error) => {
|
|
5190
|
+
LoggerProxy.logger.error(
|
|
5191
|
+
'Meeting:index#join --> Transcription Socket Connection Failed',
|
|
5192
|
+
error
|
|
5193
|
+
);
|
|
4961
5194
|
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
5195
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LLM_CONNECTION_AFTER_JOIN_FAILURE, {
|
|
5196
|
+
correlation_id: this.correlationId,
|
|
5197
|
+
reason: error?.message,
|
|
5198
|
+
stack: error.stack,
|
|
5199
|
+
});
|
|
5200
|
+
})
|
|
5201
|
+
.then(() => {
|
|
4969
5202
|
LoggerProxy.logger.info(
|
|
4970
|
-
'Meeting:index#join -->
|
|
5203
|
+
'Meeting:index#join --> Transcription Socket Connection Success'
|
|
4971
5204
|
);
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
reason: error?.message,
|
|
4983
|
-
stack: error.stack,
|
|
4984
|
-
}
|
|
4985
|
-
);
|
|
4986
|
-
});
|
|
4987
|
-
}
|
|
4988
|
-
}
|
|
4989
|
-
} else {
|
|
4990
|
-
LoggerProxy.logger.error(
|
|
4991
|
-
'Meeting:index#join --> Receving transcription is not supported on this platform'
|
|
4992
|
-
);
|
|
5205
|
+
Trigger.trigger(
|
|
5206
|
+
this,
|
|
5207
|
+
{
|
|
5208
|
+
file: 'meeting/index',
|
|
5209
|
+
function: 'join',
|
|
5210
|
+
},
|
|
5211
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED,
|
|
5212
|
+
undefined
|
|
5213
|
+
);
|
|
5214
|
+
});
|
|
4993
5215
|
}
|
|
4994
5216
|
|
|
4995
5217
|
return join;
|
|
@@ -5489,7 +5711,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5489
5711
|
logText: `${LOG_HEADER} Roap Offer`,
|
|
5490
5712
|
}
|
|
5491
5713
|
).catch(() => {
|
|
5492
|
-
this.deferSDPAnswer.reject();
|
|
5714
|
+
this.deferSDPAnswer.reject(new Error('failed to send ROAP SDP offer'));
|
|
5493
5715
|
clearTimeout(this.sdpResponseTimer);
|
|
5494
5716
|
this.sdpResponseTimer = undefined;
|
|
5495
5717
|
});
|
|
@@ -5836,6 +6058,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5836
6058
|
meetingId: this.id,
|
|
5837
6059
|
},
|
|
5838
6060
|
});
|
|
6061
|
+
|
|
6062
|
+
if (data.type === 'share') {
|
|
6063
|
+
// @ts-ignore
|
|
6064
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
6065
|
+
name: 'client.media.render.start',
|
|
6066
|
+
payload: {
|
|
6067
|
+
mediaType: 'share',
|
|
6068
|
+
shareInstanceId: this.remoteShareInstanceId,
|
|
6069
|
+
},
|
|
6070
|
+
options: {
|
|
6071
|
+
meetingId: this.id,
|
|
6072
|
+
},
|
|
6073
|
+
});
|
|
6074
|
+
}
|
|
5839
6075
|
});
|
|
5840
6076
|
this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STOPPED, (data) => {
|
|
5841
6077
|
// @ts-ignore
|
|
@@ -5849,6 +6085,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5849
6085
|
meetingId: this.id,
|
|
5850
6086
|
},
|
|
5851
6087
|
});
|
|
6088
|
+
|
|
6089
|
+
if (data.type === 'share') {
|
|
6090
|
+
// @ts-ignore
|
|
6091
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
6092
|
+
name: 'client.media.render.stop',
|
|
6093
|
+
payload: {
|
|
6094
|
+
mediaType: 'share',
|
|
6095
|
+
shareInstanceId: this.remoteShareInstanceId,
|
|
6096
|
+
},
|
|
6097
|
+
options: {
|
|
6098
|
+
meetingId: this.id,
|
|
6099
|
+
},
|
|
6100
|
+
});
|
|
6101
|
+
}
|
|
5852
6102
|
});
|
|
5853
6103
|
};
|
|
5854
6104
|
|
|
@@ -5955,16 +6205,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5955
6205
|
private async setUpLocalStreamReferences(localStreams: LocalStreams) {
|
|
5956
6206
|
const setUpStreamPromises = [];
|
|
5957
6207
|
|
|
5958
|
-
if (localStreams?.microphone) {
|
|
6208
|
+
if (localStreams?.microphone && localStreams?.microphone?.readyState !== 'ended') {
|
|
5959
6209
|
setUpStreamPromises.push(this.setLocalAudioStream(localStreams.microphone));
|
|
5960
6210
|
}
|
|
5961
|
-
if (localStreams?.camera) {
|
|
6211
|
+
if (localStreams?.camera && localStreams?.camera?.readyState !== 'ended') {
|
|
5962
6212
|
setUpStreamPromises.push(this.setLocalVideoStream(localStreams.camera));
|
|
5963
6213
|
}
|
|
5964
|
-
if (
|
|
6214
|
+
if (
|
|
6215
|
+
localStreams?.screenShare?.video &&
|
|
6216
|
+
localStreams?.screenShare?.video?.readyState !== 'ended'
|
|
6217
|
+
) {
|
|
5965
6218
|
setUpStreamPromises.push(this.setLocalShareVideoStream(localStreams.screenShare.video));
|
|
5966
6219
|
}
|
|
5967
|
-
if (
|
|
6220
|
+
if (
|
|
6221
|
+
localStreams?.screenShare?.audio &&
|
|
6222
|
+
localStreams?.screenShare?.audio?.readyState !== 'ended'
|
|
6223
|
+
) {
|
|
5968
6224
|
setUpStreamPromises.push(this.setLocalShareAudioStream(localStreams.screenShare.audio));
|
|
5969
6225
|
}
|
|
5970
6226
|
|
|
@@ -6209,6 +6465,44 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6209
6465
|
}
|
|
6210
6466
|
}
|
|
6211
6467
|
|
|
6468
|
+
/**
|
|
6469
|
+
* Performs TURN discovery as a separate call to the Locus /media API
|
|
6470
|
+
*
|
|
6471
|
+
* @param {boolean} isRetry
|
|
6472
|
+
* @param {boolean} isForced
|
|
6473
|
+
* @returns {Promise}
|
|
6474
|
+
*/
|
|
6475
|
+
private async doTurnDiscovery(isRetry: boolean, isForced: boolean): Promise<TurnDiscoveryResult> {
|
|
6476
|
+
// @ts-ignore
|
|
6477
|
+
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
6478
|
+
|
|
6479
|
+
// @ts-ignore
|
|
6480
|
+
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6481
|
+
name: 'internal.client.add-media.turn-discovery.start',
|
|
6482
|
+
});
|
|
6483
|
+
|
|
6484
|
+
const turnDiscoveryResult = await this.roap.doTurnDiscovery(this, isRetry, isForced);
|
|
6485
|
+
|
|
6486
|
+
this.turnDiscoverySkippedReason = turnDiscoveryResult?.turnDiscoverySkippedReason;
|
|
6487
|
+
this.turnServerUsed = !this.turnDiscoverySkippedReason;
|
|
6488
|
+
|
|
6489
|
+
// @ts-ignore
|
|
6490
|
+
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6491
|
+
name: 'internal.client.add-media.turn-discovery.end',
|
|
6492
|
+
});
|
|
6493
|
+
|
|
6494
|
+
if (this.turnServerUsed && turnDiscoveryResult.turnServerInfo) {
|
|
6495
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_LATENCY, {
|
|
6496
|
+
correlation_id: this.correlationId,
|
|
6497
|
+
latency: cdl.getTurnDiscoveryTime(),
|
|
6498
|
+
turnServerUsed: this.turnServerUsed,
|
|
6499
|
+
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6500
|
+
});
|
|
6501
|
+
}
|
|
6502
|
+
|
|
6503
|
+
return turnDiscoveryResult;
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6212
6506
|
/**
|
|
6213
6507
|
* Does TURN discovery, SDP offer/answer exhange, establishes ICE connection and DTLS handshake.
|
|
6214
6508
|
*
|
|
@@ -6216,43 +6510,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6216
6510
|
* @param {RemoteMediaManagerConfiguration} [remoteMediaManagerConfig]
|
|
6217
6511
|
* @param {BundlePolicy} [bundlePolicy]
|
|
6218
6512
|
* @param {boolean} [isForced] - let isForced be true to do turn discovery regardless of reachability results
|
|
6513
|
+
* @param {TurnServerInfo} [turnServerInfo]
|
|
6219
6514
|
* @returns {Promise<void>}
|
|
6220
6515
|
*/
|
|
6221
6516
|
private async establishMediaConnection(
|
|
6222
6517
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration,
|
|
6223
6518
|
bundlePolicy?: BundlePolicy,
|
|
6224
|
-
isForced?: boolean
|
|
6519
|
+
isForced?: boolean,
|
|
6520
|
+
turnServerInfo?: TurnServerInfo
|
|
6225
6521
|
): Promise<void> {
|
|
6226
6522
|
const LOG_HEADER = 'Meeting:index#addMedia():establishMediaConnection -->';
|
|
6227
|
-
// @ts-ignore
|
|
6228
|
-
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
6229
6523
|
const isRetry = this.retriedWithTurnServer;
|
|
6230
6524
|
|
|
6231
6525
|
try {
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
name: 'internal.client.add-media.turn-discovery.start',
|
|
6235
|
-
});
|
|
6236
|
-
|
|
6237
|
-
const turnDiscoveryObject = await this.roap.doTurnDiscovery(this, isRetry, isForced);
|
|
6238
|
-
|
|
6239
|
-
this.turnDiscoverySkippedReason = turnDiscoveryObject?.turnDiscoverySkippedReason;
|
|
6240
|
-
this.turnServerUsed = !this.turnDiscoverySkippedReason;
|
|
6241
|
-
|
|
6242
|
-
// @ts-ignore
|
|
6243
|
-
this.webex.internal.newMetrics.submitInternalEvent({
|
|
6244
|
-
name: 'internal.client.add-media.turn-discovery.end',
|
|
6245
|
-
});
|
|
6246
|
-
|
|
6247
|
-
const {turnServerInfo} = turnDiscoveryObject;
|
|
6248
|
-
|
|
6249
|
-
if (this.turnServerUsed && turnServerInfo) {
|
|
6250
|
-
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_LATENCY, {
|
|
6251
|
-
correlation_id: this.correlationId,
|
|
6252
|
-
latency: cdl.getTurnDiscoveryTime(),
|
|
6253
|
-
turnServerUsed: this.turnServerUsed,
|
|
6254
|
-
retriedWithTurnServer: this.retriedWithTurnServer,
|
|
6255
|
-
});
|
|
6526
|
+
if (!turnServerInfo) {
|
|
6527
|
+
({turnServerInfo} = await this.doTurnDiscovery(isRetry, isForced));
|
|
6256
6528
|
}
|
|
6257
6529
|
|
|
6258
6530
|
const mc = await this.createMediaConnection(turnServerInfo, bundlePolicy);
|
|
@@ -6369,15 +6641,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6369
6641
|
* Creates a media connection to the server. Media connection is required for sending or receiving any audio/video.
|
|
6370
6642
|
*
|
|
6371
6643
|
* @param {AddMediaOptions} options
|
|
6644
|
+
* @param {TurnServerInfo} turnServerInfo - TURN server information (used only internally by the SDK)
|
|
6372
6645
|
* @returns {Promise<void>}
|
|
6373
6646
|
* @public
|
|
6374
6647
|
* @memberof Meeting
|
|
6375
6648
|
*/
|
|
6376
|
-
async addMedia(
|
|
6649
|
+
async addMedia(
|
|
6650
|
+
options: AddMediaOptions = {},
|
|
6651
|
+
turnServerInfo: TurnServerInfo = undefined
|
|
6652
|
+
): Promise<void> {
|
|
6377
6653
|
this.retriedWithTurnServer = false;
|
|
6378
6654
|
this.hasMediaConnectionConnectedAtLeastOnce = false;
|
|
6379
6655
|
const LOG_HEADER = 'Meeting:index#addMedia -->';
|
|
6380
|
-
LoggerProxy.logger.info(
|
|
6656
|
+
LoggerProxy.logger.info(
|
|
6657
|
+
`${LOG_HEADER} called with: ${JSON.stringify(options)}, ${JSON.stringify(turnServerInfo)}`
|
|
6658
|
+
);
|
|
6381
6659
|
|
|
6382
6660
|
if (options.allowMediaInLobby !== true && this.meetingState !== FULL_STATE.ACTIVE) {
|
|
6383
6661
|
throw new MeetingNotActiveError();
|
|
@@ -6395,14 +6673,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6395
6673
|
shareVideoEnabled = true,
|
|
6396
6674
|
remoteMediaManagerConfig,
|
|
6397
6675
|
bundlePolicy,
|
|
6398
|
-
allowMediaInLobby,
|
|
6399
6676
|
} = options;
|
|
6400
6677
|
|
|
6401
6678
|
this.allowMediaInLobby = options?.allowMediaInLobby;
|
|
6402
6679
|
|
|
6403
6680
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
6404
6681
|
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
6405
|
-
if (this.isUserUnadmitted && !this.wirelessShare && !allowMediaInLobby) {
|
|
6682
|
+
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
6406
6683
|
throw new UserInLobbyError();
|
|
6407
6684
|
}
|
|
6408
6685
|
|
|
@@ -6471,9 +6748,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6471
6748
|
|
|
6472
6749
|
this.createStatsAnalyzer();
|
|
6473
6750
|
|
|
6474
|
-
await this.establishMediaConnection(
|
|
6751
|
+
await this.establishMediaConnection(
|
|
6752
|
+
remoteMediaManagerConfig,
|
|
6753
|
+
bundlePolicy,
|
|
6754
|
+
false,
|
|
6755
|
+
turnServerInfo
|
|
6756
|
+
);
|
|
6475
6757
|
|
|
6476
|
-
|
|
6758
|
+
if (audioEnabled || videoEnabled) {
|
|
6759
|
+
await Meeting.handleDeviceLogging();
|
|
6760
|
+
} else {
|
|
6761
|
+
LoggerProxy.logger.info(`${LOG_HEADER} device logging not required`);
|
|
6762
|
+
}
|
|
6477
6763
|
|
|
6478
6764
|
if (this.mediaProperties.hasLocalShareStream()) {
|
|
6479
6765
|
await this.enqueueScreenShareFloorRequest();
|
|
@@ -7420,7 +7706,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7420
7706
|
|
|
7421
7707
|
if (layoutType) {
|
|
7422
7708
|
if (!LAYOUT_TYPES.includes(layoutType)) {
|
|
7423
|
-
this.rejectWithErrorLog(
|
|
7709
|
+
return this.rejectWithErrorLog(
|
|
7424
7710
|
'Meeting:index#changeVideoLayout --> cannot change video layout, invalid layoutType received.'
|
|
7425
7711
|
);
|
|
7426
7712
|
}
|
|
@@ -7665,9 +7951,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7665
7951
|
|
|
7666
7952
|
/**
|
|
7667
7953
|
*
|
|
7668
|
-
* @returns {string} one of 'attendee','host','cohost', returns the user type of the current user
|
|
7954
|
+
* @returns {string} one of 'panelist', 'attendee', 'host', 'cohost', returns the user type of the current user
|
|
7669
7955
|
*/
|
|
7670
|
-
getCurUserType() {
|
|
7956
|
+
getCurUserType(): RawClientEvent['userType'] | null {
|
|
7671
7957
|
const {roles} = this;
|
|
7672
7958
|
if (roles) {
|
|
7673
7959
|
if (roles.includes(SELF_ROLES.MODERATOR)) {
|
|
@@ -7676,6 +7962,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7676
7962
|
if (roles.includes(SELF_ROLES.COHOST)) {
|
|
7677
7963
|
return 'cohost';
|
|
7678
7964
|
}
|
|
7965
|
+
if (roles.includes(SELF_ROLES.PANELIST)) {
|
|
7966
|
+
return 'panelist';
|
|
7967
|
+
}
|
|
7679
7968
|
if (roles.includes(SELF_ROLES.ATTENDEE)) {
|
|
7680
7969
|
return 'attendee';
|
|
7681
7970
|
}
|
|
@@ -7766,8 +8055,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7766
8055
|
this.queuedMediaUpdates = [];
|
|
7767
8056
|
|
|
7768
8057
|
if (this.transcription) {
|
|
7769
|
-
this.
|
|
7770
|
-
this.triggerStopReceivingTranscriptionEvent();
|
|
8058
|
+
this.stopTranscription();
|
|
7771
8059
|
this.transcription = undefined;
|
|
7772
8060
|
}
|
|
7773
8061
|
};
|
|
@@ -8080,6 +8368,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8080
8368
|
return;
|
|
8081
8369
|
}
|
|
8082
8370
|
|
|
8371
|
+
if (
|
|
8372
|
+
streams?.microphone?.readyState === 'ended' ||
|
|
8373
|
+
streams?.camera?.readyState === 'ended' ||
|
|
8374
|
+
streams?.screenShare?.audio?.readyState === 'ended' ||
|
|
8375
|
+
streams?.screenShare?.video?.readyState === 'ended'
|
|
8376
|
+
) {
|
|
8377
|
+
throw new Error(
|
|
8378
|
+
`Attempted to publish stream with ended readyState, correlationId=${this.correlationId}`
|
|
8379
|
+
);
|
|
8380
|
+
}
|
|
8381
|
+
|
|
8083
8382
|
let floorRequestNeeded = false;
|
|
8084
8383
|
|
|
8085
8384
|
// Screenshare Audio is supported only in multi stream. So we check for screenshare audio presence only if it's a multi stream meeting
|