@webex/plugin-meetings 3.8.1-next.10 → 3.8.1-next.12
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/index.js +2 -2
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/index.js +62 -47
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/meeting/index.d.ts +7 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +6 -6
- package/src/media/index.ts +2 -2
- package/src/meeting/index.ts +25 -4
- package/test/unit/spec/media/index.ts +107 -0
- package/test/unit/spec/meeting/index.js +69 -1
@@ -66,6 +66,13 @@ export type AddMediaOptions = {
|
|
66
66
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration;
|
67
67
|
bundlePolicy?: BundlePolicy;
|
68
68
|
allowMediaInLobby?: boolean;
|
69
|
+
additionalMediaOptions?: AdditionalMediaOptions;
|
70
|
+
};
|
71
|
+
export type AdditionalMediaOptions = {
|
72
|
+
sendVideo?: boolean;
|
73
|
+
receiveVideo?: boolean;
|
74
|
+
sendAudio?: boolean;
|
75
|
+
receiveAudio?: boolean;
|
69
76
|
};
|
70
77
|
export type CallStateForMetrics = {
|
71
78
|
correlationId?: string;
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
@@ -43,7 +43,7 @@
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
46
|
-
"@webex/plugin-meetings": "3.8.1-next.
|
46
|
+
"@webex/plugin-meetings": "3.8.1-next.12",
|
47
47
|
"@webex/plugin-rooms": "3.8.1-next.2",
|
48
48
|
"@webex/test-helper-chai": "3.8.1-next.5",
|
49
49
|
"@webex/test-helper-mocha": "3.8.1-next.5",
|
@@ -63,7 +63,7 @@
|
|
63
63
|
"dependencies": {
|
64
64
|
"@webex/common": "3.8.1-next.5",
|
65
65
|
"@webex/event-dictionary-ts": "^1.0.1819",
|
66
|
-
"@webex/internal-media-core": "2.18.
|
66
|
+
"@webex/internal-media-core": "2.18.3",
|
67
67
|
"@webex/internal-plugin-conversation": "3.8.1-next.5",
|
68
68
|
"@webex/internal-plugin-device": "3.8.1-next.5",
|
69
69
|
"@webex/internal-plugin-llm": "3.8.1-next.5",
|
@@ -71,12 +71,12 @@
|
|
71
71
|
"@webex/internal-plugin-metrics": "3.8.1-next.5",
|
72
72
|
"@webex/internal-plugin-support": "3.8.1-next.5",
|
73
73
|
"@webex/internal-plugin-user": "3.8.1-next.5",
|
74
|
-
"@webex/internal-plugin-voicea": "3.8.1-next.
|
75
|
-
"@webex/media-helpers": "3.8.1-next.
|
74
|
+
"@webex/internal-plugin-voicea": "3.8.1-next.12",
|
75
|
+
"@webex/media-helpers": "3.8.1-next.7",
|
76
76
|
"@webex/plugin-people": "3.8.1-next.5",
|
77
77
|
"@webex/plugin-rooms": "3.8.1-next.2",
|
78
78
|
"@webex/ts-sdp": "^1.8.1",
|
79
|
-
"@webex/web-capabilities": "^1.
|
79
|
+
"@webex/web-capabilities": "^1.6.0",
|
80
80
|
"@webex/webex-core": "3.8.1-next.5",
|
81
81
|
"ampersand-collection": "^2.0.2",
|
82
82
|
"bowser": "^2.11.0",
|
@@ -93,5 +93,5 @@
|
|
93
93
|
"//": [
|
94
94
|
"TODO: upgrade jwt-decode when moving to node 18"
|
95
95
|
],
|
96
|
-
"version": "3.8.1-next.
|
96
|
+
"version": "3.8.1-next.12"
|
97
97
|
}
|
package/src/media/index.ts
CHANGED
@@ -239,8 +239,8 @@ Media.createMediaConnection = (
|
|
239
239
|
screenShareAudio: shareAudioStream?.outputStream?.getTracks()[0], // TODO: add type for screenShareAudio in internal-media-core SPARK-446923
|
240
240
|
} as unknown,
|
241
241
|
direction: {
|
242
|
-
audio: Media.getDirection(
|
243
|
-
video: Media.getDirection(
|
242
|
+
audio: Media.getDirection(false, mediaDirection.receiveAudio, mediaDirection.sendAudio),
|
243
|
+
video: Media.getDirection(false, mediaDirection.receiveVideo, mediaDirection.sendVideo),
|
244
244
|
screenShareVideo: Media.getDirection(
|
245
245
|
false,
|
246
246
|
mediaDirection.receiveShare,
|
package/src/meeting/index.ts
CHANGED
@@ -231,6 +231,14 @@ export type AddMediaOptions = {
|
|
231
231
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration; // applies only to multistream meetings
|
232
232
|
bundlePolicy?: BundlePolicy; // applies only to multistream meetings
|
233
233
|
allowMediaInLobby?: boolean; // allows adding media when in the lobby
|
234
|
+
additionalMediaOptions?: AdditionalMediaOptions; // allows adding additional options like send/receive audio/video
|
235
|
+
};
|
236
|
+
|
237
|
+
export type AdditionalMediaOptions = {
|
238
|
+
sendVideo?: boolean; // if not specified, default value of videoEnabled is used
|
239
|
+
receiveVideo?: boolean; // if not specified, default value of videoEnabled is used
|
240
|
+
sendAudio?: boolean; // if not specified, default value of audioEnabled true is used
|
241
|
+
receiveAudio?: boolean; // if not specified, default value of audioEnabled true is used
|
234
242
|
};
|
235
243
|
|
236
244
|
export type CallStateForMetrics = {
|
@@ -7757,8 +7765,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7757
7765
|
shareVideoEnabled = true,
|
7758
7766
|
remoteMediaManagerConfig,
|
7759
7767
|
bundlePolicy = 'max-bundle',
|
7768
|
+
additionalMediaOptions = {},
|
7760
7769
|
} = options;
|
7761
7770
|
|
7771
|
+
const {
|
7772
|
+
sendVideo: rawSendVideo,
|
7773
|
+
receiveVideo: rawReceiveVideo,
|
7774
|
+
sendAudio: rawSendAudio,
|
7775
|
+
receiveAudio: rawReceiveAudio,
|
7776
|
+
} = additionalMediaOptions;
|
7777
|
+
|
7778
|
+
const sendVideo = videoEnabled && (rawSendVideo ?? true);
|
7779
|
+
const receiveVideo = videoEnabled && (rawReceiveVideo ?? true);
|
7780
|
+
const sendAudio = audioEnabled && (rawSendAudio ?? true);
|
7781
|
+
const receiveAudio = audioEnabled && (rawReceiveAudio ?? true);
|
7782
|
+
|
7762
7783
|
this.allowMediaInLobby = options?.allowMediaInLobby;
|
7763
7784
|
|
7764
7785
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
@@ -7794,11 +7815,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7794
7815
|
// when audioEnabled/videoEnabled is true, we set sendAudio/sendVideo to true even before any streams are published
|
7795
7816
|
// to avoid doing an extra SDP exchange when they are published for the first time
|
7796
7817
|
this.mediaProperties.setMediaDirection({
|
7797
|
-
sendAudio
|
7798
|
-
sendVideo
|
7818
|
+
sendAudio,
|
7819
|
+
sendVideo,
|
7799
7820
|
sendShare: false,
|
7800
|
-
receiveAudio
|
7801
|
-
receiveVideo
|
7821
|
+
receiveAudio,
|
7822
|
+
receiveVideo,
|
7802
7823
|
receiveShare: shareAudioEnabled || shareVideoEnabled,
|
7803
7824
|
});
|
7804
7825
|
|
@@ -137,6 +137,113 @@ describe('createMediaConnection', () => {
|
|
137
137
|
);
|
138
138
|
});
|
139
139
|
|
140
|
+
it('should set direction to sendonly for both audio and video when only send flags are true', () => {
|
141
|
+
const roapMediaConnectionConstructorStub = sinon
|
142
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
143
|
+
.returns(fakeRoapMediaConnection);
|
144
|
+
|
145
|
+
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
146
|
+
|
147
|
+
const ENABLE_EXTMAP = false;
|
148
|
+
const ENABLE_RTX = true;
|
149
|
+
|
150
|
+
Media.createMediaConnection(false, 'sendonly-debug-id', 'meetingId', {
|
151
|
+
mediaProperties: {
|
152
|
+
mediaDirection: {
|
153
|
+
sendAudio: true,
|
154
|
+
receiveAudio: false,
|
155
|
+
sendVideo: true,
|
156
|
+
receiveVideo: false,
|
157
|
+
sendShare: false,
|
158
|
+
receiveShare: false,
|
159
|
+
},
|
160
|
+
audioStream: fakeAudioStream,
|
161
|
+
videoStream: fakeVideoStream,
|
162
|
+
shareVideoTrack: null,
|
163
|
+
shareAudioTrack: null,
|
164
|
+
},
|
165
|
+
remoteQualityLevel: 'HIGH',
|
166
|
+
enableRtx: ENABLE_RTX,
|
167
|
+
enableExtmap: ENABLE_EXTMAP,
|
168
|
+
turnServerInfo: undefined,
|
169
|
+
iceCandidatesTimeout: undefined,
|
170
|
+
});
|
171
|
+
|
172
|
+
assert.calledWith(
|
173
|
+
roapMediaConnectionConstructorStub,
|
174
|
+
sinon.match.any,
|
175
|
+
{
|
176
|
+
localTracks: {
|
177
|
+
audio: fakeTrack,
|
178
|
+
video: fakeTrack,
|
179
|
+
screenShareVideo: undefined,
|
180
|
+
screenShareAudio: undefined,
|
181
|
+
},
|
182
|
+
direction: {
|
183
|
+
audio: 'sendonly',
|
184
|
+
video: 'sendonly',
|
185
|
+
screenShareVideo: 'inactive',
|
186
|
+
},
|
187
|
+
remoteQualityLevel: 'HIGH',
|
188
|
+
},
|
189
|
+
'sendonly-debug-id'
|
190
|
+
);
|
191
|
+
});
|
192
|
+
|
193
|
+
it('should set direction to recvonly for both audio and video when only receive flags are true', () => {
|
194
|
+
const roapMediaConnectionConstructorStub = sinon
|
195
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
196
|
+
.returns(fakeRoapMediaConnection);
|
197
|
+
|
198
|
+
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
199
|
+
|
200
|
+
const ENABLE_EXTMAP = true;
|
201
|
+
const ENABLE_RTX = false;
|
202
|
+
|
203
|
+
Media.createMediaConnection(false, 'recvonly-debug-id', 'meetingId', {
|
204
|
+
mediaProperties: {
|
205
|
+
mediaDirection: {
|
206
|
+
sendAudio: false,
|
207
|
+
receiveAudio: true,
|
208
|
+
sendVideo: false,
|
209
|
+
receiveVideo: true,
|
210
|
+
sendShare: false,
|
211
|
+
receiveShare: false,
|
212
|
+
},
|
213
|
+
audioStream: fakeAudioStream,
|
214
|
+
videoStream: fakeVideoStream,
|
215
|
+
shareVideoTrack: null,
|
216
|
+
shareAudioTrack: null,
|
217
|
+
},
|
218
|
+
remoteQualityLevel: 'HIGH',
|
219
|
+
enableRtx: ENABLE_RTX,
|
220
|
+
enableExtmap: ENABLE_EXTMAP,
|
221
|
+
turnServerInfo: undefined,
|
222
|
+
iceCandidatesTimeout: undefined,
|
223
|
+
});
|
224
|
+
|
225
|
+
assert.calledWith(
|
226
|
+
roapMediaConnectionConstructorStub,
|
227
|
+
sinon.match.any,
|
228
|
+
{
|
229
|
+
localTracks: {
|
230
|
+
audio: fakeTrack,
|
231
|
+
video: fakeTrack,
|
232
|
+
screenShareVideo: undefined,
|
233
|
+
screenShareAudio: undefined,
|
234
|
+
},
|
235
|
+
direction: {
|
236
|
+
audio: 'recvonly',
|
237
|
+
video: 'recvonly',
|
238
|
+
screenShareVideo: 'inactive',
|
239
|
+
},
|
240
|
+
remoteQualityLevel: 'HIGH',
|
241
|
+
},
|
242
|
+
'recvonly-debug-id'
|
243
|
+
);
|
244
|
+
});
|
245
|
+
|
246
|
+
|
140
247
|
it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
|
141
248
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
142
249
|
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
@@ -1208,8 +1208,76 @@ describe('plugin-meetings', () => {
|
|
1208
1208
|
reason: 'joinWithMedia failure',
|
1209
1209
|
});
|
1210
1210
|
});
|
1211
|
-
});
|
1212
1211
|
|
1212
|
+
it('should ignore sendVideo/receiveVideo when videoEnabled is false', async () => {
|
1213
|
+
await meeting.joinWithMedia({
|
1214
|
+
joinOptions,
|
1215
|
+
mediaOptions: {
|
1216
|
+
videoEnabled: false,
|
1217
|
+
sendVideo: true,
|
1218
|
+
receiveVideo: true,
|
1219
|
+
allowMediaInLobby: true,
|
1220
|
+
},
|
1221
|
+
});
|
1222
|
+
|
1223
|
+
assert.calledWithMatch(
|
1224
|
+
meeting.addMediaInternal,
|
1225
|
+
sinon.match.any,
|
1226
|
+
sinon.match.any,
|
1227
|
+
sinon.match.any,
|
1228
|
+
sinon.match.has('videoEnabled', false)
|
1229
|
+
.and(sinon.match.has('allowMediaInLobby', true))
|
1230
|
+
);
|
1231
|
+
});
|
1232
|
+
|
1233
|
+
it('should ignore sendAudio/receiveAudio when audioEnabled is false', async () => {
|
1234
|
+
await meeting.joinWithMedia({
|
1235
|
+
joinOptions,
|
1236
|
+
mediaOptions: {
|
1237
|
+
audioEnabled: false,
|
1238
|
+
sendAudio: true,
|
1239
|
+
receiveAudio: false,
|
1240
|
+
allowMediaInLobby: true,
|
1241
|
+
},
|
1242
|
+
});
|
1243
|
+
|
1244
|
+
assert.calledWithMatch(
|
1245
|
+
meeting.addMediaInternal,
|
1246
|
+
sinon.match.any,
|
1247
|
+
sinon.match.any,
|
1248
|
+
sinon.match.any,
|
1249
|
+
sinon.match.has('audioEnabled', false)
|
1250
|
+
.and(sinon.match.has('allowMediaInLobby', true))
|
1251
|
+
);
|
1252
|
+
});
|
1253
|
+
|
1254
|
+
|
1255
|
+
it('should use provided send/receive values when videoEnabled/audioEnabled are true or not set', async () => {
|
1256
|
+
await meeting.joinWithMedia({
|
1257
|
+
joinOptions,
|
1258
|
+
mediaOptions: {
|
1259
|
+
sendVideo: true,
|
1260
|
+
receiveVideo: false,
|
1261
|
+
sendAudio: false,
|
1262
|
+
receiveAudio: true,
|
1263
|
+
allowMediaInLobby: true,
|
1264
|
+
},
|
1265
|
+
});
|
1266
|
+
|
1267
|
+
assert.calledWith(
|
1268
|
+
meeting.addMediaInternal,
|
1269
|
+
sinon.match.any,
|
1270
|
+
sinon.match.any,
|
1271
|
+
sinon.match.any,
|
1272
|
+
sinon.match({
|
1273
|
+
sendVideo: true,
|
1274
|
+
receiveVideo: false,
|
1275
|
+
sendAudio: false,
|
1276
|
+
receiveAudio: true,
|
1277
|
+
})
|
1278
|
+
);
|
1279
|
+
});
|
1280
|
+
});
|
1213
1281
|
describe('#isTranscriptionSupported', () => {
|
1214
1282
|
it('should return false if the feature is not supported for the meeting', () => {
|
1215
1283
|
meeting.locusInfo.controls = {transcribe: {caption: false}};
|