@webex/plugin-meetings 3.1.0-next.9 → 3.2.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/dist/annotation/annotation.types.d.ts +42 -0
- package/dist/annotation/constants.d.ts +31 -0
- package/dist/annotation/index.d.ts +117 -0
- package/dist/breakouts/breakout.d.ts +8 -0
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/collection.d.ts +5 -0
- package/dist/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/breakouts/events.d.ts +8 -0
- package/dist/breakouts/index.d.ts +5 -0
- package/dist/breakouts/index.js +1 -1
- package/dist/breakouts/request.d.ts +22 -0
- package/dist/breakouts/utils.d.ts +15 -0
- package/dist/common/browser-detection.d.ts +9 -0
- package/dist/common/collection.d.ts +48 -0
- package/dist/common/config.d.ts +2 -0
- package/dist/common/errors/captcha-error.d.ts +15 -0
- package/dist/common/errors/intent-to-join.d.ts +16 -0
- package/dist/common/errors/join-meeting.d.ts +17 -0
- package/dist/common/errors/media.d.ts +15 -0
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/parameter.d.ts +15 -0
- package/dist/common/errors/password-error.d.ts +15 -0
- package/dist/common/errors/permission.d.ts +14 -0
- package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/common/errors/reconnection-in-progress.d.ts +9 -0
- package/dist/common/errors/reconnection-in-progress.js +34 -0
- package/dist/common/errors/reconnection-in-progress.js.map +1 -0
- package/dist/common/errors/reconnection.d.ts +15 -0
- package/dist/common/errors/stats.d.ts +15 -0
- package/dist/common/errors/webex-errors.d.ts +93 -0
- package/dist/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/common/events/events-scope.d.ts +17 -0
- package/dist/common/events/events.d.ts +12 -0
- package/dist/common/events/trigger-proxy.d.ts +2 -0
- package/dist/common/events/util.d.ts +2 -0
- package/dist/common/logs/logger-config.d.ts +2 -0
- package/dist/common/logs/logger-proxy.d.ts +2 -0
- package/dist/common/logs/request.d.ts +36 -0
- package/dist/common/queue.d.ts +34 -0
- package/dist/config.d.ts +73 -0
- package/dist/constants.d.ts +1088 -0
- package/dist/constants.js +6 -3
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.d.ts +4 -0
- package/dist/controls-options-manager/enums.d.ts +15 -0
- package/dist/controls-options-manager/index.d.ts +136 -0
- package/dist/controls-options-manager/types.d.ts +43 -0
- package/dist/controls-options-manager/util.d.ts +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/interceptors/index.d.ts +2 -0
- package/dist/interceptors/locusRetry.d.ts +27 -0
- package/dist/interpretation/collection.d.ts +5 -0
- package/dist/interpretation/index.d.ts +5 -0
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.d.ts +5 -0
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.d.ts +2 -0
- package/dist/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/locus-info/fullState.d.ts +2 -0
- package/dist/locus-info/hostUtils.d.ts +2 -0
- package/dist/locus-info/index.d.ts +322 -0
- package/dist/locus-info/infoUtils.d.ts +2 -0
- package/dist/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/locus-info/parser.d.ts +272 -0
- package/dist/locus-info/selfUtils.d.ts +2 -0
- package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/media/index.d.ts +34 -0
- package/dist/media/properties.d.ts +93 -0
- package/dist/media/util.d.ts +2 -0
- package/dist/mediaQualityMetrics/config.d.ts +241 -0
- package/dist/mediaQualityMetrics/config.js +10 -10
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.d.ts +167 -0
- package/dist/meeting/index.d.ts +1825 -0
- package/dist/meeting/index.js +112 -64
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/meeting/locusMediaRequest.js +27 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.d.ts +178 -0
- package/dist/meeting/request.d.ts +295 -0
- package/dist/meeting/request.type.d.ts +11 -0
- package/dist/meeting/state.d.ts +9 -0
- package/dist/meeting/util.d.ts +119 -0
- package/dist/meeting/util.js +0 -16
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +16 -0
- package/dist/meeting/voicea-meeting.js +37 -49
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meeting-info/collection.d.ts +20 -0
- package/dist/meeting-info/index.d.ts +69 -0
- package/dist/meeting-info/meeting-info-v2.d.ts +123 -0
- package/dist/meeting-info/request.d.ts +22 -0
- package/dist/meeting-info/util.d.ts +2 -0
- package/dist/meeting-info/utilv2.d.ts +2 -0
- package/dist/meetings/collection.d.ts +40 -0
- package/dist/meetings/index.d.ts +398 -0
- package/dist/meetings/index.js +12 -28
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.d.ts +4 -0
- package/dist/meetings/request.d.ts +27 -0
- package/dist/meetings/util.d.ts +18 -0
- package/dist/member/index.d.ts +160 -0
- package/dist/member/types.d.ts +32 -0
- package/dist/member/util.d.ts +2 -0
- package/dist/members/collection.d.ts +29 -0
- package/dist/members/index.d.ts +353 -0
- package/dist/members/request.d.ts +114 -0
- package/dist/members/types.d.ts +25 -0
- package/dist/members/util.d.ts +215 -0
- package/dist/metrics/constants.d.ts +70 -0
- package/dist/metrics/index.d.ts +45 -0
- package/dist/multistream/mediaRequestManager.d.ts +119 -0
- package/dist/multistream/receiveSlot.d.ts +68 -0
- package/dist/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/multistream/remoteMedia.d.ts +72 -0
- package/dist/multistream/remoteMediaGroup.d.ts +49 -0
- package/dist/multistream/remoteMediaManager.d.ts +300 -0
- package/dist/multistream/sendSlotManager.d.ts +69 -0
- package/dist/networkQualityMonitor/index.d.ts +70 -0
- package/dist/personal-meeting-room/index.d.ts +47 -0
- package/dist/personal-meeting-room/request.d.ts +14 -0
- package/dist/personal-meeting-room/util.d.ts +2 -0
- package/dist/reachability/clusterReachability.d.ts +110 -0
- package/dist/reachability/index.d.ts +109 -0
- package/dist/reachability/index.js +88 -9
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.d.ts +39 -0
- package/dist/reachability/util.d.ts +15 -0
- package/dist/reactions/constants.d.ts +3 -0
- package/dist/reactions/reactions.d.ts +4 -0
- package/dist/reactions/reactions.type.d.ts +52 -0
- package/dist/reconnection-manager/index.d.ts +136 -0
- package/dist/recording-controller/enums.d.ts +7 -0
- package/dist/recording-controller/index.d.ts +207 -0
- package/dist/recording-controller/util.d.ts +14 -0
- package/dist/roap/index.d.ts +86 -0
- package/dist/roap/request.d.ts +39 -0
- package/dist/roap/request.js +3 -27
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +155 -0
- package/dist/rtcMetrics/constants.d.ts +4 -0
- package/dist/rtcMetrics/index.d.ts +61 -0
- package/dist/statsAnalyzer/global.d.ts +36 -0
- package/dist/statsAnalyzer/index.d.ts +217 -0
- package/dist/statsAnalyzer/index.js +4 -2
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
- package/dist/statsAnalyzer/mqaUtil.js +14 -0
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.d.ts +64 -0
- package/dist/types/constants.d.ts +3 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +8 -2
- package/dist/types/meeting/index.d.ts +10 -1
- package/dist/types/meeting/locusMediaRequest.d.ts +1 -0
- package/dist/types/meeting/voicea-meeting.d.ts +3 -2
- package/dist/types/meetings/index.d.ts +1 -16
- package/dist/types/reachability/index.d.ts +11 -0
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +21 -21
- package/src/constants.ts +3 -2
- package/src/mediaQualityMetrics/config.ts +13 -7
- package/src/meeting/index.ts +73 -30
- package/src/meeting/locusMediaRequest.ts +31 -0
- package/src/meeting/util.ts +1 -16
- package/src/meeting/voicea-meeting.ts +44 -46
- package/src/meetings/index.ts +15 -27
- package/src/reachability/index.ts +60 -0
- package/src/roap/request.ts +1 -24
- package/src/statsAnalyzer/index.ts +6 -3
- package/src/statsAnalyzer/mqaUtil.ts +18 -0
- package/test/unit/spec/meeting/index.js +70 -33
- package/test/unit/spec/meeting/locusMediaRequest.ts +49 -0
- package/test/unit/spec/meeting/utils.js +0 -10
- package/test/unit/spec/meeting/voicea-meeting.ts +5 -14
- package/test/unit/spec/meetings/index.js +59 -17
- package/test/unit/spec/reachability/index.ts +266 -0
- package/test/unit/spec/roap/request.ts +0 -37
- package/test/unit/spec/stats-analyzer/index.js +89 -8
|
@@ -21,7 +21,9 @@ export const emptyAudioReceive = {
|
|
|
21
21
|
direction: 'inactive',
|
|
22
22
|
isMain: true,
|
|
23
23
|
mariFecEnabled: false,
|
|
24
|
+
mariRtxEnabled: false,
|
|
24
25
|
mariQosEnabled: false,
|
|
26
|
+
mariLiteEnabled: false,
|
|
25
27
|
multistreamEnabled: false,
|
|
26
28
|
},
|
|
27
29
|
dtlsBitrate: 0,
|
|
@@ -75,7 +77,9 @@ export const emptyAudioTransmit = {
|
|
|
75
77
|
direction: 'inactive',
|
|
76
78
|
isMain: true,
|
|
77
79
|
mariFecEnabled: false,
|
|
80
|
+
mariRtxEnabled: false,
|
|
78
81
|
mariQosEnabled: false,
|
|
82
|
+
mariLiteEnabled: false,
|
|
79
83
|
multistreamEnabled: false,
|
|
80
84
|
},
|
|
81
85
|
dtlsBitrate: 0,
|
|
@@ -86,7 +90,6 @@ export const emptyAudioTransmit = {
|
|
|
86
90
|
queueDelay: 0,
|
|
87
91
|
remoteJitter: 0,
|
|
88
92
|
remoteLossRate: 0,
|
|
89
|
-
remoteReceiveRate: 0,
|
|
90
93
|
roundTripTime: 0,
|
|
91
94
|
rtcpBitrate: 0,
|
|
92
95
|
rtcpPackets: 0,
|
|
@@ -119,8 +122,10 @@ export const emptyVideoReceive = {
|
|
|
119
122
|
common: {
|
|
120
123
|
direction: 'inactive',
|
|
121
124
|
isMain: true, // Not avaliable
|
|
122
|
-
mariFecEnabled:
|
|
123
|
-
|
|
125
|
+
mariFecEnabled: false,
|
|
126
|
+
mariRtxEnabled: false,
|
|
127
|
+
mariQosEnabled: false,
|
|
128
|
+
mariLiteEnabled: false,
|
|
124
129
|
multistreamEnabled: true, // Not avaliable
|
|
125
130
|
},
|
|
126
131
|
dtlsBitrate: 0, // Not avaliable
|
|
@@ -184,8 +189,10 @@ export const emptyVideoTransmit = {
|
|
|
184
189
|
common: {
|
|
185
190
|
direction: 'inactive',
|
|
186
191
|
isMain: true,
|
|
187
|
-
mariFecEnabled: false,
|
|
188
|
-
|
|
192
|
+
mariFecEnabled: false,
|
|
193
|
+
mariRtxEnabled: false,
|
|
194
|
+
mariQosEnabled: false,
|
|
195
|
+
mariLiteEnabled: false,
|
|
189
196
|
multistreamEnabled: false, // Not avaliable
|
|
190
197
|
},
|
|
191
198
|
dtlsBitrate: 0, // Not avaliable
|
|
@@ -193,10 +200,9 @@ export const emptyVideoTransmit = {
|
|
|
193
200
|
fecBitrate: 0, // Not avaliable
|
|
194
201
|
fecPackets: 0, // TODO: check inbound-rtp// Not avaliable
|
|
195
202
|
maxBitrate: 0, // Currently hardcoded
|
|
196
|
-
queueDelay: 0,
|
|
203
|
+
queueDelay: 0,
|
|
197
204
|
remoteJitter: 0, // remoteInboundRtp.jitter
|
|
198
205
|
remoteLossRate: 0, // comparedResults.lossRate
|
|
199
|
-
remoteReceiveRate: 0, // compareResults.packetsLost
|
|
200
206
|
roundTripTime: 0, // compareResults.roundTripTime
|
|
201
207
|
rtcpBitrate: 0, // Dont have access to it
|
|
202
208
|
rtcpPackets: 0, // Dont have access to rtcp
|
package/src/meeting/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
import {
|
|
39
39
|
EVENT_TRIGGERS as VOICEAEVENTS,
|
|
40
40
|
TURN_ON_CAPTION_STATUS,
|
|
41
|
+
type MeetingTranscriptPayload,
|
|
41
42
|
} from '@webex/internal-plugin-voicea';
|
|
42
43
|
import {processNewCaptions} from './voicea-meeting';
|
|
43
44
|
|
|
@@ -630,6 +631,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
630
631
|
turnDiscoverySkippedReason: TurnDiscoverySkipReason;
|
|
631
632
|
turnServerUsed: boolean;
|
|
632
633
|
areVoiceaEventsSetup = false;
|
|
634
|
+
isMoveToInProgress = false;
|
|
633
635
|
|
|
634
636
|
voiceaListenerCallbacks: object = {
|
|
635
637
|
[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]: (payload: Transcription['languageOptions']) => {
|
|
@@ -654,7 +656,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
654
656
|
this.transcription.isListening = !!data.isListening;
|
|
655
657
|
this.transcription.commandText = data.text ?? '';
|
|
656
658
|
},
|
|
657
|
-
[VOICEAEVENTS.NEW_CAPTION]: (data) => {
|
|
659
|
+
[VOICEAEVENTS.NEW_CAPTION]: (data: MeetingTranscriptPayload) => {
|
|
658
660
|
processNewCaptions({data, meeting: this});
|
|
659
661
|
|
|
660
662
|
LoggerProxy.logger.debug(
|
|
@@ -1389,11 +1391,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1389
1391
|
this.remoteMediaManager = null;
|
|
1390
1392
|
|
|
1391
1393
|
this.localAudioStreamMuteStateHandler = () => {
|
|
1392
|
-
this.audio
|
|
1394
|
+
this.audio?.handleLocalStreamMuteStateChange(this);
|
|
1393
1395
|
};
|
|
1394
1396
|
|
|
1395
1397
|
this.localVideoStreamMuteStateHandler = () => {
|
|
1396
|
-
this.video
|
|
1398
|
+
this.video?.handleLocalStreamMuteStateChange(this);
|
|
1397
1399
|
};
|
|
1398
1400
|
|
|
1399
1401
|
// The handling of output track changes should be done inside
|
|
@@ -3079,6 +3081,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3079
3081
|
options: {meetingId: this.id},
|
|
3080
3082
|
});
|
|
3081
3083
|
}
|
|
3084
|
+
this.updateLLMConnection();
|
|
3082
3085
|
});
|
|
3083
3086
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, async (payload) => {
|
|
3084
3087
|
this.stopKeepAlive();
|
|
@@ -3942,7 +3945,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3942
3945
|
// we don't update this.mediaProperties.mediaDirection.sendAudio, because we always keep it as true to avoid extra SDP exchanges
|
|
3943
3946
|
this.mediaProperties.setLocalAudioStream(localStream);
|
|
3944
3947
|
|
|
3945
|
-
this.audio
|
|
3948
|
+
this.audio?.handleLocalStreamChange(this);
|
|
3946
3949
|
|
|
3947
3950
|
localStream?.on(
|
|
3948
3951
|
LocalStreamEventNames.UserMuteStateChange,
|
|
@@ -3984,7 +3987,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3984
3987
|
// we don't update this.mediaProperties.mediaDirection.sendVideo, because we always keep it as true to avoid extra SDP exchanges
|
|
3985
3988
|
this.mediaProperties.setLocalVideoStream(localStream);
|
|
3986
3989
|
|
|
3987
|
-
this.video
|
|
3990
|
+
this.video?.handleLocalStreamChange(this);
|
|
3988
3991
|
|
|
3989
3992
|
localStream?.on(
|
|
3990
3993
|
LocalStreamEventNames.UserMuteStateChange,
|
|
@@ -4694,12 +4697,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4694
4697
|
* @throws TranscriptionNotSupportedError
|
|
4695
4698
|
*/
|
|
4696
4699
|
isTranscriptionSupported() {
|
|
4697
|
-
if (this.locusInfo.controls.transcribe?.
|
|
4700
|
+
if (this.locusInfo.controls.transcribe?.caption) {
|
|
4698
4701
|
return true;
|
|
4699
4702
|
}
|
|
4700
4703
|
|
|
4701
4704
|
LoggerProxy.logger.error(
|
|
4702
|
-
'Meeting:index#isTranscriptionSupported -->
|
|
4705
|
+
'Meeting:index#isTranscriptionSupported --> Closed Captions is not enabled/supported'
|
|
4703
4706
|
);
|
|
4704
4707
|
|
|
4705
4708
|
return false;
|
|
@@ -4950,6 +4953,27 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4950
4953
|
);
|
|
4951
4954
|
}
|
|
4952
4955
|
|
|
4956
|
+
/**
|
|
4957
|
+
* This is a callback for the LLM event that is triggered when it comes online
|
|
4958
|
+
* This method in turn will trigger an event to the developers that the LLM is connected
|
|
4959
|
+
* @private
|
|
4960
|
+
* @memberof Meeting
|
|
4961
|
+
* @returns {null}
|
|
4962
|
+
*/
|
|
4963
|
+
private handleLLMOnline = (): void => {
|
|
4964
|
+
// @ts-ignore
|
|
4965
|
+
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
4966
|
+
Trigger.trigger(
|
|
4967
|
+
this,
|
|
4968
|
+
{
|
|
4969
|
+
file: 'meeting/index',
|
|
4970
|
+
function: 'handleLLMOnline',
|
|
4971
|
+
},
|
|
4972
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED,
|
|
4973
|
+
undefined
|
|
4974
|
+
);
|
|
4975
|
+
};
|
|
4976
|
+
|
|
4953
4977
|
/**
|
|
4954
4978
|
* Specify joining via audio (option: pstn), video, screenshare
|
|
4955
4979
|
* @param {JoinOptions} options A configurable options object for joining a meeting
|
|
@@ -5169,6 +5193,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5169
5193
|
.then((join) => {
|
|
5170
5194
|
// @ts-ignore - config coming from registerPlugin
|
|
5171
5195
|
if (this.config.enableAutomaticLLM) {
|
|
5196
|
+
// @ts-ignore
|
|
5197
|
+
this.webex.internal.llm.on('online', this.handleLLMOnline);
|
|
5172
5198
|
this.updateLLMConnection()
|
|
5173
5199
|
.catch((error) => {
|
|
5174
5200
|
LoggerProxy.logger.error(
|
|
@@ -5186,15 +5212,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5186
5212
|
LoggerProxy.logger.info(
|
|
5187
5213
|
'Meeting:index#join --> Transcription Socket Connection Success'
|
|
5188
5214
|
);
|
|
5189
|
-
Trigger.trigger(
|
|
5190
|
-
this,
|
|
5191
|
-
{
|
|
5192
|
-
file: 'meeting/index',
|
|
5193
|
-
function: 'join',
|
|
5194
|
-
},
|
|
5195
|
-
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED,
|
|
5196
|
-
undefined
|
|
5197
|
-
);
|
|
5198
5215
|
});
|
|
5199
5216
|
}
|
|
5200
5217
|
|
|
@@ -5426,17 +5443,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5426
5443
|
},
|
|
5427
5444
|
};
|
|
5428
5445
|
|
|
5429
|
-
this.cleanupLocalStreams();
|
|
5430
|
-
|
|
5431
5446
|
this.mediaProperties.setMediaDirection(mediaSettings.mediaDirection);
|
|
5432
5447
|
this.mediaProperties.unsetRemoteMedia();
|
|
5433
5448
|
|
|
5434
|
-
// when a move to is intiated by the client , Locus delets the existing media node from the server as soon the
|
|
5435
|
-
// once the
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5449
|
+
// when a move to is intiated by the client , Locus delets the existing media node from the server as soon the device answers the meeting
|
|
5450
|
+
// once the device answers we close the old connection and create new media server connection with only share enabled
|
|
5451
|
+
if (this.statsAnalyzer) {
|
|
5452
|
+
await this.statsAnalyzer.stopAnalyzer();
|
|
5453
|
+
}
|
|
5454
|
+
await this.closeRemoteStreams();
|
|
5455
|
+
await this.closePeerConnections();
|
|
5456
|
+
this.cleanupLocalStreams();
|
|
5457
|
+
this.unsetRemoteStreams();
|
|
5458
|
+
this.unsetPeerConnections();
|
|
5459
|
+
this.reconnectionManager.cleanUp();
|
|
5460
|
+
|
|
5461
|
+
await this.addMedia({
|
|
5462
|
+
audioEnabled: false,
|
|
5463
|
+
videoEnabled: false,
|
|
5464
|
+
shareVideoEnabled: true,
|
|
5439
5465
|
});
|
|
5466
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_TO_SUCCESS);
|
|
5467
|
+
this.isMoveToInProgress = false;
|
|
5440
5468
|
} catch (error) {
|
|
5441
5469
|
LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
|
|
5442
5470
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_TO_FAILURE, {
|
|
@@ -5445,6 +5473,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5445
5473
|
reason: error.message,
|
|
5446
5474
|
stack: error.stack,
|
|
5447
5475
|
});
|
|
5476
|
+
this.isMoveToInProgress = false;
|
|
5448
5477
|
}
|
|
5449
5478
|
});
|
|
5450
5479
|
|
|
@@ -5453,6 +5482,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5453
5482
|
resourceId
|
|
5454
5483
|
);
|
|
5455
5484
|
|
|
5485
|
+
// TODO: Check with locus if SELF_OBSERVING event would ever be not emitted
|
|
5486
|
+
// If yes, introduce a timeout mechanism
|
|
5487
|
+
this.isMoveToInProgress = true;
|
|
5488
|
+
|
|
5456
5489
|
return MeetingUtil.joinMeetingOptions(this, {resourceId, moveToResource: true})
|
|
5457
5490
|
.then(() => {
|
|
5458
5491
|
this.meetingFiniteStateMachine.join();
|
|
@@ -5466,6 +5499,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5466
5499
|
stack: error.stack,
|
|
5467
5500
|
});
|
|
5468
5501
|
LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
|
|
5502
|
+
this.isMoveToInProgress = false;
|
|
5469
5503
|
|
|
5470
5504
|
return Promise.reject(error);
|
|
5471
5505
|
});
|
|
@@ -6452,11 +6486,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6452
6486
|
/**
|
|
6453
6487
|
* Performs TURN discovery as a separate call to the Locus /media API
|
|
6454
6488
|
*
|
|
6455
|
-
* @param {boolean}
|
|
6489
|
+
* @param {boolean} isReconnecting
|
|
6456
6490
|
* @param {boolean} isForced
|
|
6457
6491
|
* @returns {Promise}
|
|
6458
6492
|
*/
|
|
6459
|
-
private async doTurnDiscovery(
|
|
6493
|
+
private async doTurnDiscovery(
|
|
6494
|
+
isReconnecting: boolean,
|
|
6495
|
+
isForced: boolean
|
|
6496
|
+
): Promise<TurnDiscoveryResult> {
|
|
6460
6497
|
// @ts-ignore
|
|
6461
6498
|
const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;
|
|
6462
6499
|
|
|
@@ -6465,7 +6502,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6465
6502
|
name: 'internal.client.add-media.turn-discovery.start',
|
|
6466
6503
|
});
|
|
6467
6504
|
|
|
6468
|
-
const turnDiscoveryResult = await this.roap.doTurnDiscovery(this,
|
|
6505
|
+
const turnDiscoveryResult = await this.roap.doTurnDiscovery(this, isReconnecting, isForced);
|
|
6469
6506
|
|
|
6470
6507
|
this.turnDiscoverySkippedReason = turnDiscoveryResult?.turnDiscoverySkippedReason;
|
|
6471
6508
|
this.turnServerUsed = !this.turnDiscoverySkippedReason;
|
|
@@ -6504,11 +6541,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6504
6541
|
turnServerInfo?: TurnServerInfo
|
|
6505
6542
|
): Promise<void> {
|
|
6506
6543
|
const LOG_HEADER = 'Meeting:index#addMedia():establishMediaConnection -->';
|
|
6507
|
-
const
|
|
6544
|
+
const isReconnecting = this.isMoveToInProgress || this.retriedWithTurnServer;
|
|
6545
|
+
|
|
6546
|
+
// We are forcing turn discovery if the case is moveTo and a turn server was used already
|
|
6547
|
+
if (this.isMoveToInProgress && this.turnServerUsed) {
|
|
6548
|
+
isForced = true;
|
|
6549
|
+
}
|
|
6508
6550
|
|
|
6509
6551
|
try {
|
|
6510
6552
|
if (!turnServerInfo) {
|
|
6511
|
-
({turnServerInfo} = await this.doTurnDiscovery(
|
|
6553
|
+
({turnServerInfo} = await this.doTurnDiscovery(isReconnecting, isForced));
|
|
6512
6554
|
}
|
|
6513
6555
|
|
|
6514
6556
|
const mc = await this.createMediaConnection(turnServerInfo, bundlePolicy);
|
|
@@ -6705,6 +6747,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6705
6747
|
this.locusMediaRequest = new LocusMediaRequest(
|
|
6706
6748
|
{
|
|
6707
6749
|
correlationId: this.correlationId,
|
|
6750
|
+
meetingId: this.id,
|
|
6708
6751
|
device: {
|
|
6709
6752
|
url: this.deviceUrl,
|
|
6710
6753
|
// @ts-ignore
|
|
@@ -7007,7 +7050,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7007
7050
|
if (audioEnabled !== undefined) {
|
|
7008
7051
|
this.mediaProperties.mediaDirection.sendAudio = audioEnabled;
|
|
7009
7052
|
this.mediaProperties.mediaDirection.receiveAudio = audioEnabled;
|
|
7010
|
-
this.audio
|
|
7053
|
+
this.audio?.enable(this, audioEnabled);
|
|
7011
7054
|
if (this.isMultistream) {
|
|
7012
7055
|
this.sendSlotManager.setActive(MediaType.AudioMain, audioEnabled);
|
|
7013
7056
|
}
|
|
@@ -7016,7 +7059,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7016
7059
|
if (videoEnabled !== undefined) {
|
|
7017
7060
|
this.mediaProperties.mediaDirection.sendVideo = videoEnabled;
|
|
7018
7061
|
this.mediaProperties.mediaDirection.receiveVideo = videoEnabled;
|
|
7019
|
-
this.video
|
|
7062
|
+
this.video?.enable(this, videoEnabled);
|
|
7020
7063
|
if (this.isMultistream) {
|
|
7021
7064
|
this.sendSlotManager.setActive(MediaType.VideoMain, videoEnabled);
|
|
7022
7065
|
}
|
|
@@ -88,6 +88,7 @@ export type Config = {
|
|
|
88
88
|
regionCode?: string;
|
|
89
89
|
};
|
|
90
90
|
correlationId: string;
|
|
91
|
+
meetingId: string;
|
|
91
92
|
preferTranscoding: boolean;
|
|
92
93
|
};
|
|
93
94
|
|
|
@@ -223,6 +224,14 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
223
224
|
localMedias.roapMessage = request.roapMessage;
|
|
224
225
|
localMedias.reachability = request.reachability;
|
|
225
226
|
body.clientMediaPreferences.joinCookie = request.joinCookie;
|
|
227
|
+
|
|
228
|
+
// @ts-ignore
|
|
229
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
230
|
+
name: 'client.locus.media.request',
|
|
231
|
+
options: {
|
|
232
|
+
meetingId: this.config.meetingId,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
226
235
|
break;
|
|
227
236
|
}
|
|
228
237
|
|
|
@@ -256,6 +265,16 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
256
265
|
this.confluenceState = 'created';
|
|
257
266
|
}
|
|
258
267
|
|
|
268
|
+
if (request.type === 'RoapMessage') {
|
|
269
|
+
// @ts-ignore
|
|
270
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
271
|
+
name: 'client.locus.media.response',
|
|
272
|
+
options: {
|
|
273
|
+
meetingId: this.config.meetingId,
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
259
278
|
return result;
|
|
260
279
|
})
|
|
261
280
|
.catch((e) => {
|
|
@@ -265,6 +284,18 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
265
284
|
) {
|
|
266
285
|
this.confluenceState = 'not created';
|
|
267
286
|
}
|
|
287
|
+
|
|
288
|
+
if (request.type === 'RoapMessage') {
|
|
289
|
+
// @ts-ignore
|
|
290
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
291
|
+
name: 'client.locus.media.response',
|
|
292
|
+
options: {
|
|
293
|
+
meetingId: this.config.meetingId,
|
|
294
|
+
rawError: e,
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
268
299
|
throw e;
|
|
269
300
|
});
|
|
270
301
|
}
|
package/src/meeting/util.ts
CHANGED
|
@@ -47,7 +47,6 @@ const MeetingUtil = {
|
|
|
47
47
|
},
|
|
48
48
|
|
|
49
49
|
remoteUpdateAudioVideo: (meeting, audioMuted?: boolean, videoMuted?: boolean) => {
|
|
50
|
-
const webex = meeting.getWebexObject();
|
|
51
50
|
if (!meeting) {
|
|
52
51
|
return Promise.reject(new ParameterError('You need a meeting object.'));
|
|
53
52
|
}
|
|
@@ -60,12 +59,6 @@ const MeetingUtil = {
|
|
|
60
59
|
);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
// @ts-ignore
|
|
64
|
-
webex.internal.newMetrics.submitClientEvent({
|
|
65
|
-
name: 'client.locus.media.request',
|
|
66
|
-
options: {meetingId: meeting.id},
|
|
67
|
-
});
|
|
68
|
-
|
|
69
62
|
return meeting.locusMediaRequest
|
|
70
63
|
.send({
|
|
71
64
|
type: 'LocalMute',
|
|
@@ -77,15 +70,7 @@ const MeetingUtil = {
|
|
|
77
70
|
videoMuted,
|
|
78
71
|
},
|
|
79
72
|
})
|
|
80
|
-
.then((response) =>
|
|
81
|
-
// @ts-ignore
|
|
82
|
-
webex.internal.newMetrics.submitClientEvent({
|
|
83
|
-
name: 'client.locus.media.response',
|
|
84
|
-
options: {meetingId: meeting.id},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return response?.body?.locus;
|
|
88
|
-
});
|
|
73
|
+
.then((response) => response?.body?.locus);
|
|
89
74
|
},
|
|
90
75
|
|
|
91
76
|
hasOwner: (info) => info && info.owner,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {type MeetingTranscriptPayload} from '@webex/internal-plugin-voicea';
|
|
2
|
+
|
|
1
3
|
export const getSpeaker = (members, csis = []) =>
|
|
2
4
|
Object.values(members).find((member: any) => {
|
|
3
5
|
const memberCSIs = member.participant.status.csis ?? [];
|
|
@@ -31,43 +33,16 @@ export const getSpeakerFromProxyOrStore = ({csisKey, meetingMembers, transcriptD
|
|
|
31
33
|
return {speaker, needsCaching};
|
|
32
34
|
};
|
|
33
35
|
|
|
34
|
-
export const processNewCaptions = ({
|
|
36
|
+
export const processNewCaptions = ({
|
|
37
|
+
data,
|
|
38
|
+
meeting,
|
|
39
|
+
}: {
|
|
40
|
+
data: MeetingTranscriptPayload;
|
|
41
|
+
meeting: any;
|
|
42
|
+
}) => {
|
|
35
43
|
const {transcriptId} = data;
|
|
36
44
|
const transcriptData = meeting.transcription;
|
|
37
45
|
|
|
38
|
-
if (data.isFinal) {
|
|
39
|
-
transcriptData.interimCaptions[transcriptId].forEach((interimId) => {
|
|
40
|
-
const interimTranscriptIndex = transcriptData.captions.findIndex(
|
|
41
|
-
(transcript) => transcript.id === interimId
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
if (interimTranscriptIndex !== -1) {
|
|
45
|
-
transcriptData.captions.splice(interimTranscriptIndex, 1);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
delete transcriptData.interimCaptions[transcriptId];
|
|
49
|
-
const csisKey = data.transcript?.csis[0];
|
|
50
|
-
|
|
51
|
-
const {needsCaching, speaker} = getSpeakerFromProxyOrStore({
|
|
52
|
-
meetingMembers: meeting.members.membersCollection.members,
|
|
53
|
-
transcriptData,
|
|
54
|
-
csisKey,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
if (needsCaching) {
|
|
58
|
-
transcriptData.speakerProxy[csisKey] = speaker;
|
|
59
|
-
}
|
|
60
|
-
const captionData = {
|
|
61
|
-
id: transcriptId,
|
|
62
|
-
isFinal: data.isFinal,
|
|
63
|
-
translations: data.translations,
|
|
64
|
-
text: data.transcript?.text,
|
|
65
|
-
currentSpokenLanguage: data.transcript?.transcript_language_code,
|
|
66
|
-
timestamp: data.timestamp,
|
|
67
|
-
speaker,
|
|
68
|
-
};
|
|
69
|
-
transcriptData.captions.push(captionData);
|
|
70
|
-
}
|
|
71
46
|
const {transcripts = []} = data;
|
|
72
47
|
const transcriptsPerCsis = new Map();
|
|
73
48
|
|
|
@@ -80,8 +55,11 @@ export const processNewCaptions = ({data, meeting}) => {
|
|
|
80
55
|
|
|
81
56
|
const newCaption = `${transcriptsPerCsis.get(csisMember)?.text ?? ''} ${text}`.trim();
|
|
82
57
|
|
|
83
|
-
|
|
84
|
-
|
|
58
|
+
transcriptsPerCsis.set(csisMember, {
|
|
59
|
+
...transcript,
|
|
60
|
+
text: newCaption,
|
|
61
|
+
currentSpokenLanguage,
|
|
62
|
+
});
|
|
85
63
|
}
|
|
86
64
|
const interimTranscriptionIds = [];
|
|
87
65
|
|
|
@@ -91,31 +69,51 @@ export const processNewCaptions = ({data, meeting}) => {
|
|
|
91
69
|
transcriptData,
|
|
92
70
|
csisKey: key,
|
|
93
71
|
});
|
|
72
|
+
const {speakerId} = speaker;
|
|
73
|
+
const interimId = `${transcriptId}_${speakerId}`;
|
|
94
74
|
|
|
95
75
|
if (needsCaching) {
|
|
96
76
|
transcriptData.speakerProxy[key] = speaker;
|
|
97
77
|
}
|
|
98
|
-
|
|
99
|
-
const interimId = `${transcriptId}_${speakerId}`;
|
|
78
|
+
|
|
100
79
|
const captionData = {
|
|
101
80
|
id: interimId,
|
|
102
81
|
isFinal: data.isFinal,
|
|
103
82
|
translations: value.translations,
|
|
104
83
|
text: value.text,
|
|
105
|
-
currentCaptionLanguage:
|
|
84
|
+
currentCaptionLanguage:
|
|
85
|
+
meeting.transcription?.languageOptions?.currentCaptionLanguage ||
|
|
86
|
+
value.currentSpokenLanguage,
|
|
87
|
+
currentSpokenLanguage:
|
|
88
|
+
meeting.transcription?.languageOptions?.currentSpokenLanguage ||
|
|
89
|
+
data.transcripts[0]?.transcript_language_code,
|
|
106
90
|
timestamp: value?.timestamp,
|
|
107
91
|
speaker,
|
|
108
92
|
};
|
|
109
93
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
94
|
+
if (!data.isFinal) {
|
|
95
|
+
const interimTranscriptIndex = transcriptData.captions.findIndex(
|
|
96
|
+
(transcript) => transcript.id === interimId
|
|
97
|
+
);
|
|
113
98
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
99
|
+
if (interimTranscriptIndex !== -1) {
|
|
100
|
+
transcriptData.captions.splice(interimTranscriptIndex, 1);
|
|
101
|
+
}
|
|
117
102
|
|
|
118
|
-
|
|
103
|
+
interimTranscriptionIds.push(interimId);
|
|
104
|
+
} else {
|
|
105
|
+
transcriptData.interimCaptions[transcriptId].forEach((innerInterimId) => {
|
|
106
|
+
const interimTranscriptIndex = transcriptData.captions.findIndex(
|
|
107
|
+
(transcript) => transcript.id === innerInterimId
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
if (interimTranscriptIndex !== -1) {
|
|
111
|
+
transcriptData.captions.splice(interimTranscriptIndex, 1);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
delete transcriptData.interimCaptions[transcriptId];
|
|
115
|
+
captionData.id = transcriptId;
|
|
116
|
+
}
|
|
119
117
|
transcriptData.captions.push(captionData);
|
|
120
118
|
}
|
|
121
119
|
transcriptData.interimCaptions[transcriptId] = interimTranscriptionIds;
|
package/src/meetings/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
|
|
2
|
-
|
|
2
|
+
import {union} from 'lodash';
|
|
3
3
|
import '@webex/internal-plugin-mercury';
|
|
4
4
|
import '@webex/internal-plugin-conversation';
|
|
5
5
|
import '@webex/internal-plugin-metrics';
|
|
@@ -45,6 +45,8 @@ import {
|
|
|
45
45
|
MEETINGNUMBER,
|
|
46
46
|
_JOINED_,
|
|
47
47
|
_MOVED_,
|
|
48
|
+
_ON_HOLD_LOBBY_,
|
|
49
|
+
_WAIT_,
|
|
48
50
|
} from '../constants';
|
|
49
51
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
50
52
|
import MeetingInfo from '../meeting-info';
|
|
@@ -340,6 +342,9 @@ export default class Meetings extends WebexPlugin {
|
|
|
340
342
|
if (newLocus) {
|
|
341
343
|
const isNewLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(newLocus);
|
|
342
344
|
const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
|
|
345
|
+
const isSelfMovedToLobby =
|
|
346
|
+
newLocus?.self?.devices[0]?.intent?.reason === _ON_HOLD_LOBBY_ &&
|
|
347
|
+
newLocus?.self?.devices[0]?.intent?.type === _WAIT_;
|
|
343
348
|
if (!meeting) {
|
|
344
349
|
if (isNewLocusAsBreakout) {
|
|
345
350
|
LoggerProxy.logger.log(
|
|
@@ -352,7 +357,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
352
357
|
return this.isNeedHandleMainLocus(meeting, newLocus);
|
|
353
358
|
}
|
|
354
359
|
if (!isNewLocusAsBreakout) {
|
|
355
|
-
return this.isNeedHandleMainLocus(meeting, newLocus);
|
|
360
|
+
return isSelfMovedToLobby || this.isNeedHandleMainLocus(meeting, newLocus);
|
|
356
361
|
}
|
|
357
362
|
|
|
358
363
|
return !isSelfMoved;
|
|
@@ -996,7 +1001,10 @@ export default class Meetings extends WebexPlugin {
|
|
|
996
1001
|
fetchUserPreferredWebexSite() {
|
|
997
1002
|
return this.request.getMeetingPreferences().then((res) => {
|
|
998
1003
|
if (res) {
|
|
999
|
-
|
|
1004
|
+
const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
|
|
1005
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
1006
|
+
// @ts-ignore
|
|
1007
|
+
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
|
|
1000
1008
|
}
|
|
1001
1009
|
|
|
1002
1010
|
// fall back to getting the preferred site from the user information
|
|
@@ -1009,6 +1017,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1009
1017
|
user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
|
|
1010
1018
|
if (preferredWebexSite) {
|
|
1011
1019
|
this.preferredWebexSite = preferredWebexSite;
|
|
1020
|
+
// @ts-ignore
|
|
1021
|
+
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
|
|
1012
1022
|
} else {
|
|
1013
1023
|
throw new Error('site not found');
|
|
1014
1024
|
}
|
|
@@ -1383,22 +1393,12 @@ export default class Meetings extends WebexPlugin {
|
|
|
1383
1393
|
|
|
1384
1394
|
/**
|
|
1385
1395
|
* Get all meetings.
|
|
1386
|
-
* @param {object} options
|
|
1387
|
-
* @param {object} options.startDate - get meetings after this start date
|
|
1388
|
-
* @param {object} options.endDate - get meetings before this end date
|
|
1389
1396
|
* @returns {Object} All currently active meetings.
|
|
1390
1397
|
* @public
|
|
1391
1398
|
* @memberof Meetings
|
|
1392
1399
|
*/
|
|
1393
|
-
public getAllMeetings(
|
|
1394
|
-
|
|
1395
|
-
startDate: object;
|
|
1396
|
-
endDate: object;
|
|
1397
|
-
} = {} as any
|
|
1398
|
-
) {
|
|
1399
|
-
// Options may include other parameters to filter this collection
|
|
1400
|
-
// of meetings.
|
|
1401
|
-
return this.meetingCollection.getAll(options);
|
|
1400
|
+
public getAllMeetings() {
|
|
1401
|
+
return this.meetingCollection.getAll();
|
|
1402
1402
|
}
|
|
1403
1403
|
|
|
1404
1404
|
/**
|
|
@@ -1524,18 +1524,6 @@ export default class Meetings extends WebexPlugin {
|
|
|
1524
1524
|
this.breakoutLocusForHandleLater.splice(existIndex, 1);
|
|
1525
1525
|
}
|
|
1526
1526
|
|
|
1527
|
-
/**
|
|
1528
|
-
* Get all scheduled meetings.
|
|
1529
|
-
* @param {object} options
|
|
1530
|
-
* @param {object} options.startDate - get meetings after this start date
|
|
1531
|
-
* @param {object} options.endDate - get meetings before this end date
|
|
1532
|
-
* @returns {Object} All scheduled meetings.
|
|
1533
|
-
* @memberof Meetings
|
|
1534
|
-
*/
|
|
1535
|
-
getScheduledMeetings() {
|
|
1536
|
-
return this.meetingCollection.getAll({scheduled: true});
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
1527
|
/**
|
|
1540
1528
|
* Get the logger instance for plugin-meetings
|
|
1541
1529
|
* @returns {Logger}
|