@webex/web-client-media-engine 3.22.1 → 3.22.3
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 +90 -29
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +90 -29
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -9415,30 +9415,26 @@ function disableRtcpFbValue(sdpOrAv, rtcpFbValue) {
|
|
|
9415
9415
|
function disableTwcc(sdpOrAv) {
|
|
9416
9416
|
disableRtcpFbValue(sdpOrAv, 'transport-cc');
|
|
9417
9417
|
}
|
|
9418
|
-
function
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9418
|
+
function retainCodecs(av, predicate) {
|
|
9419
|
+
let filtered = false;
|
|
9420
|
+
av.codecs.forEach((codecInfo) => {
|
|
9421
|
+
if (!predicate(codecInfo)) {
|
|
9422
|
+
av.removePt(codecInfo.pt);
|
|
9423
|
+
filtered = true;
|
|
9424
|
+
}
|
|
9423
9425
|
});
|
|
9426
|
+
return filtered;
|
|
9424
9427
|
}
|
|
9425
|
-
function
|
|
9426
|
-
const avMediaDescriptions = sdpOrAv instanceof Sdp ? sdpOrAv.avMedia : [sdpOrAv];
|
|
9428
|
+
function retainCodecsByCodecName(av, allowedCodecNames) {
|
|
9427
9429
|
const allowedLowerCase = allowedCodecNames.map((s) => s.toLowerCase());
|
|
9428
|
-
|
|
9429
|
-
.map((av) => {
|
|
9430
|
-
return [...av.codecs.values()].map((c) => c.name);
|
|
9431
|
-
})
|
|
9432
|
-
.flat()
|
|
9433
|
-
.filter((codecName) => !allowedLowerCase.includes(codecName.toLowerCase()))
|
|
9434
|
-
.forEach((unwantedCodec) => removeCodec(sdpOrAv, unwantedCodec));
|
|
9430
|
+
return retainCodecs(av, (codecInfo) => !!codecInfo.name && allowedLowerCase.includes(codecInfo.name.toLowerCase()));
|
|
9435
9431
|
}
|
|
9436
|
-
function retainCandidates(sdpOrMedia,
|
|
9432
|
+
function retainCandidates(sdpOrMedia, predicate) {
|
|
9437
9433
|
const mediaDescriptions = sdpOrMedia instanceof Sdp ? sdpOrMedia.media : [sdpOrMedia];
|
|
9438
9434
|
let filtered = false;
|
|
9439
9435
|
mediaDescriptions.forEach((media) => {
|
|
9440
9436
|
media.iceInfo.candidates = media.iceInfo.candidates.filter((candidate) => {
|
|
9441
|
-
if (
|
|
9437
|
+
if (predicate(candidate)) {
|
|
9442
9438
|
return true;
|
|
9443
9439
|
}
|
|
9444
9440
|
filtered = true;
|
|
@@ -9446,6 +9442,10 @@ function retainCandidates(sdpOrMedia, allowedTransportTypes) {
|
|
|
9446
9442
|
});
|
|
9447
9443
|
});
|
|
9448
9444
|
return filtered;
|
|
9445
|
+
}
|
|
9446
|
+
function retainCandidatesByTransportType(sdpOrMedia, allowedTransportTypes) {
|
|
9447
|
+
const allowedLowerCase = allowedTransportTypes.map((s) => s.toLowerCase());
|
|
9448
|
+
return retainCandidates(sdpOrMedia, (candidate) => allowedLowerCase.includes(candidate.transport.toLowerCase()));
|
|
9449
9449
|
}
|
|
9450
9450
|
|
|
9451
9451
|
function hasCodec(codecName, mLine) {
|
|
@@ -9473,6 +9473,12 @@ var BrowserName;
|
|
|
9473
9473
|
BrowserName["EDGE"] = "Microsoft Edge";
|
|
9474
9474
|
BrowserName["SAFARI"] = "Safari";
|
|
9475
9475
|
})(BrowserName || (BrowserName = {}));
|
|
9476
|
+
var OSName;
|
|
9477
|
+
(function (OSName) {
|
|
9478
|
+
OSName["WINDOWS"] = "Windows";
|
|
9479
|
+
OSName["MAC"] = "macOS";
|
|
9480
|
+
OSName["LINUX"] = "Linux";
|
|
9481
|
+
})(OSName || (OSName = {}));
|
|
9476
9482
|
class BrowserInfo {
|
|
9477
9483
|
static getBrowserDetails() {
|
|
9478
9484
|
return this.browser.getBrowser();
|
|
@@ -9498,6 +9504,15 @@ class BrowserInfo {
|
|
|
9498
9504
|
static isSafari() {
|
|
9499
9505
|
return this.browser.getBrowserName() === BrowserName.SAFARI;
|
|
9500
9506
|
}
|
|
9507
|
+
static isWindows() {
|
|
9508
|
+
return this.browser.getOSName() === OSName.WINDOWS;
|
|
9509
|
+
}
|
|
9510
|
+
static isMac() {
|
|
9511
|
+
return this.browser.getOSName() === OSName.MAC;
|
|
9512
|
+
}
|
|
9513
|
+
static isLinux() {
|
|
9514
|
+
return this.browser.getOSName() === OSName.LINUX;
|
|
9515
|
+
}
|
|
9501
9516
|
static isVersionGreaterThan(version) {
|
|
9502
9517
|
const browserName = this.browser.getBrowserName();
|
|
9503
9518
|
const checkTree = { [browserName]: `>${version}` };
|
|
@@ -9751,16 +9766,33 @@ function generateSsrc() {
|
|
|
9751
9766
|
}
|
|
9752
9767
|
|
|
9753
9768
|
class EgressSdpMunger {
|
|
9754
|
-
constructor() {
|
|
9769
|
+
constructor(options) {
|
|
9755
9770
|
this.streamIds = [];
|
|
9756
9771
|
this.customCodecParameters = new Map();
|
|
9772
|
+
this.egressMungerOptions = options;
|
|
9757
9773
|
}
|
|
9758
9774
|
reset() {
|
|
9759
9775
|
this.streamIds = [];
|
|
9760
9776
|
}
|
|
9761
9777
|
mungeLocalDescription(mediaDescription, options) {
|
|
9762
9778
|
var _a;
|
|
9763
|
-
|
|
9779
|
+
retainCodecsByCodecName(mediaDescription, ['h264', 'opus', 'rtx']);
|
|
9780
|
+
if (options.forceSoftwareEncoder) {
|
|
9781
|
+
const isH264Cbp = (codecInfo) => {
|
|
9782
|
+
var _a;
|
|
9783
|
+
if (((_a = codecInfo.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'h264') {
|
|
9784
|
+
const profileLevelId = codecInfo.fmtParams.get('profile-level-id');
|
|
9785
|
+
return !!profileLevelId && /^42[^0]/.test(profileLevelId);
|
|
9786
|
+
}
|
|
9787
|
+
return false;
|
|
9788
|
+
};
|
|
9789
|
+
if ([...mediaDescription.codecs.values()].some(isH264Cbp)) {
|
|
9790
|
+
retainCodecs(mediaDescription, (codecInfo) => { var _a; return ((_a = codecInfo.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'h264' || isH264Cbp(codecInfo); });
|
|
9791
|
+
}
|
|
9792
|
+
else {
|
|
9793
|
+
logger.log(`No H.264 CBP present in m-line with MID ${mediaDescription.mid}, so all H.264 codecs have been retained.`);
|
|
9794
|
+
}
|
|
9795
|
+
}
|
|
9764
9796
|
if (mediaDescription.codecs.size === 0) {
|
|
9765
9797
|
logErrorAndThrow(exports.WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
|
|
9766
9798
|
}
|
|
@@ -9842,7 +9874,9 @@ class EgressSdpMunger {
|
|
|
9842
9874
|
mungeLocalDescriptionForRemoteServer(mediaDescription, mediaContent, csi) {
|
|
9843
9875
|
injectContentType(mediaDescription, mediaContent);
|
|
9844
9876
|
injectJmpAttributes(mediaDescription, csi, 'SSRC');
|
|
9845
|
-
|
|
9877
|
+
if (!this.egressMungerOptions.doFullIce) {
|
|
9878
|
+
injectDummyCandidates(mediaDescription);
|
|
9879
|
+
}
|
|
9846
9880
|
if (mediaDescription.type === 'video') {
|
|
9847
9881
|
const ssrcGroup = mediaDescription.ssrcGroups.find((sg) => sg.semantics === 'SIM');
|
|
9848
9882
|
if (ssrcGroup) {
|
|
@@ -9853,7 +9887,7 @@ class EgressSdpMunger {
|
|
|
9853
9887
|
}
|
|
9854
9888
|
}
|
|
9855
9889
|
mungeRemoteDescription(mediaDescription) {
|
|
9856
|
-
if (
|
|
9890
|
+
if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
|
|
9857
9891
|
logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
|
|
9858
9892
|
}
|
|
9859
9893
|
mediaDescription.bandwidth = undefined;
|
|
@@ -10366,7 +10400,7 @@ class IngressSdpMunger {
|
|
|
10366
10400
|
return Object.assign({ ssrc: this.ssrc }, (this.rtxSsrc ? { rtxSsrc: this.rtxSsrc } : {}));
|
|
10367
10401
|
}
|
|
10368
10402
|
mungeLocalDescription(mediaDescription, options) {
|
|
10369
|
-
|
|
10403
|
+
retainCodecsByCodecName(mediaDescription, ['h264', 'opus', 'rtx']);
|
|
10370
10404
|
if (mediaDescription.codecs.size === 0) {
|
|
10371
10405
|
logErrorAndThrow(exports.WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
|
|
10372
10406
|
}
|
|
@@ -10388,7 +10422,7 @@ class IngressSdpMunger {
|
|
|
10388
10422
|
mediaDescription.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
|
|
10389
10423
|
}
|
|
10390
10424
|
}
|
|
10391
|
-
if (
|
|
10425
|
+
if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
|
|
10392
10426
|
logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
|
|
10393
10427
|
}
|
|
10394
10428
|
[...mediaDescription.codecs.values()].forEach((ci) => {
|
|
@@ -14576,6 +14610,9 @@ class SendOnlyTransceiver extends Transceiver {
|
|
|
14576
14610
|
simulcastEnabled: this.isSimulcastEnabled(),
|
|
14577
14611
|
rtxEnabled: this.rtxEnabled,
|
|
14578
14612
|
twccDisabled: this.twccDisabled,
|
|
14613
|
+
forceSoftwareEncoder: this.mediaType === exports.MediaType.VideoSlides &&
|
|
14614
|
+
(BrowserInfo.isWindows() || BrowserInfo.isMac()) &&
|
|
14615
|
+
(BrowserInfo.isChrome() || BrowserInfo.isEdge()),
|
|
14579
14616
|
});
|
|
14580
14617
|
}
|
|
14581
14618
|
mungeLocalDescriptionForRemoteServer(mediaDescription) {
|
|
@@ -14757,6 +14794,7 @@ const defaultMultistreamConnectionOptions = {
|
|
|
14757
14794
|
iceServers: undefined,
|
|
14758
14795
|
disableContentSimulcast: true,
|
|
14759
14796
|
disableAudioTwcc: true,
|
|
14797
|
+
doFullIce: BrowserInfo.isFirefox(),
|
|
14760
14798
|
};
|
|
14761
14799
|
class MultistreamConnection extends EventEmitter$2 {
|
|
14762
14800
|
constructor(userOptions = {}) {
|
|
@@ -14863,7 +14901,9 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
14863
14901
|
}
|
|
14864
14902
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
14865
14903
|
const csi = generateCsi(getMediaFamily(mediaType), sceneId);
|
|
14866
|
-
const munger = new EgressSdpMunger(
|
|
14904
|
+
const munger = new EgressSdpMunger({
|
|
14905
|
+
doFullIce: this.options.doFullIce,
|
|
14906
|
+
});
|
|
14867
14907
|
const transceiver = new SendOnlyTransceiver(rtcTransceiver, mid, csi, munger, mediaType);
|
|
14868
14908
|
if (getMediaFamily(mediaType) === exports.MediaFamily.Video) {
|
|
14869
14909
|
transceiver.rtxEnabled = true;
|
|
@@ -15221,6 +15261,22 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15221
15261
|
}
|
|
15222
15262
|
return targetCodec.pt;
|
|
15223
15263
|
}
|
|
15264
|
+
waitForIceGatheringComplete() {
|
|
15265
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
15266
|
+
return new Promise((resolve) => {
|
|
15267
|
+
if (this.pc.iceGatheringState === 'complete') {
|
|
15268
|
+
resolve();
|
|
15269
|
+
}
|
|
15270
|
+
else {
|
|
15271
|
+
this.pc.on(PeerConnection.Events.IceGatheringStateChange, () => {
|
|
15272
|
+
if (this.pc.iceGatheringState === 'complete') {
|
|
15273
|
+
resolve();
|
|
15274
|
+
}
|
|
15275
|
+
});
|
|
15276
|
+
}
|
|
15277
|
+
});
|
|
15278
|
+
});
|
|
15279
|
+
}
|
|
15224
15280
|
createOffer() {
|
|
15225
15281
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
15226
15282
|
if (!this.pc.getLocalDescription()) {
|
|
@@ -15250,6 +15306,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15250
15306
|
var _a;
|
|
15251
15307
|
logErrorAndThrow(exports.WcmeErrorType.CREATE_OFFER_FAILED, `Error: ${error}. SDP: ${maskIp((_a = offer.sdp) !== null && _a !== void 0 ? _a : '')}`);
|
|
15252
15308
|
});
|
|
15309
|
+
if (this.options.doFullIce) {
|
|
15310
|
+
yield this.waitForIceGatheringComplete();
|
|
15311
|
+
}
|
|
15253
15312
|
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
15254
15313
|
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
15255
15314
|
if (this.currentCreateOfferId > createOfferId) {
|
|
@@ -15354,11 +15413,13 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15354
15413
|
const sendTransceiver = this.getSendTransceiverByMidOrThrow(av.mid);
|
|
15355
15414
|
sendTransceiver.mungeLocalDescriptionForRemoteServer(av);
|
|
15356
15415
|
});
|
|
15357
|
-
|
|
15358
|
-
.
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
|
|
15416
|
+
if (!this.options.doFullIce) {
|
|
15417
|
+
parsedOffer.media
|
|
15418
|
+
.filter((media) => media instanceof ApplicationMediaDescription)
|
|
15419
|
+
.forEach((media) => {
|
|
15420
|
+
injectDummyCandidates(media);
|
|
15421
|
+
});
|
|
15422
|
+
}
|
|
15362
15423
|
if (BrowserInfo.isFirefox()) {
|
|
15363
15424
|
setupBundle(parsedOffer, this.options.bundlePolicy, this.midPredictor.getMidMap());
|
|
15364
15425
|
if (this.options.bundlePolicy === 'max-bundle') {
|
|
@@ -15392,7 +15453,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15392
15453
|
parsedAnswer.media
|
|
15393
15454
|
.filter((media) => media instanceof ApplicationMediaDescription)
|
|
15394
15455
|
.forEach((media) => {
|
|
15395
|
-
if (
|
|
15456
|
+
if (retainCandidatesByTransportType(media, ['udp', 'tcp'])) {
|
|
15396
15457
|
logger.log(`Some unsupported remote candidates have been removed from mid ${media.mid}`);
|
|
15397
15458
|
}
|
|
15398
15459
|
});
|