@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
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SendSlot,
|
|
3
|
+
MediaType,
|
|
4
|
+
LocalStream,
|
|
5
|
+
MultistreamRoapMediaConnection,
|
|
6
|
+
} from '@webex/internal-media-core';
|
|
7
|
+
|
|
8
|
+
export default class SendSlotManager {
|
|
9
|
+
private readonly slots: Map<MediaType, SendSlot> = new Map();
|
|
10
|
+
private readonly LoggerProxy: any;
|
|
11
|
+
|
|
12
|
+
constructor(LoggerProxy: any) {
|
|
13
|
+
this.LoggerProxy = LoggerProxy;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* This method is used to create a sendSlot for the given mediaType and returns the created sendSlot
|
|
18
|
+
* @param {MultistreamRoapMediaConnection} mediaConnection MultistreamRoapMediaConnection for which a sendSlot needs to be created
|
|
19
|
+
* @param {MediaType} mediaType MediaType for which a sendSlot needs to be created (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
20
|
+
* @param {boolean} active This is optional boolean to set the active state of the sendSlot. Default is true
|
|
21
|
+
* @returns {SendSlot} slot The created sendSlot
|
|
22
|
+
*/
|
|
23
|
+
public createSlot(
|
|
24
|
+
mediaConnection: MultistreamRoapMediaConnection,
|
|
25
|
+
mediaType: MediaType,
|
|
26
|
+
active = true
|
|
27
|
+
): SendSlot {
|
|
28
|
+
if (this.slots.has(mediaType)) {
|
|
29
|
+
throw new Error(`Slot for ${mediaType} already exists`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const slot: SendSlot = mediaConnection.createSendSlot(mediaType, active);
|
|
33
|
+
|
|
34
|
+
this.slots.set(mediaType, slot);
|
|
35
|
+
|
|
36
|
+
this.LoggerProxy.logger.info(
|
|
37
|
+
`SendSlotsManager->createSlot#Created slot for ${mediaType} with active ${active}`
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return slot;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* This method is used to retrieve the sendSlot for the given mediaType
|
|
45
|
+
* @param {MediaType} mediaType of which the slot needs to be retrieved
|
|
46
|
+
* @returns {SendSlot}
|
|
47
|
+
*/
|
|
48
|
+
public getSlot(mediaType: MediaType): SendSlot {
|
|
49
|
+
const slot = this.slots.get(mediaType);
|
|
50
|
+
|
|
51
|
+
if (!slot) {
|
|
52
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return slot;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* This method publishes the given stream to the sendSlot for the given mediaType
|
|
60
|
+
* @param {MediaType} mediaType MediaType of the sendSlot to which a stream needs to be published (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
61
|
+
* @param {LocalStream} stream LocalStream to be published
|
|
62
|
+
* @returns {Promise<void>}
|
|
63
|
+
*/
|
|
64
|
+
public async publishStream(mediaType: MediaType, stream: LocalStream): Promise<void> {
|
|
65
|
+
const slot = this.slots.get(mediaType);
|
|
66
|
+
|
|
67
|
+
if (!slot) {
|
|
68
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await slot.publishStream(stream);
|
|
72
|
+
|
|
73
|
+
this.LoggerProxy.logger.info(
|
|
74
|
+
`SendSlotsManager->publishStream#Published stream for ${mediaType} and stream with label ${stream.label} and muted ${stream.muted}`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* This method unpublishes the stream from the sendSlot of the given mediaType
|
|
80
|
+
* @param {MediaType} mediaType MediaType of the sendSlot from which a stream needs to be unpublished (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
81
|
+
* @returns {Promise<void>}
|
|
82
|
+
*/
|
|
83
|
+
public async unpublishStream(mediaType: MediaType): Promise<void> {
|
|
84
|
+
const slot = this.slots.get(mediaType);
|
|
85
|
+
|
|
86
|
+
if (!slot) {
|
|
87
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await slot.unpublishStream();
|
|
91
|
+
|
|
92
|
+
this.LoggerProxy.logger.info(
|
|
93
|
+
`SendSlotsManager->unpublishStream#Unpublished stream for ${mediaType}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* This method is used to set the active state of the sendSlot for the given mediaType
|
|
99
|
+
* @param {MediaType} mediaType The MediaType of the sendSlot for which the active state needs to be set (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
100
|
+
* @param {boolean} active The boolean to set the active state of the sendSlot. Default is true
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
public setActive(mediaType: MediaType, active = true): void {
|
|
104
|
+
const slot = this.slots.get(mediaType);
|
|
105
|
+
|
|
106
|
+
if (!slot) {
|
|
107
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
slot.active = active;
|
|
111
|
+
|
|
112
|
+
this.LoggerProxy.logger.info(
|
|
113
|
+
`SendSlotsManager->setActive#Set active for ${mediaType} to ${active}`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* This method is used to set the codec parameters for the sendSlot of the given mediaType
|
|
119
|
+
* @param {MediaType} mediaType MediaType of the sendSlot for which the codec parameters needs to be set (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
120
|
+
* @param {Object} codecParameters
|
|
121
|
+
* @returns {Promise<void>}
|
|
122
|
+
*/
|
|
123
|
+
public async setCodecParameters(
|
|
124
|
+
mediaType: MediaType,
|
|
125
|
+
codecParameters: {
|
|
126
|
+
[key: string]: string | undefined; // As per ts-sdp undefined is considered as a valid value to be used for codec parameters
|
|
127
|
+
}
|
|
128
|
+
): Promise<void> {
|
|
129
|
+
// These codec parameter changes underneath are SDP value changes that are taken care by WCME automatically. So no need for any change in streams from the web sdk side
|
|
130
|
+
const slot = this.slots.get(mediaType);
|
|
131
|
+
|
|
132
|
+
if (!slot) {
|
|
133
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
await slot.setCodecParameters(codecParameters);
|
|
137
|
+
|
|
138
|
+
this.LoggerProxy.logger.info(
|
|
139
|
+
`SendSlotsManager->setCodecParameters#Set codec parameters for ${mediaType} to ${codecParameters}`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* This method is used to delete the codec parameters for the sendSlot of the given mediaType
|
|
145
|
+
* @param {MediaType} mediaType MediaType of the sendSlot for which the codec parameters needs to be deleted (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
|
146
|
+
* @param {Array<String>} parameters Array of keys of the codec parameters to be deleted
|
|
147
|
+
* @returns {Promise<void>}
|
|
148
|
+
*/
|
|
149
|
+
public async deleteCodecParameters(mediaType: MediaType, parameters: string[]): Promise<void> {
|
|
150
|
+
const slot = this.slots.get(mediaType);
|
|
151
|
+
|
|
152
|
+
if (!slot) {
|
|
153
|
+
throw new Error(`Slot for ${mediaType} does not exist`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await slot.deleteCodecParameters(parameters);
|
|
157
|
+
|
|
158
|
+
this.LoggerProxy.logger.info(
|
|
159
|
+
`SendSlotsManager->deleteCodecParameters#Deleted the following codec parameters -> ${parameters} for ${mediaType}`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* This method is used to reset the SendSlotsManager by deleting all the sendSlots
|
|
165
|
+
* @returns {undefined}
|
|
166
|
+
*/
|
|
167
|
+
public reset(): void {
|
|
168
|
+
this.slots.clear();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import _ from 'lodash';
|
|
8
8
|
|
|
9
9
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
10
|
-
import {ICE_GATHERING_STATE, CONNECTION_STATE, REACHABILITY} from '../constants';
|
|
10
|
+
import {ICE_GATHERING_STATE, CONNECTION_STATE, REACHABILITY, IP_VERSION} from '../constants';
|
|
11
11
|
|
|
12
12
|
import ReachabilityRequest from './request';
|
|
13
13
|
|
|
@@ -70,7 +70,9 @@ export default class Reachability {
|
|
|
70
70
|
|
|
71
71
|
// Fetch clusters and measure latency
|
|
72
72
|
try {
|
|
73
|
-
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
|
|
73
|
+
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
|
|
74
|
+
this.getIpVersion()
|
|
75
|
+
);
|
|
74
76
|
|
|
75
77
|
// Perform Reachability Check
|
|
76
78
|
const results = await this.performReachabilityCheck(clusters);
|
|
@@ -132,6 +134,14 @@ export default class Reachability {
|
|
|
132
134
|
return reachable;
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Returns what we know about the IP version of the networks we're connected to.
|
|
139
|
+
* @returns {IP_VERSION}
|
|
140
|
+
*/
|
|
141
|
+
getIpVersion(): IP_VERSION {
|
|
142
|
+
return IP_VERSION.unknown;
|
|
143
|
+
}
|
|
144
|
+
|
|
135
145
|
/**
|
|
136
146
|
* Generate peerConnection config settings
|
|
137
147
|
* @param {object} cluster
|
|
@@ -140,7 +150,7 @@ export default class Reachability {
|
|
|
140
150
|
* @memberof Reachability
|
|
141
151
|
*/
|
|
142
152
|
private buildPeerConnectionConfig(cluster: any) {
|
|
143
|
-
const iceServers = _.uniq(
|
|
153
|
+
const iceServers = _.uniq(cluster.udp).map((url) => ({
|
|
144
154
|
username: '',
|
|
145
155
|
credential: '',
|
|
146
156
|
urls: [url],
|
|
@@ -411,7 +421,8 @@ export default class Reachability {
|
|
|
411
421
|
|
|
412
422
|
reachabilityMap[clusterId] = {
|
|
413
423
|
udp: latencyResult,
|
|
414
|
-
tcp:
|
|
424
|
+
tcp: {untested: 'true'},
|
|
425
|
+
xtls: {untested: 'true'},
|
|
415
426
|
};
|
|
416
427
|
});
|
|
417
428
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
2
|
-
import {HTTP_VERBS, RESOURCE, API} from '../constants';
|
|
2
|
+
import {HTTP_VERBS, RESOURCE, API, IP_VERSION} from '../constants';
|
|
3
3
|
|
|
4
4
|
export interface ClusterNode {
|
|
5
5
|
isVideoMesh: boolean;
|
|
@@ -30,9 +30,10 @@ class ReachabilityRequest {
|
|
|
30
30
|
/**
|
|
31
31
|
* Gets the cluster information
|
|
32
32
|
*
|
|
33
|
+
* @param {IP_VERSION} ipVersion information about current ip network we're on
|
|
33
34
|
* @returns {Promise}
|
|
34
35
|
*/
|
|
35
|
-
getClusters = (): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
36
|
+
getClusters = (ipVersion: IP_VERSION): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
36
37
|
this.webex
|
|
37
38
|
.request({
|
|
38
39
|
method: HTTP_VERBS.GET,
|
|
@@ -41,6 +42,7 @@ class ReachabilityRequest {
|
|
|
41
42
|
resource: RESOURCE.CLUSTERS,
|
|
42
43
|
qs: {
|
|
43
44
|
JCSupport: 1,
|
|
45
|
+
ipver: ipVersion,
|
|
44
46
|
},
|
|
45
47
|
})
|
|
46
48
|
.then((res) => {
|
|
@@ -51,7 +53,9 @@ class ReachabilityRequest {
|
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
LoggerProxy.logger.log(
|
|
54
|
-
`Reachability:request#getClusters --> get clusters successful:${JSON.stringify(
|
|
56
|
+
`Reachability:request#getClusters --> get clusters (ipver=${ipVersion}) successful:${JSON.stringify(
|
|
57
|
+
clusters
|
|
58
|
+
)}`
|
|
55
59
|
);
|
|
56
60
|
|
|
57
61
|
return {
|
|
@@ -18,8 +18,6 @@ import {
|
|
|
18
18
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
19
19
|
import ReconnectionError from '../common/errors/reconnection';
|
|
20
20
|
import ReconnectInProgress from '../common/errors/reconnection-in-progress';
|
|
21
|
-
import {eventType, reconnection, errorObjects} from '../metrics/config';
|
|
22
|
-
import Media from '../media';
|
|
23
21
|
import Metrics from '../metrics';
|
|
24
22
|
import Meeting from '../meeting';
|
|
25
23
|
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
@@ -233,25 +231,23 @@ export default class ReconnectionManager {
|
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
/**
|
|
236
|
-
* Stop the local share
|
|
234
|
+
* Stop the local share stream.
|
|
237
235
|
*
|
|
238
236
|
* @param {string} reason a {@link SHARE_STOPPED_REASON}
|
|
239
237
|
* @returns {undefined}
|
|
240
238
|
* @private
|
|
241
239
|
* @memberof ReconnectionManager
|
|
242
240
|
*/
|
|
243
|
-
private
|
|
244
|
-
this.meeting.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
this.meeting.mediaProperties.mediaDirection.sendShare = false;
|
|
241
|
+
private async stopLocalShareStream(reason: string) {
|
|
242
|
+
await this.meeting.unpublishStreams([
|
|
243
|
+
this.meeting.mediaProperties.shareVideoStream,
|
|
244
|
+
this.meeting.mediaProperties.shareAudioStream,
|
|
245
|
+
]);
|
|
250
246
|
Trigger.trigger(
|
|
251
247
|
this.meeting,
|
|
252
248
|
{
|
|
253
249
|
file: 'reconnection-manager/index',
|
|
254
|
-
function: '
|
|
250
|
+
function: 'stopLocalShareStream',
|
|
255
251
|
},
|
|
256
252
|
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
|
|
257
253
|
{
|
|
@@ -331,9 +327,13 @@ export default class ReconnectionManager {
|
|
|
331
327
|
LoggerProxy.logger.info(
|
|
332
328
|
'ReconnectionManager:index#reconnect --> Sending reconnect start metric.'
|
|
333
329
|
);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
330
|
+
|
|
331
|
+
// @ts-ignore
|
|
332
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
333
|
+
name: 'client.media.reconnecting',
|
|
334
|
+
options: {
|
|
335
|
+
meetingId: this.meeting.id,
|
|
336
|
+
},
|
|
337
337
|
});
|
|
338
338
|
}
|
|
339
339
|
|
|
@@ -343,10 +343,16 @@ export default class ReconnectionManager {
|
|
|
343
343
|
LoggerProxy.logger.info(
|
|
344
344
|
'ReconnectionManager:index#reconnect --> Sending reconnect success metric.'
|
|
345
345
|
);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
346
|
+
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
349
|
+
name: 'client.media.recovered',
|
|
350
|
+
payload: {
|
|
351
|
+
recoveredBy: 'new',
|
|
352
|
+
},
|
|
353
|
+
options: {
|
|
354
|
+
meetingId: this.meeting.id,
|
|
355
|
+
},
|
|
350
356
|
});
|
|
351
357
|
})
|
|
352
358
|
.catch((reconnectError) => {
|
|
@@ -370,23 +376,24 @@ export default class ReconnectionManager {
|
|
|
370
376
|
'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
|
|
371
377
|
);
|
|
372
378
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
379
|
+
// @ts-ignore
|
|
380
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
381
|
+
name: 'client.call.aborted',
|
|
382
|
+
payload: {
|
|
377
383
|
errors: [
|
|
378
384
|
{
|
|
379
|
-
category:
|
|
385
|
+
category: 'expected',
|
|
380
386
|
errorCode: 2008,
|
|
381
387
|
fatal: true,
|
|
382
|
-
name:
|
|
388
|
+
name: 'media-engine',
|
|
383
389
|
shownToUser: false,
|
|
384
390
|
},
|
|
385
391
|
],
|
|
386
392
|
},
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
393
|
+
options: {
|
|
394
|
+
meetingId: this.meeting.id,
|
|
395
|
+
},
|
|
396
|
+
});
|
|
390
397
|
if (reconnectError instanceof NeedsRejoinError) {
|
|
391
398
|
// send call aborded event with catogery as expected as we are trying to rejoin
|
|
392
399
|
|
|
@@ -417,7 +424,7 @@ export default class ReconnectionManager {
|
|
|
417
424
|
const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
|
|
418
425
|
|
|
419
426
|
if (wasSharing) {
|
|
420
|
-
this.
|
|
427
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEDIA_RECONNECTION);
|
|
421
428
|
}
|
|
422
429
|
|
|
423
430
|
if (networkDisconnect) {
|
|
@@ -508,7 +515,7 @@ export default class ReconnectionManager {
|
|
|
508
515
|
LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
|
|
509
516
|
|
|
510
517
|
if (wasSharing) {
|
|
511
|
-
this.
|
|
518
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEETING_REJOIN);
|
|
512
519
|
}
|
|
513
520
|
} catch (joinError) {
|
|
514
521
|
this.rejoinAttempts += 1;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import PermissionError from '../common/errors/permission';
|
|
2
|
-
import {CONTROLS, HTTP_VERBS} from '../constants';
|
|
2
|
+
import {CONTROLS, HTTP_VERBS, SELF_POLICY} from '../constants';
|
|
3
3
|
import MeetingRequest from '../meeting/request';
|
|
4
4
|
import RecordingAction from './enums';
|
|
5
5
|
import Util from './util';
|
|
@@ -28,6 +28,14 @@ export default class RecordingController {
|
|
|
28
28
|
*/
|
|
29
29
|
private displayHints: Array<string> = [];
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @instance
|
|
33
|
+
* @type {Object}
|
|
34
|
+
* @private
|
|
35
|
+
* @memberof RecordingInfo
|
|
36
|
+
*/
|
|
37
|
+
private selfUserPolicies: Record<SELF_POLICY, boolean>;
|
|
38
|
+
|
|
31
39
|
/**
|
|
32
40
|
* @instance
|
|
33
41
|
* @type {string}
|
|
@@ -81,7 +89,6 @@ export default class RecordingController {
|
|
|
81
89
|
|
|
82
90
|
/**
|
|
83
91
|
* @param {MeetingRequest} request
|
|
84
|
-
* @param {LocusInfo} info
|
|
85
92
|
* @returns {void}
|
|
86
93
|
* @private
|
|
87
94
|
* @memberof RecordingController
|
|
@@ -126,6 +133,16 @@ export default class RecordingController {
|
|
|
126
133
|
this.displayHints = hints;
|
|
127
134
|
}
|
|
128
135
|
|
|
136
|
+
/**
|
|
137
|
+
* @param {Object} selfUserPolicies
|
|
138
|
+
* @returns {void}
|
|
139
|
+
* @public
|
|
140
|
+
* @memberof RecordingController
|
|
141
|
+
*/
|
|
142
|
+
public setUserPolicy(selfUserPolicies: Record<SELF_POLICY, boolean>) {
|
|
143
|
+
this.selfUserPolicies = selfUserPolicies;
|
|
144
|
+
}
|
|
145
|
+
|
|
129
146
|
/**
|
|
130
147
|
* @param {string} id
|
|
131
148
|
* @returns {void}
|
|
@@ -264,7 +281,7 @@ export default class RecordingController {
|
|
|
264
281
|
);
|
|
265
282
|
|
|
266
283
|
// assumes action is proper cased (i.e., Example)
|
|
267
|
-
if (Util?.[`canUser${action}`](this.displayHints)) {
|
|
284
|
+
if (Util?.[`canUser${action}`](this.displayHints, this.selfUserPolicies)) {
|
|
268
285
|
if (this.serviceUrl) {
|
|
269
286
|
return this.recordingService(action);
|
|
270
287
|
}
|
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
import {DISPLAY_HINTS} from '../constants';
|
|
1
|
+
import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
|
|
2
2
|
import RecordingAction from './enums';
|
|
3
|
+
import MeetingUtil from '../meeting/util';
|
|
3
4
|
|
|
4
|
-
const canUserStart = (
|
|
5
|
-
displayHints
|
|
5
|
+
const canUserStart = (
|
|
6
|
+
displayHints: Array<string>,
|
|
7
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
8
|
+
): boolean =>
|
|
9
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) &&
|
|
10
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
6
11
|
|
|
7
|
-
const canUserPause = (
|
|
8
|
-
displayHints
|
|
12
|
+
const canUserPause = (
|
|
13
|
+
displayHints: Array<string>,
|
|
14
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
15
|
+
): boolean =>
|
|
16
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) &&
|
|
17
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
9
18
|
|
|
10
|
-
const canUserResume = (
|
|
11
|
-
displayHints
|
|
19
|
+
const canUserResume = (
|
|
20
|
+
displayHints: Array<string>,
|
|
21
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
22
|
+
): boolean =>
|
|
23
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) &&
|
|
24
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
12
25
|
|
|
13
|
-
const canUserStop = (
|
|
14
|
-
displayHints
|
|
26
|
+
const canUserStop = (
|
|
27
|
+
displayHints: Array<string>,
|
|
28
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
29
|
+
): boolean =>
|
|
30
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) &&
|
|
31
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
15
32
|
|
|
16
33
|
const extractLocusId = (url: string) => {
|
|
17
34
|
return url?.split('/').pop();
|
package/src/roap/index.ts
CHANGED
|
@@ -98,11 +98,9 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
98
98
|
roapMessage,
|
|
99
99
|
locusSelfUrl: meeting.selfUrl,
|
|
100
100
|
mediaId: options.mediaId,
|
|
101
|
-
correlationId: options.correlationId,
|
|
102
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
103
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
104
101
|
meetingId: meeting.id,
|
|
105
|
-
|
|
102
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
103
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
106
104
|
})
|
|
107
105
|
.then(() => {
|
|
108
106
|
LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);
|
|
@@ -135,11 +133,9 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
135
133
|
roapMessage,
|
|
136
134
|
locusSelfUrl: meeting.selfUrl,
|
|
137
135
|
mediaId: options.mediaId,
|
|
138
|
-
correlationId: options.correlationId,
|
|
139
|
-
audioMuted: meeting.isAudioMuted(),
|
|
140
|
-
videoMuted: meeting.isVideoMuted(),
|
|
141
136
|
meetingId: meeting.id,
|
|
142
|
-
|
|
137
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
138
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
143
139
|
});
|
|
144
140
|
}
|
|
145
141
|
|
|
@@ -167,11 +163,9 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
167
163
|
roapMessage,
|
|
168
164
|
locusSelfUrl: meeting.selfUrl,
|
|
169
165
|
mediaId: options.mediaId,
|
|
170
|
-
correlationId: options.correlationId,
|
|
171
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
172
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
173
166
|
meetingId: meeting.id,
|
|
174
|
-
|
|
167
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
168
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
175
169
|
})
|
|
176
170
|
.then(() => {
|
|
177
171
|
LoggerProxy.logger.log(
|
|
@@ -199,26 +193,27 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
199
193
|
// When reconnecting, it's important that the first roap message being sent out has empty media id.
|
|
200
194
|
// Normally this is the roap offer, but when TURN discovery is enabled,
|
|
201
195
|
// then this is the TURN discovery request message
|
|
202
|
-
|
|
196
|
+
return this.turnDiscovery.isSkipped(meeting).then((isTurnDiscoverySkipped) => {
|
|
197
|
+
const sendEmptyMediaId = reconnect && isTurnDiscoverySkipped;
|
|
203
198
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
199
|
+
return this.roapRequest
|
|
200
|
+
.sendRoap({
|
|
201
|
+
roapMessage,
|
|
202
|
+
locusSelfUrl: meeting.selfUrl,
|
|
203
|
+
mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
|
|
204
|
+
meetingId: meeting.id,
|
|
205
|
+
preferTranscoding: !meeting.isMultistream,
|
|
206
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
207
|
+
ipVersion: meeting.webex.meetings.reachability.getIpVersion(),
|
|
208
|
+
})
|
|
209
|
+
.then(({locus, mediaConnections}) => {
|
|
210
|
+
if (mediaConnections) {
|
|
211
|
+
meeting.updateMediaConnections(mediaConnections);
|
|
212
|
+
}
|
|
219
213
|
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
return locus;
|
|
215
|
+
});
|
|
216
|
+
});
|
|
222
217
|
}
|
|
223
218
|
|
|
224
219
|
/**
|