@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/esm/index.js
CHANGED
|
@@ -9411,30 +9411,26 @@ function disableRtcpFbValue(sdpOrAv, rtcpFbValue) {
|
|
|
9411
9411
|
function disableTwcc(sdpOrAv) {
|
|
9412
9412
|
disableRtcpFbValue(sdpOrAv, 'transport-cc');
|
|
9413
9413
|
}
|
|
9414
|
-
function
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9414
|
+
function retainCodecs(av, predicate) {
|
|
9415
|
+
let filtered = false;
|
|
9416
|
+
av.codecs.forEach((codecInfo) => {
|
|
9417
|
+
if (!predicate(codecInfo)) {
|
|
9418
|
+
av.removePt(codecInfo.pt);
|
|
9419
|
+
filtered = true;
|
|
9420
|
+
}
|
|
9419
9421
|
});
|
|
9422
|
+
return filtered;
|
|
9420
9423
|
}
|
|
9421
|
-
function
|
|
9422
|
-
const avMediaDescriptions = sdpOrAv instanceof Sdp ? sdpOrAv.avMedia : [sdpOrAv];
|
|
9424
|
+
function retainCodecsByCodecName(av, allowedCodecNames) {
|
|
9423
9425
|
const allowedLowerCase = allowedCodecNames.map((s) => s.toLowerCase());
|
|
9424
|
-
|
|
9425
|
-
.map((av) => {
|
|
9426
|
-
return [...av.codecs.values()].map((c) => c.name);
|
|
9427
|
-
})
|
|
9428
|
-
.flat()
|
|
9429
|
-
.filter((codecName) => !allowedLowerCase.includes(codecName.toLowerCase()))
|
|
9430
|
-
.forEach((unwantedCodec) => removeCodec(sdpOrAv, unwantedCodec));
|
|
9426
|
+
return retainCodecs(av, (codecInfo) => !!codecInfo.name && allowedLowerCase.includes(codecInfo.name.toLowerCase()));
|
|
9431
9427
|
}
|
|
9432
|
-
function retainCandidates(sdpOrMedia,
|
|
9428
|
+
function retainCandidates(sdpOrMedia, predicate) {
|
|
9433
9429
|
const mediaDescriptions = sdpOrMedia instanceof Sdp ? sdpOrMedia.media : [sdpOrMedia];
|
|
9434
9430
|
let filtered = false;
|
|
9435
9431
|
mediaDescriptions.forEach((media) => {
|
|
9436
9432
|
media.iceInfo.candidates = media.iceInfo.candidates.filter((candidate) => {
|
|
9437
|
-
if (
|
|
9433
|
+
if (predicate(candidate)) {
|
|
9438
9434
|
return true;
|
|
9439
9435
|
}
|
|
9440
9436
|
filtered = true;
|
|
@@ -9442,6 +9438,10 @@ function retainCandidates(sdpOrMedia, allowedTransportTypes) {
|
|
|
9442
9438
|
});
|
|
9443
9439
|
});
|
|
9444
9440
|
return filtered;
|
|
9441
|
+
}
|
|
9442
|
+
function retainCandidatesByTransportType(sdpOrMedia, allowedTransportTypes) {
|
|
9443
|
+
const allowedLowerCase = allowedTransportTypes.map((s) => s.toLowerCase());
|
|
9444
|
+
return retainCandidates(sdpOrMedia, (candidate) => allowedLowerCase.includes(candidate.transport.toLowerCase()));
|
|
9445
9445
|
}
|
|
9446
9446
|
|
|
9447
9447
|
function hasCodec(codecName, mLine) {
|
|
@@ -9469,6 +9469,12 @@ var BrowserName;
|
|
|
9469
9469
|
BrowserName["EDGE"] = "Microsoft Edge";
|
|
9470
9470
|
BrowserName["SAFARI"] = "Safari";
|
|
9471
9471
|
})(BrowserName || (BrowserName = {}));
|
|
9472
|
+
var OSName;
|
|
9473
|
+
(function (OSName) {
|
|
9474
|
+
OSName["WINDOWS"] = "Windows";
|
|
9475
|
+
OSName["MAC"] = "macOS";
|
|
9476
|
+
OSName["LINUX"] = "Linux";
|
|
9477
|
+
})(OSName || (OSName = {}));
|
|
9472
9478
|
class BrowserInfo {
|
|
9473
9479
|
static getBrowserDetails() {
|
|
9474
9480
|
return this.browser.getBrowser();
|
|
@@ -9494,6 +9500,15 @@ class BrowserInfo {
|
|
|
9494
9500
|
static isSafari() {
|
|
9495
9501
|
return this.browser.getBrowserName() === BrowserName.SAFARI;
|
|
9496
9502
|
}
|
|
9503
|
+
static isWindows() {
|
|
9504
|
+
return this.browser.getOSName() === OSName.WINDOWS;
|
|
9505
|
+
}
|
|
9506
|
+
static isMac() {
|
|
9507
|
+
return this.browser.getOSName() === OSName.MAC;
|
|
9508
|
+
}
|
|
9509
|
+
static isLinux() {
|
|
9510
|
+
return this.browser.getOSName() === OSName.LINUX;
|
|
9511
|
+
}
|
|
9497
9512
|
static isVersionGreaterThan(version) {
|
|
9498
9513
|
const browserName = this.browser.getBrowserName();
|
|
9499
9514
|
const checkTree = { [browserName]: `>${version}` };
|
|
@@ -9747,16 +9762,33 @@ function generateSsrc() {
|
|
|
9747
9762
|
}
|
|
9748
9763
|
|
|
9749
9764
|
class EgressSdpMunger {
|
|
9750
|
-
constructor() {
|
|
9765
|
+
constructor(options) {
|
|
9751
9766
|
this.streamIds = [];
|
|
9752
9767
|
this.customCodecParameters = new Map();
|
|
9768
|
+
this.egressMungerOptions = options;
|
|
9753
9769
|
}
|
|
9754
9770
|
reset() {
|
|
9755
9771
|
this.streamIds = [];
|
|
9756
9772
|
}
|
|
9757
9773
|
mungeLocalDescription(mediaDescription, options) {
|
|
9758
9774
|
var _a;
|
|
9759
|
-
|
|
9775
|
+
retainCodecsByCodecName(mediaDescription, ['h264', 'opus', 'rtx']);
|
|
9776
|
+
if (options.forceSoftwareEncoder) {
|
|
9777
|
+
const isH264Cbp = (codecInfo) => {
|
|
9778
|
+
var _a;
|
|
9779
|
+
if (((_a = codecInfo.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'h264') {
|
|
9780
|
+
const profileLevelId = codecInfo.fmtParams.get('profile-level-id');
|
|
9781
|
+
return !!profileLevelId && /^42[^0]/.test(profileLevelId);
|
|
9782
|
+
}
|
|
9783
|
+
return false;
|
|
9784
|
+
};
|
|
9785
|
+
if ([...mediaDescription.codecs.values()].some(isH264Cbp)) {
|
|
9786
|
+
retainCodecs(mediaDescription, (codecInfo) => { var _a; return ((_a = codecInfo.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== 'h264' || isH264Cbp(codecInfo); });
|
|
9787
|
+
}
|
|
9788
|
+
else {
|
|
9789
|
+
logger.log(`No H.264 CBP present in m-line with MID ${mediaDescription.mid}, so all H.264 codecs have been retained.`);
|
|
9790
|
+
}
|
|
9791
|
+
}
|
|
9760
9792
|
if (mediaDescription.codecs.size === 0) {
|
|
9761
9793
|
logErrorAndThrow(WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
|
|
9762
9794
|
}
|
|
@@ -9838,7 +9870,9 @@ class EgressSdpMunger {
|
|
|
9838
9870
|
mungeLocalDescriptionForRemoteServer(mediaDescription, mediaContent, csi) {
|
|
9839
9871
|
injectContentType(mediaDescription, mediaContent);
|
|
9840
9872
|
injectJmpAttributes(mediaDescription, csi, 'SSRC');
|
|
9841
|
-
|
|
9873
|
+
if (!this.egressMungerOptions.doFullIce) {
|
|
9874
|
+
injectDummyCandidates(mediaDescription);
|
|
9875
|
+
}
|
|
9842
9876
|
if (mediaDescription.type === 'video') {
|
|
9843
9877
|
const ssrcGroup = mediaDescription.ssrcGroups.find((sg) => sg.semantics === 'SIM');
|
|
9844
9878
|
if (ssrcGroup) {
|
|
@@ -9849,7 +9883,7 @@ class EgressSdpMunger {
|
|
|
9849
9883
|
}
|
|
9850
9884
|
}
|
|
9851
9885
|
mungeRemoteDescription(mediaDescription) {
|
|
9852
|
-
if (
|
|
9886
|
+
if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
|
|
9853
9887
|
logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
|
|
9854
9888
|
}
|
|
9855
9889
|
mediaDescription.bandwidth = undefined;
|
|
@@ -10362,7 +10396,7 @@ class IngressSdpMunger {
|
|
|
10362
10396
|
return Object.assign({ ssrc: this.ssrc }, (this.rtxSsrc ? { rtxSsrc: this.rtxSsrc } : {}));
|
|
10363
10397
|
}
|
|
10364
10398
|
mungeLocalDescription(mediaDescription, options) {
|
|
10365
|
-
|
|
10399
|
+
retainCodecsByCodecName(mediaDescription, ['h264', 'opus', 'rtx']);
|
|
10366
10400
|
if (mediaDescription.codecs.size === 0) {
|
|
10367
10401
|
logErrorAndThrow(WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
|
|
10368
10402
|
}
|
|
@@ -10384,7 +10418,7 @@ class IngressSdpMunger {
|
|
|
10384
10418
|
mediaDescription.addLine(new SsrcGroupLine('FID', [this.ssrc, this.rtxSsrc]));
|
|
10385
10419
|
}
|
|
10386
10420
|
}
|
|
10387
|
-
if (
|
|
10421
|
+
if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
|
|
10388
10422
|
logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
|
|
10389
10423
|
}
|
|
10390
10424
|
[...mediaDescription.codecs.values()].forEach((ci) => {
|
|
@@ -14572,6 +14606,9 @@ class SendOnlyTransceiver extends Transceiver {
|
|
|
14572
14606
|
simulcastEnabled: this.isSimulcastEnabled(),
|
|
14573
14607
|
rtxEnabled: this.rtxEnabled,
|
|
14574
14608
|
twccDisabled: this.twccDisabled,
|
|
14609
|
+
forceSoftwareEncoder: this.mediaType === MediaType.VideoSlides &&
|
|
14610
|
+
(BrowserInfo.isWindows() || BrowserInfo.isMac()) &&
|
|
14611
|
+
(BrowserInfo.isChrome() || BrowserInfo.isEdge()),
|
|
14575
14612
|
});
|
|
14576
14613
|
}
|
|
14577
14614
|
mungeLocalDescriptionForRemoteServer(mediaDescription) {
|
|
@@ -14753,6 +14790,7 @@ const defaultMultistreamConnectionOptions = {
|
|
|
14753
14790
|
iceServers: undefined,
|
|
14754
14791
|
disableContentSimulcast: true,
|
|
14755
14792
|
disableAudioTwcc: true,
|
|
14793
|
+
doFullIce: BrowserInfo.isFirefox(),
|
|
14756
14794
|
};
|
|
14757
14795
|
class MultistreamConnection extends EventEmitter$2 {
|
|
14758
14796
|
constructor(userOptions = {}) {
|
|
@@ -14859,7 +14897,9 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
14859
14897
|
}
|
|
14860
14898
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
14861
14899
|
const csi = generateCsi(getMediaFamily(mediaType), sceneId);
|
|
14862
|
-
const munger = new EgressSdpMunger(
|
|
14900
|
+
const munger = new EgressSdpMunger({
|
|
14901
|
+
doFullIce: this.options.doFullIce,
|
|
14902
|
+
});
|
|
14863
14903
|
const transceiver = new SendOnlyTransceiver(rtcTransceiver, mid, csi, munger, mediaType);
|
|
14864
14904
|
if (getMediaFamily(mediaType) === MediaFamily.Video) {
|
|
14865
14905
|
transceiver.rtxEnabled = true;
|
|
@@ -15217,6 +15257,22 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15217
15257
|
}
|
|
15218
15258
|
return targetCodec.pt;
|
|
15219
15259
|
}
|
|
15260
|
+
waitForIceGatheringComplete() {
|
|
15261
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
15262
|
+
return new Promise((resolve) => {
|
|
15263
|
+
if (this.pc.iceGatheringState === 'complete') {
|
|
15264
|
+
resolve();
|
|
15265
|
+
}
|
|
15266
|
+
else {
|
|
15267
|
+
this.pc.on(PeerConnection.Events.IceGatheringStateChange, () => {
|
|
15268
|
+
if (this.pc.iceGatheringState === 'complete') {
|
|
15269
|
+
resolve();
|
|
15270
|
+
}
|
|
15271
|
+
});
|
|
15272
|
+
}
|
|
15273
|
+
});
|
|
15274
|
+
});
|
|
15275
|
+
}
|
|
15220
15276
|
createOffer() {
|
|
15221
15277
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
15222
15278
|
if (!this.pc.getLocalDescription()) {
|
|
@@ -15246,6 +15302,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15246
15302
|
var _a;
|
|
15247
15303
|
logErrorAndThrow(WcmeErrorType.CREATE_OFFER_FAILED, `Error: ${error}. SDP: ${maskIp((_a = offer.sdp) !== null && _a !== void 0 ? _a : '')}`);
|
|
15248
15304
|
});
|
|
15305
|
+
if (this.options.doFullIce) {
|
|
15306
|
+
yield this.waitForIceGatheringComplete();
|
|
15307
|
+
}
|
|
15249
15308
|
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
15250
15309
|
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
15251
15310
|
if (this.currentCreateOfferId > createOfferId) {
|
|
@@ -15350,11 +15409,13 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15350
15409
|
const sendTransceiver = this.getSendTransceiverByMidOrThrow(av.mid);
|
|
15351
15410
|
sendTransceiver.mungeLocalDescriptionForRemoteServer(av);
|
|
15352
15411
|
});
|
|
15353
|
-
|
|
15354
|
-
.
|
|
15355
|
-
|
|
15356
|
-
|
|
15357
|
-
|
|
15412
|
+
if (!this.options.doFullIce) {
|
|
15413
|
+
parsedOffer.media
|
|
15414
|
+
.filter((media) => media instanceof ApplicationMediaDescription)
|
|
15415
|
+
.forEach((media) => {
|
|
15416
|
+
injectDummyCandidates(media);
|
|
15417
|
+
});
|
|
15418
|
+
}
|
|
15358
15419
|
if (BrowserInfo.isFirefox()) {
|
|
15359
15420
|
setupBundle(parsedOffer, this.options.bundlePolicy, this.midPredictor.getMidMap());
|
|
15360
15421
|
if (this.options.bundlePolicy === 'max-bundle') {
|
|
@@ -15388,7 +15449,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15388
15449
|
parsedAnswer.media
|
|
15389
15450
|
.filter((media) => media instanceof ApplicationMediaDescription)
|
|
15390
15451
|
.forEach((media) => {
|
|
15391
|
-
if (
|
|
15452
|
+
if (retainCandidatesByTransportType(media, ['udp', 'tcp'])) {
|
|
15392
15453
|
logger.log(`Some unsupported remote candidates have been removed from mid ${media.mid}`);
|
|
15393
15454
|
}
|
|
15394
15455
|
});
|