@webex/web-client-media-engine 1.39.0 → 1.40.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/cjs/index.js +163 -21
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +163 -21
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -978,6 +978,10 @@ exports.LocalTrackEvents = void 0;
|
|
|
978
978
|
* Fires when there has been a change in the underlying track.
|
|
979
979
|
*/
|
|
980
980
|
LocalTrackEvents["UnderlyingTrackChange"] = "underlying-track-change";
|
|
981
|
+
/**
|
|
982
|
+
* Fires when the applyConstraints() has been called for the track.
|
|
983
|
+
*/
|
|
984
|
+
LocalTrackEvents["TrackConstraintsChange"] = "track-constraints-change";
|
|
981
985
|
})(exports.LocalTrackEvents || (exports.LocalTrackEvents = {}));
|
|
982
986
|
// TBD: Fix this once types are published separately
|
|
983
987
|
// export type TrackEffect = BaseMicrophoneEffect | BaseCameraEffect;
|
|
@@ -1151,7 +1155,7 @@ class LocalTrack extends EventEmitter$2 {
|
|
|
1151
1155
|
return effect;
|
|
1152
1156
|
}
|
|
1153
1157
|
/**
|
|
1154
|
-
* Cleanup local microphone track.
|
|
1158
|
+
* Cleanup the local microphone track.
|
|
1155
1159
|
*/
|
|
1156
1160
|
disposeEffects() {
|
|
1157
1161
|
if (this.effects.size > 0) {
|
|
@@ -1161,6 +1165,59 @@ class LocalTrack extends EventEmitter$2 {
|
|
|
1161
1165
|
this.emit(exports.LocalTrackEvents.UnderlyingTrackChange);
|
|
1162
1166
|
}
|
|
1163
1167
|
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Apply constraints to the track.
|
|
1170
|
+
*
|
|
1171
|
+
* @param constraints - The constraints to apply to the track.
|
|
1172
|
+
* @returns A promise which resolves when the constraints have been successfully applied.
|
|
1173
|
+
*/
|
|
1174
|
+
applyConstraints(constraints) {
|
|
1175
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
1176
|
+
logger$3.log(`Applying constraints to local track:`, constraints);
|
|
1177
|
+
const ret = this.underlyingTrack.applyConstraints(constraints).then(() => {
|
|
1178
|
+
this.emit(exports.LocalTrackEvents.TrackConstraintsChange);
|
|
1179
|
+
});
|
|
1180
|
+
return ret;
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Get the current constraints of the track.
|
|
1185
|
+
*
|
|
1186
|
+
* @returns The constraints of the track.
|
|
1187
|
+
*/
|
|
1188
|
+
getConstraints() {
|
|
1189
|
+
return this.underlyingTrack.getConstraints();
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Get the current settings of the track.
|
|
1193
|
+
*
|
|
1194
|
+
* @returns The settings of the track.
|
|
1195
|
+
*/
|
|
1196
|
+
getSettings() {
|
|
1197
|
+
return this.underlyingTrack.getSettings();
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Check the resolution and then return how many layers will be active.
|
|
1201
|
+
*
|
|
1202
|
+
* @returns The active layers count.
|
|
1203
|
+
*/
|
|
1204
|
+
getNumActiveSimulcastLayers() {
|
|
1205
|
+
let activeSimulcastLayersNumber = 0;
|
|
1206
|
+
if (this.trackState.type === 'audio') {
|
|
1207
|
+
return activeSimulcastLayersNumber;
|
|
1208
|
+
}
|
|
1209
|
+
const videoHeight = this.underlyingTrack.getSettings().height;
|
|
1210
|
+
if (videoHeight <= 180) {
|
|
1211
|
+
activeSimulcastLayersNumber = 1;
|
|
1212
|
+
}
|
|
1213
|
+
else if (videoHeight <= 360) {
|
|
1214
|
+
activeSimulcastLayersNumber = 2;
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
activeSimulcastLayersNumber = 3;
|
|
1218
|
+
}
|
|
1219
|
+
return activeSimulcastLayersNumber;
|
|
1220
|
+
}
|
|
1164
1221
|
}
|
|
1165
1222
|
LocalTrack.Events = exports.LocalTrackEvents;
|
|
1166
1223
|
|
|
@@ -1204,7 +1261,10 @@ class WcmeError {
|
|
|
1204
1261
|
}
|
|
1205
1262
|
}
|
|
1206
1263
|
/**
|
|
1207
|
-
* Creates a camera video track.
|
|
1264
|
+
* Creates a camera video track. Please note that the constraint params in second getUserMedia call would NOT take effect when:
|
|
1265
|
+
*
|
|
1266
|
+
* 1. Previous captured video track from the same device is not stopped .
|
|
1267
|
+
* 2. Previous createCameraTrack() call for the same device is in progress.
|
|
1208
1268
|
*
|
|
1209
1269
|
* @param constraints - Video device constraints.
|
|
1210
1270
|
* @returns A LocalTrack object or an error.
|
|
@@ -4995,6 +5055,44 @@ class PeerConnection extends EventEmitter$2 {
|
|
|
4995
5055
|
get iceGatheringState() {
|
|
4996
5056
|
return this.pc.iceGatheringState;
|
|
4997
5057
|
}
|
|
5058
|
+
/**
|
|
5059
|
+
* Returns the type of a connection that has been established.
|
|
5060
|
+
*
|
|
5061
|
+
* @returns The connection type which would be `ConnectionType`.
|
|
5062
|
+
*/
|
|
5063
|
+
getCurrentConnectionType() {
|
|
5064
|
+
var _a;
|
|
5065
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5066
|
+
// make sure this method only can be called when the ice connection is established;
|
|
5067
|
+
const isIceConnected = this.pc.iceConnectionState === 'connected' || this.pc.iceConnectionState === 'completed';
|
|
5068
|
+
if (!isIceConnected) {
|
|
5069
|
+
throw new Error('Ice connection is not established');
|
|
5070
|
+
}
|
|
5071
|
+
const succeededLocalCandidateIds = new Set();
|
|
5072
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5073
|
+
const localCandidateStatsReports = [];
|
|
5074
|
+
(yield this.pc.getStats()).forEach((report) => {
|
|
5075
|
+
var _a;
|
|
5076
|
+
// collect all local candidate ids from `candidate-pair` stats reports with `succeeded` state.
|
|
5077
|
+
if (report.type === 'candidate-pair' && ((_a = report.state) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'succeeded') {
|
|
5078
|
+
succeededLocalCandidateIds.add(report.localCandidateId);
|
|
5079
|
+
}
|
|
5080
|
+
// collect all `local-candidate` stats.
|
|
5081
|
+
if (report.type === 'local-candidate') {
|
|
5082
|
+
localCandidateStatsReports.push(report);
|
|
5083
|
+
}
|
|
5084
|
+
});
|
|
5085
|
+
// find the `local-candidate` stats which report id contains in `succeededLocalCandidateIds`.
|
|
5086
|
+
const localCandidate = localCandidateStatsReports.find((report) => succeededLocalCandidateIds.has(report.id));
|
|
5087
|
+
if (!localCandidate) {
|
|
5088
|
+
return 'unknown';
|
|
5089
|
+
}
|
|
5090
|
+
if (localCandidate.relayProtocol) {
|
|
5091
|
+
return `TURN-${localCandidate.relayProtocol.toUpperCase()}`;
|
|
5092
|
+
}
|
|
5093
|
+
return (_a = localCandidate.protocol) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
5094
|
+
});
|
|
5095
|
+
}
|
|
4998
5096
|
}
|
|
4999
5097
|
PeerConnection.Events = PeerConnectionEvents;
|
|
5000
5098
|
|
|
@@ -9604,6 +9702,10 @@ const defaultMultistreamConnectionOptions = {
|
|
|
9604
9702
|
enableMainAudio: true,
|
|
9605
9703
|
enableMainVideo: true,
|
|
9606
9704
|
};
|
|
9705
|
+
const defaultVideoCodecParameters = {
|
|
9706
|
+
'max-mbps': `${defaultMaxVideoEncodeMbps}`,
|
|
9707
|
+
'max-fs': `${defaultMaxVideoEncodeFrameSize}`,
|
|
9708
|
+
};
|
|
9607
9709
|
class MultistreamConnection extends EventEmitter {
|
|
9608
9710
|
constructor(userOptions = {}) {
|
|
9609
9711
|
var _a, _b;
|
|
@@ -9614,6 +9716,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
9614
9716
|
this.pendingJmpTasks = [];
|
|
9615
9717
|
this.metricsCallback = () => { };
|
|
9616
9718
|
this.overuseUpdateCallback = () => { };
|
|
9719
|
+
this.customCodecParameters = new Map();
|
|
9617
9720
|
this.midMap = new Map();
|
|
9618
9721
|
this.currentMid = 0;
|
|
9619
9722
|
this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
|
|
@@ -9626,6 +9729,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
9626
9729
|
const mainSceneId = generateSceneId();
|
|
9627
9730
|
const videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent.Main);
|
|
9628
9731
|
this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions);
|
|
9732
|
+
this.setCodecParameters(MediaType.VideoMain, defaultVideoCodecParameters);
|
|
9629
9733
|
this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
|
|
9630
9734
|
(_a = this.sendTransceivers.get(MediaType.VideoMain)) === null || _a === void 0 ? void 0 : _a.setActive(this.options.enableMainVideo);
|
|
9631
9735
|
(_b = this.sendTransceivers.get(MediaType.AudioMain)) === null || _b === void 0 ? void 0 : _b.setActive(this.options.enableMainAudio);
|
|
@@ -9633,6 +9737,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
9633
9737
|
const videoPresentationEncodingOptions = this.getVideoEncodingOptions(MediaContent.Slides);
|
|
9634
9738
|
const contentSceneId = generateSceneId();
|
|
9635
9739
|
this.createSendTransceiver(MediaType.VideoSlides, contentSceneId, videoPresentationEncodingOptions);
|
|
9740
|
+
this.setCodecParameters(MediaType.VideoSlides, defaultVideoCodecParameters);
|
|
9636
9741
|
this.createSendTransceiver(MediaType.AudioSlides, contentSceneId);
|
|
9637
9742
|
}
|
|
9638
9743
|
}
|
|
@@ -9997,20 +10102,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
9997
10102
|
return ingressSignaler.getReceiverId();
|
|
9998
10103
|
});
|
|
9999
10104
|
if (this.pc.getRemoteDescription()) {
|
|
10000
|
-
yield this.
|
|
10001
|
-
.createOffer()
|
|
10002
|
-
.then((offer) => {
|
|
10003
|
-
if (!offer.sdp) {
|
|
10004
|
-
throw new Error('No SDP offer');
|
|
10005
|
-
}
|
|
10006
|
-
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
10007
|
-
return this.pc.setLocalDescription(offer);
|
|
10008
|
-
})
|
|
10009
|
-
.then(() => {
|
|
10010
|
-
var _a;
|
|
10011
|
-
const answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
10012
|
-
return this.pc.setRemoteDescription({ type: 'answer', sdp: answer });
|
|
10013
|
-
});
|
|
10105
|
+
yield this.doLocalOfferAnswer();
|
|
10014
10106
|
}
|
|
10015
10107
|
this.recvTransceivers.set(mediaType, [
|
|
10016
10108
|
...(this.recvTransceivers.get(mediaType) || []),
|
|
@@ -10076,8 +10168,26 @@ class MultistreamConnection extends EventEmitter {
|
|
|
10076
10168
|
}
|
|
10077
10169
|
setAnswer(answer) {
|
|
10078
10170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10171
|
+
const isInitialAnswer = !this.pc.getRemoteDescription();
|
|
10079
10172
|
const sdp = this.preProcessRemoteAnswer(answer);
|
|
10080
|
-
return this.pc.setRemoteDescription({ type: 'answer', sdp })
|
|
10173
|
+
return this.pc.setRemoteDescription({ type: 'answer', sdp }).then(() => {
|
|
10174
|
+
if (isInitialAnswer && this.customCodecParameters.size > 0) {
|
|
10175
|
+
this.doLocalOfferAnswer();
|
|
10176
|
+
}
|
|
10177
|
+
});
|
|
10178
|
+
});
|
|
10179
|
+
}
|
|
10180
|
+
doLocalOfferAnswer() {
|
|
10181
|
+
var _a;
|
|
10182
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10183
|
+
const offer = yield this.pc.createOffer();
|
|
10184
|
+
if (!offer.sdp) {
|
|
10185
|
+
throw new Error('No SDP offer');
|
|
10186
|
+
}
|
|
10187
|
+
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
10188
|
+
yield this.pc.setLocalDescription(offer);
|
|
10189
|
+
const answer = this.preProcessRemoteAnswer((_a = this.pc.getRemoteDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
10190
|
+
return this.pc.setRemoteDescription({ type: 'answer', sdp: answer });
|
|
10081
10191
|
});
|
|
10082
10192
|
}
|
|
10083
10193
|
enableMultistreamAudio(enabled) {
|
|
@@ -10104,12 +10214,20 @@ class MultistreamConnection extends EventEmitter {
|
|
|
10104
10214
|
const simulcastEnabled = !!av.simulcast;
|
|
10105
10215
|
const rtxEnabled = av.type === 'video';
|
|
10106
10216
|
egressSignaler.signalStreams(simulcastEnabled, rtxEnabled, av);
|
|
10107
|
-
|
|
10217
|
+
const mediaType = [...this.sendTransceivers.keys()].find((key) => { var _a; return ((_a = this.sendTransceivers.get(key)) === null || _a === void 0 ? void 0 : _a.mid) === av.mid; });
|
|
10218
|
+
if (mediaType && this.customCodecParameters.has(mediaType)) {
|
|
10108
10219
|
[...av.codecs.values()]
|
|
10109
|
-
.filter((ci) => ci.name === 'H264')
|
|
10220
|
+
.filter((ci) => ci.name === (av.type === 'audio' ? 'opus' : 'H264'))
|
|
10110
10221
|
.forEach((ci) => {
|
|
10111
|
-
|
|
10112
|
-
|
|
10222
|
+
var _a;
|
|
10223
|
+
(_a = this.customCodecParameters.get(mediaType)) === null || _a === void 0 ? void 0 : _a.forEach((value, param) => {
|
|
10224
|
+
if (value === null) {
|
|
10225
|
+
ci.fmtParams.delete(param);
|
|
10226
|
+
}
|
|
10227
|
+
else {
|
|
10228
|
+
ci.fmtParams.set(param, `${value}`);
|
|
10229
|
+
}
|
|
10230
|
+
});
|
|
10113
10231
|
});
|
|
10114
10232
|
}
|
|
10115
10233
|
});
|
|
@@ -10165,6 +10283,30 @@ class MultistreamConnection extends EventEmitter {
|
|
|
10165
10283
|
.map((transceiver) => transceiver.publishedTrack)
|
|
10166
10284
|
.filter(Boolean);
|
|
10167
10285
|
}
|
|
10286
|
+
setCodecParameters(mediaType, parameters) {
|
|
10287
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10288
|
+
const currentParams = this.customCodecParameters.get(mediaType) || new Map();
|
|
10289
|
+
Object.entries(parameters).forEach(([param, value]) => {
|
|
10290
|
+
currentParams.set(param, value);
|
|
10291
|
+
});
|
|
10292
|
+
this.customCodecParameters.set(mediaType, currentParams);
|
|
10293
|
+
if (this.pc.getRemoteDescription()) {
|
|
10294
|
+
yield this.doLocalOfferAnswer();
|
|
10295
|
+
}
|
|
10296
|
+
});
|
|
10297
|
+
}
|
|
10298
|
+
deleteCodecParameters(mediaType, parameters) {
|
|
10299
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10300
|
+
const currentParams = this.customCodecParameters.get(mediaType) || new Map();
|
|
10301
|
+
parameters.forEach((param) => {
|
|
10302
|
+
currentParams.set(param, null);
|
|
10303
|
+
});
|
|
10304
|
+
this.customCodecParameters.set(mediaType, currentParams);
|
|
10305
|
+
if (this.pc.getRemoteDescription()) {
|
|
10306
|
+
yield this.doLocalOfferAnswer();
|
|
10307
|
+
}
|
|
10308
|
+
});
|
|
10309
|
+
}
|
|
10168
10310
|
requestMedia(mediaType, mediaRequests) {
|
|
10169
10311
|
var _a;
|
|
10170
10312
|
const task = () => {
|