@webex/plugin-meetings 3.0.0-bnr.4 → 3.0.0-stream-classes.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +70 -32
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +422 -217
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +12 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/webex-errors.js +3 -2
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.d.ts +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +1 -7
- package/dist/config.js.map +1 -1
- package/dist/constants.js +118 -24
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +2 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +19 -14
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +80 -11
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +62 -20
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +71 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +305 -57
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +43 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +219 -63
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +44 -22
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +57 -104
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +60 -121
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +61 -3
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +2530 -2534
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +125 -205
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +150 -150
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +568 -438
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +48 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +94 -38
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +4 -2
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.d.ts +0 -2
- package/dist/meetings/index.js +260 -85
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/util.js +42 -7
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.d.ts +2 -0
- package/dist/member/index.js +26 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/member.types.d.ts +11 -0
- package/dist/member/member.types.js +18 -0
- package/dist/member/member.types.js.map +1 -0
- package/dist/member/types.js +11 -1
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +60 -23
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +4 -1
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +75 -45
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +308 -317
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/config.js +1 -3
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/constants.js +1 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.js +1 -451
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +136 -40
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +4 -4
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +36 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/index.js +18 -3
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +5 -3
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +181 -153
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +25 -32
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +42 -51
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +97 -38
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +0 -1
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +43 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +124 -0
- package/dist/types/breakouts/events.d.ts +2 -0
- package/dist/types/breakouts/utils.d.ts +7 -0
- package/dist/types/common/errors/webex-errors.d.ts +1 -1
- package/dist/types/config.d.ts +0 -6
- package/dist/types/constants.d.ts +51 -21
- package/dist/types/controls-options-manager/enums.d.ts +2 -0
- package/dist/types/controls-options-manager/index.d.ts +1 -1
- package/dist/types/controls-options-manager/types.d.ts +7 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +39 -1
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +16 -38
- package/dist/types/meeting/in-meeting-actions.d.ts +46 -2
- package/dist/types/meeting/index.d.ts +179 -379
- package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
- package/dist/types/meeting/muteState.d.ts +39 -40
- package/dist/types/meeting/request.d.ts +25 -26
- package/dist/types/meeting/util.d.ts +74 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +14 -3
- package/dist/types/meetings/index.d.ts +49 -1
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +2 -0
- package/dist/types/members/request.d.ts +56 -11
- package/dist/types/members/util.d.ts +209 -1
- package/dist/types/metrics/config.d.ts +26 -2
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +17 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +27 -10
- package/dist/types/multistream/receiveSlot.d.ts +3 -3
- package/dist/types/multistream/remoteMedia.d.ts +2 -2
- package/dist/types/multistream/remoteMediaManager.d.ts +14 -0
- package/dist/types/roap/request.d.ts +6 -8
- package/dist/types/roap/turnDiscovery.d.ts +18 -1
- package/package.json +3 -2
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +3 -2
- package/src/breakouts/breakout.ts +62 -27
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +244 -64
- package/src/breakouts/utils.ts +13 -0
- package/src/common/errors/webex-errors.ts +6 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +0 -6
- package/src/constants.ts +111 -19
- package/src/controls-options-manager/enums.ts +2 -0
- package/src/controls-options-manager/index.ts +13 -10
- package/src/controls-options-manager/types.ts +10 -0
- package/src/controls-options-manager/util.ts +82 -11
- package/src/index.ts +18 -11
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +81 -0
- package/src/locus-info/index.ts +318 -57
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +48 -0
- package/src/locus-info/parser.ts +224 -39
- package/src/locus-info/selfUtils.ts +32 -20
- package/src/media/index.ts +94 -108
- package/src/media/properties.ts +69 -109
- package/src/meeting/in-meeting-actions.ts +120 -4
- package/src/meeting/index.ts +1967 -2120
- package/src/meeting/locusMediaRequest.ts +314 -0
- package/src/meeting/muteState.ts +119 -194
- package/src/meeting/request.ts +122 -115
- package/src/meeting/util.ts +549 -413
- package/src/meeting-info/index.ts +54 -8
- package/src/meeting-info/meeting-info-v2.ts +89 -24
- package/src/meeting-info/utilv2.ts +6 -2
- package/src/meetings/index.ts +247 -87
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/util.ts +47 -12
- package/src/member/index.ts +28 -1
- package/src/member/types.ts +14 -0
- package/src/member/util.ts +75 -26
- package/src/members/index.ts +7 -1
- package/src/members/request.ts +61 -21
- package/src/members/util.ts +316 -326
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +1 -474
- package/src/multistream/mediaRequestManager.ts +183 -67
- package/src/multistream/receiveSlot.ts +4 -4
- package/src/multistream/receiveSlotManager.ts +4 -4
- package/src/multistream/remoteMedia.ts +2 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +33 -0
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/index.ts +15 -4
- package/src/reachability/request.ts +7 -3
- package/src/reconnection-manager/index.ts +36 -29
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +25 -30
- package/src/roap/request.ts +44 -51
- package/src/roap/turnDiscovery.ts +51 -25
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/index.ts +0 -1
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +336 -259
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +85 -26
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +636 -98
- package/test/unit/spec/breakouts/utils.js +19 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +8 -1
- package/test/unit/spec/controls-options-manager/util.js +576 -397
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +195 -1
- package/test/unit/spec/locus-info/index.js +950 -45
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
- package/test/unit/spec/locus-info/parser.js +62 -22
- package/test/unit/spec/locus-info/selfConstant.js +19 -0
- package/test/unit/spec/locus-info/selfUtils.js +131 -26
- package/test/unit/spec/media/index.ts +82 -79
- package/test/unit/spec/meeting/in-meeting-actions.ts +60 -2
- package/test/unit/spec/meeting/index.js +3208 -1734
- package/test/unit/spec/meeting/locusMediaRequest.ts +443 -0
- package/test/unit/spec/meeting/muteState.js +328 -417
- package/test/unit/spec/meeting/request.js +393 -48
- package/test/unit/spec/meeting/utils.js +552 -76
- package/test/unit/spec/meeting-info/index.js +181 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +258 -20
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/index.js +631 -145
- package/test/unit/spec/meetings/utils.js +164 -9
- package/test/unit/spec/member/index.js +44 -14
- package/test/unit/spec/member/util.js +296 -155
- package/test/unit/spec/members/index.js +23 -3
- package/test/unit/spec/members/request.js +167 -35
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +366 -8
- package/test/unit/spec/multistream/receiveSlot.ts +1 -1
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +123 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/index.ts +66 -5
- package/test/unit/spec/reachability/request.js +3 -1
- package/test/unit/spec/reconnection-manager/index.js +55 -5
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +21 -48
- package/test/unit/spec/roap/request.ts +74 -60
- package/test/unit/spec/roap/turnDiscovery.ts +30 -6
- package/test/unit/spec/rtcMetrics/index.ts +68 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -60
- package/src/metrics/config.ts +0 -487
package/src/roap/request.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/* global window */
|
|
2
1
|
// @ts-ignore
|
|
3
2
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
4
3
|
|
|
5
4
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {eventType} from '../metrics/config';
|
|
5
|
+
import {IP_VERSION, REACHABILITY} from '../constants';
|
|
6
|
+
import {LocusMediaRequest} from '../meeting/locusMediaRequest';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* @class RoapRequest
|
|
@@ -64,72 +62,64 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
64
62
|
* @param {String} options.locusSelfUrl
|
|
65
63
|
* @param {String} options.mediaId
|
|
66
64
|
* @param {String} options.correlationId
|
|
67
|
-
* @param {Boolean} options.audioMuted
|
|
68
|
-
* @param {Boolean} options.videoMuted
|
|
69
65
|
* @param {String} options.meetingId
|
|
70
|
-
* @param {Boolean} options.preferTranscoding
|
|
71
66
|
* @returns {Promise} returns the response/failure of the request
|
|
72
67
|
*/
|
|
73
68
|
async sendRoap(options: {
|
|
74
69
|
roapMessage: any;
|
|
75
70
|
locusSelfUrl: string;
|
|
76
71
|
mediaId: string;
|
|
77
|
-
correlationId: string;
|
|
78
|
-
audioMuted: boolean;
|
|
79
|
-
videoMuted: boolean;
|
|
80
72
|
meetingId: string;
|
|
81
|
-
|
|
73
|
+
ipVersion: IP_VERSION;
|
|
74
|
+
locusMediaRequest?: LocusMediaRequest;
|
|
82
75
|
}) {
|
|
83
|
-
const {roapMessage, locusSelfUrl, mediaId,
|
|
76
|
+
const {roapMessage, locusSelfUrl, mediaId, meetingId, locusMediaRequest, ipVersion} = options;
|
|
84
77
|
|
|
85
78
|
if (!mediaId) {
|
|
86
|
-
LoggerProxy.logger.info('Roap:request#sendRoap -->
|
|
79
|
+
LoggerProxy.logger.info('Roap:request#sendRoap --> sending empty mediaID');
|
|
87
80
|
}
|
|
88
81
|
|
|
82
|
+
if (!locusMediaRequest) {
|
|
83
|
+
LoggerProxy.logger.warn(
|
|
84
|
+
'Roap:request#sendRoap --> locusMediaRequest unavailable, not sending roap'
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return Promise.reject(new Error('sendRoap called when locusMediaRequest is undefined'));
|
|
88
|
+
}
|
|
89
89
|
const {localSdp: localSdpWithReachabilityData, joinCookie} = await this.attachReachabilityData({
|
|
90
90
|
roapMessage,
|
|
91
|
-
// eslint-disable-next-line no-warning-comments
|
|
92
|
-
// TODO: check whats the need for video and audiomute
|
|
93
|
-
audioMuted: !!options.audioMuted,
|
|
94
|
-
videoMuted: !!options.videoMuted,
|
|
95
91
|
});
|
|
96
92
|
|
|
97
|
-
const mediaUrl = `${locusSelfUrl}/${MEDIA}`;
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
const deviceUrl = this.webex.internal.device.url;
|
|
100
|
-
|
|
101
93
|
LoggerProxy.logger.info(
|
|
102
|
-
`Roap:request#sendRoap --> ${
|
|
94
|
+
`Roap:request#sendRoap --> ${locusSelfUrl} \n ${roapMessage.messageType} \n seq:${roapMessage.seq}`
|
|
103
95
|
);
|
|
104
96
|
|
|
105
|
-
Metrics.postEvent({event: eventType.MEDIA_REQUEST, meetingId});
|
|
106
|
-
|
|
107
97
|
// @ts-ignore
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
device: {
|
|
113
|
-
url: deviceUrl,
|
|
114
|
-
// @ts-ignore
|
|
115
|
-
deviceType: this.config.meetings.deviceType,
|
|
116
|
-
},
|
|
117
|
-
correlationId,
|
|
118
|
-
localMedias: [
|
|
119
|
-
{
|
|
120
|
-
localSdp: JSON.stringify(localSdpWithReachabilityData),
|
|
121
|
-
mediaId: options.mediaId,
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
clientMediaPreferences: {
|
|
125
|
-
preferTranscoding: options.preferTranscoding ?? true,
|
|
126
|
-
joinCookie,
|
|
127
|
-
},
|
|
98
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
99
|
+
name: 'client.locus.media.request',
|
|
100
|
+
options: {
|
|
101
|
+
meetingId,
|
|
128
102
|
},
|
|
129
|
-
})
|
|
130
|
-
.then((res) => {
|
|
131
|
-
Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meetingId});
|
|
103
|
+
});
|
|
132
104
|
|
|
105
|
+
return locusMediaRequest
|
|
106
|
+
.send({
|
|
107
|
+
type: 'RoapMessage',
|
|
108
|
+
selfUrl: locusSelfUrl,
|
|
109
|
+
joinCookie,
|
|
110
|
+
mediaId,
|
|
111
|
+
roapMessage,
|
|
112
|
+
reachability: localSdpWithReachabilityData.reachability,
|
|
113
|
+
ipVersion,
|
|
114
|
+
})
|
|
115
|
+
.then((res) => {
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
118
|
+
name: 'client.locus.media.response',
|
|
119
|
+
options: {
|
|
120
|
+
meetingId,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
133
123
|
// always it will be the first mediaConnection Object
|
|
134
124
|
const mediaConnections =
|
|
135
125
|
res.body.mediaConnections &&
|
|
@@ -153,10 +143,13 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
153
143
|
};
|
|
154
144
|
})
|
|
155
145
|
.catch((err) => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
148
|
+
name: 'client.locus.media.response',
|
|
149
|
+
options: {
|
|
150
|
+
meetingId,
|
|
151
|
+
rawError: err,
|
|
152
|
+
},
|
|
160
153
|
});
|
|
161
154
|
LoggerProxy.logger.error(`Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`);
|
|
162
155
|
LoggerProxy.logger.error(
|
|
@@ -176,15 +176,14 @@ export default class TurnDiscovery {
|
|
|
176
176
|
return this.roapRequest
|
|
177
177
|
.sendRoap({
|
|
178
178
|
roapMessage,
|
|
179
|
-
correlationId: meeting.correlationId,
|
|
180
179
|
// @ts-ignore - Fix missing type
|
|
181
180
|
locusSelfUrl: meeting.selfUrl,
|
|
182
181
|
// @ts-ignore - Fix missing type
|
|
183
182
|
mediaId: isReconnecting ? '' : meeting.mediaId,
|
|
184
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
185
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
186
183
|
meetingId: meeting.id,
|
|
187
|
-
|
|
184
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
185
|
+
// @ts-ignore - because of meeting.webex
|
|
186
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
188
187
|
})
|
|
189
188
|
.then(({mediaConnections}) => {
|
|
190
189
|
if (mediaConnections) {
|
|
@@ -213,14 +212,55 @@ export default class TurnDiscovery {
|
|
|
213
212
|
locusSelfUrl: meeting.selfUrl,
|
|
214
213
|
// @ts-ignore - fix type
|
|
215
214
|
mediaId: meeting.mediaId,
|
|
216
|
-
correlationId: meeting.correlationId,
|
|
217
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
218
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
219
215
|
meetingId: meeting.id,
|
|
220
|
-
|
|
216
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
217
|
+
// @ts-ignore - because of meeting.webex
|
|
218
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
221
219
|
});
|
|
222
220
|
}
|
|
223
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Gets the reason why reachability is skipped.
|
|
224
|
+
*
|
|
225
|
+
* @param {Meeting} meeting
|
|
226
|
+
* @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped
|
|
227
|
+
*/
|
|
228
|
+
private async getSkipReason(meeting: Meeting): Promise<string> {
|
|
229
|
+
// @ts-ignore - fix type
|
|
230
|
+
const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();
|
|
231
|
+
|
|
232
|
+
if (isAnyClusterReachable) {
|
|
233
|
+
LoggerProxy.logger.info(
|
|
234
|
+
'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
return 'reachability';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// @ts-ignore - fix type
|
|
241
|
+
if (!meeting.config.experimental.enableTurnDiscovery) {
|
|
242
|
+
LoggerProxy.logger.info(
|
|
243
|
+
'Roap:turnDiscovery#getSkipReason --> TURN discovery disabled in config, skipping it'
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
return 'config';
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return '';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Checks if TURN discovery is skipped.
|
|
254
|
+
*
|
|
255
|
+
* @param {Meeting} meeting
|
|
256
|
+
* @returns {Boolean} true if TURN discovery is being skipped, false if it is being done
|
|
257
|
+
*/
|
|
258
|
+
async isSkipped(meeting) {
|
|
259
|
+
const skipReason = await this.getSkipReason(meeting);
|
|
260
|
+
|
|
261
|
+
return !!skipReason;
|
|
262
|
+
}
|
|
263
|
+
|
|
224
264
|
/**
|
|
225
265
|
* Retrieves TURN server information from the backend by doing
|
|
226
266
|
* a roap message exchange:
|
|
@@ -239,29 +279,15 @@ export default class TurnDiscovery {
|
|
|
239
279
|
* @returns {Promise}
|
|
240
280
|
*/
|
|
241
281
|
async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {
|
|
242
|
-
|
|
243
|
-
const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();
|
|
244
|
-
|
|
245
|
-
if (isAnyClusterReachable) {
|
|
246
|
-
LoggerProxy.logger.info(
|
|
247
|
-
'Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery'
|
|
248
|
-
);
|
|
282
|
+
const turnDiscoverySkippedReason = await this.getSkipReason(meeting);
|
|
249
283
|
|
|
284
|
+
if (turnDiscoverySkippedReason) {
|
|
250
285
|
return {
|
|
251
286
|
turnServerInfo: undefined,
|
|
252
|
-
turnDiscoverySkippedReason
|
|
287
|
+
turnDiscoverySkippedReason,
|
|
253
288
|
};
|
|
254
289
|
}
|
|
255
290
|
|
|
256
|
-
// @ts-ignore - fix type
|
|
257
|
-
if (!meeting.config.experimental.enableTurnDiscovery) {
|
|
258
|
-
LoggerProxy.logger.info(
|
|
259
|
-
'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it'
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
return {turnServerInfo: undefined, turnDiscoverySkippedReason: 'config'};
|
|
263
|
-
}
|
|
264
|
-
|
|
265
291
|
return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)
|
|
266
292
|
.then(() => this.waitForTurnDiscoveryResponse())
|
|
267
293
|
.then(() => this.sendRoapOK(meeting))
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import RTC_METRICS from './constants';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rtc Metrics
|
|
5
|
+
*/
|
|
6
|
+
export default class RtcMetrics {
|
|
7
|
+
/**
|
|
8
|
+
* Array of MetricData items to be sent to the metrics service.
|
|
9
|
+
*/
|
|
10
|
+
metricsQueue = [];
|
|
11
|
+
|
|
12
|
+
intervalId: number;
|
|
13
|
+
|
|
14
|
+
webex: any;
|
|
15
|
+
|
|
16
|
+
meetingId: string;
|
|
17
|
+
|
|
18
|
+
correlationId: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the interval.
|
|
22
|
+
*
|
|
23
|
+
* @param {object} webex - The main `webex` object.
|
|
24
|
+
* @param {string} meetingId - The meeting id.
|
|
25
|
+
* @param {string} correlationId - The correlation id.
|
|
26
|
+
*/
|
|
27
|
+
constructor(webex, meetingId, correlationId) {
|
|
28
|
+
// `window` is used to prevent typescript from returning a NodeJS.Timer.
|
|
29
|
+
this.intervalId = window.setInterval(this.checkMetrics.bind(this), 30 * 1000);
|
|
30
|
+
this.meetingId = meetingId;
|
|
31
|
+
this.webex = webex;
|
|
32
|
+
this.correlationId = correlationId;
|
|
33
|
+
// Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.
|
|
34
|
+
setTimeout(this.checkMetrics.bind(this), 5 * 1000);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Check to see if the metrics queue has any items.
|
|
39
|
+
*
|
|
40
|
+
* @returns {void}
|
|
41
|
+
*/
|
|
42
|
+
private checkMetrics() {
|
|
43
|
+
if (this.metricsQueue.length) {
|
|
44
|
+
this.sendMetrics();
|
|
45
|
+
this.metricsQueue = [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Add metrics items to the metrics queue.
|
|
51
|
+
*
|
|
52
|
+
* @param {object} data - An object with a payload array of metrics items.
|
|
53
|
+
*
|
|
54
|
+
* @returns {void}
|
|
55
|
+
*/
|
|
56
|
+
addMetrics(data) {
|
|
57
|
+
if (data.payload.length) {
|
|
58
|
+
this.metricsQueue.push(data);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Clear the metrics interval.
|
|
64
|
+
*
|
|
65
|
+
* @returns {void}
|
|
66
|
+
*/
|
|
67
|
+
closeMetrics() {
|
|
68
|
+
this.checkMetrics();
|
|
69
|
+
clearInterval(this.intervalId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Send metrics to the metrics service.
|
|
74
|
+
*
|
|
75
|
+
* @returns {void}
|
|
76
|
+
*/
|
|
77
|
+
private sendMetrics() {
|
|
78
|
+
this.webex.request({
|
|
79
|
+
method: 'POST',
|
|
80
|
+
service: 'unifiedTelemetry',
|
|
81
|
+
resource: 'metric/v2',
|
|
82
|
+
headers: {
|
|
83
|
+
type: 'webrtcMedia',
|
|
84
|
+
appId: RTC_METRICS.APP_ID,
|
|
85
|
+
},
|
|
86
|
+
body: {
|
|
87
|
+
metrics: [
|
|
88
|
+
{
|
|
89
|
+
type: 'webrtc',
|
|
90
|
+
version: '1.0.1',
|
|
91
|
+
userId: this.webex.internal.device.userId,
|
|
92
|
+
meetingId: this.meetingId,
|
|
93
|
+
correlationId: this.correlationId,
|
|
94
|
+
data: this.metricsQueue,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -3,13 +3,30 @@ import 'jsdom-global/register';
|
|
|
3
3
|
import {assert} from '@webex/test-helper-chai';
|
|
4
4
|
import {skipInNode} from '@webex/test-helper-mocha';
|
|
5
5
|
import BrowserDetection from '@webex/plugin-meetings/dist/common/browser-detection';
|
|
6
|
+
import {createCameraTrack, createMicrophoneTrack} from '@webex/plugin-meetings';
|
|
6
7
|
|
|
7
8
|
import {MEDIA_SERVERS} from '../../utils/constants';
|
|
8
9
|
import testUtils from '../../utils/testUtils';
|
|
10
|
+
import integrationTestUtils from '../../utils/integrationTestUtils';
|
|
9
11
|
import webexTestUsers from '../../utils/webex-test-users';
|
|
10
12
|
|
|
11
13
|
config();
|
|
12
14
|
|
|
15
|
+
const localTracks = {
|
|
16
|
+
alice: {
|
|
17
|
+
microphone: undefined,
|
|
18
|
+
camera: undefined,
|
|
19
|
+
},
|
|
20
|
+
bob: {
|
|
21
|
+
microphone: undefined,
|
|
22
|
+
camera: undefined,
|
|
23
|
+
},
|
|
24
|
+
chris: {
|
|
25
|
+
microphone: undefined,
|
|
26
|
+
camera: undefined,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
13
30
|
skipInNode(describe)('plugin-meetings', () => {
|
|
14
31
|
const {isBrowser} = BrowserDetection();
|
|
15
32
|
|
|
@@ -135,6 +152,17 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
135
152
|
assert.exists(chris.meeting.joinedWith);
|
|
136
153
|
});
|
|
137
154
|
|
|
155
|
+
it('users "alice", "bob", and "chris" create local tracks', async () => {
|
|
156
|
+
localTracks.alice.microphone = await createMicrophoneTrack();
|
|
157
|
+
localTracks.alice.camera = await createCameraTrack();
|
|
158
|
+
|
|
159
|
+
localTracks.bob.microphone = await createMicrophoneTrack();
|
|
160
|
+
localTracks.bob.camera = await createCameraTrack();
|
|
161
|
+
|
|
162
|
+
localTracks.chris.microphone = await createMicrophoneTrack();
|
|
163
|
+
localTracks.chris.camera = await createCameraTrack();
|
|
164
|
+
});
|
|
165
|
+
|
|
138
166
|
it('users "alice", "bob", and "chris" add media', async () => {
|
|
139
167
|
mediaReadyListener = testUtils.waitForEvents([
|
|
140
168
|
{scope: alice.meeting, event: 'media:negotiated'},
|
|
@@ -142,9 +170,9 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
142
170
|
{scope: chris.meeting, event: 'media:negotiated'},
|
|
143
171
|
]);
|
|
144
172
|
|
|
145
|
-
const addMediaAlice =
|
|
146
|
-
const addMediaBob =
|
|
147
|
-
const addMediaChris =
|
|
173
|
+
const addMediaAlice = integrationTestUtils.addMedia(alice, {multistream: true, microphone: localTracks.alice.microphone, camera: localTracks.alice.camera});
|
|
174
|
+
const addMediaBob = integrationTestUtils.addMedia(bob, {multistream: true, microphone: localTracks.bob.microphone, camera: localTracks.bob.camera});
|
|
175
|
+
const addMediaChris = integrationTestUtils.addMedia(chris, {multistream: true, microphone: localTracks.chris.microphone, camera: localTracks.chris.camera});
|
|
148
176
|
|
|
149
177
|
await addMediaAlice;
|
|
150
178
|
await addMediaBob;
|
|
@@ -171,6 +199,35 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
171
199
|
assert.equal(bob.meeting.mediaProperties.webrtcMediaConnection.mediaServer, MEDIA_SERVERS.HOMER);
|
|
172
200
|
assert.equal(chris.meeting.mediaProperties.webrtcMediaConnection.mediaServer, MEDIA_SERVERS.HOMER);
|
|
173
201
|
});
|
|
202
|
+
|
|
203
|
+
it('users "alice", "bob", and "chris" stop their local tracks', () => {
|
|
204
|
+
if (localTracks.alice.microphone) {
|
|
205
|
+
localTracks.alice.microphone.stop();
|
|
206
|
+
localTracks.alice.microphone = undefined;
|
|
207
|
+
}
|
|
208
|
+
if (localTracks.alice.camera) {
|
|
209
|
+
localTracks.alice.camera.stop();
|
|
210
|
+
localTracks.alice.camera = undefined;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (localTracks.bob.microphone) {
|
|
214
|
+
localTracks.bob.microphone.stop();
|
|
215
|
+
localTracks.bob.microphone = undefined;
|
|
216
|
+
}
|
|
217
|
+
if (localTracks.bob.camera) {
|
|
218
|
+
localTracks.bob.camera.stop();
|
|
219
|
+
localTracks.bob.camera = undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (localTracks.chris.microphone) {
|
|
223
|
+
localTracks.chris.microphone.stop();
|
|
224
|
+
localTracks.chris.microphone = undefined;
|
|
225
|
+
}
|
|
226
|
+
if (localTracks.chris.camera) {
|
|
227
|
+
localTracks.chris.camera.stop();
|
|
228
|
+
localTracks.chris.camera = undefined;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
174
231
|
});
|
|
175
232
|
}
|
|
176
233
|
});
|