@webex/web-client-media-engine 3.36.1 → 3.37.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 +106 -61
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +106 -61
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +9 -11
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -8206,6 +8206,24 @@ function getRecommendedMaxBitrateForFrameSize(requestedMaxFs) {
|
|
|
8206
8206
|
.sort((a, b) => b - a)
|
|
8207
8207
|
.find((h) => requestedMaxFs >= h);
|
|
8208
8208
|
return maxFrameSizeToMaxBitrateMap.get(expectedHeight);
|
|
8209
|
+
}
|
|
8210
|
+
function setCodecParameters(allCodecParameters, codecMimeType, newParameters) {
|
|
8211
|
+
if (!allCodecParameters.has(codecMimeType)) {
|
|
8212
|
+
allCodecParameters.set(codecMimeType, {});
|
|
8213
|
+
}
|
|
8214
|
+
const currentParameters = allCodecParameters.get(codecMimeType);
|
|
8215
|
+
Object.entries(newParameters).forEach(([param, value]) => {
|
|
8216
|
+
currentParameters[param] = value;
|
|
8217
|
+
});
|
|
8218
|
+
}
|
|
8219
|
+
function markCodecParametersForDeletion(allCodecParameters, codecMimeTypeToUpdate, codecParameters) {
|
|
8220
|
+
if (!allCodecParameters.has(codecMimeTypeToUpdate)) {
|
|
8221
|
+
allCodecParameters.set(codecMimeTypeToUpdate, {});
|
|
8222
|
+
}
|
|
8223
|
+
const currentParameters = allCodecParameters.get(codecMimeTypeToUpdate);
|
|
8224
|
+
codecParameters.forEach((param) => {
|
|
8225
|
+
currentParameters[param] = undefined;
|
|
8226
|
+
});
|
|
8209
8227
|
}
|
|
8210
8228
|
|
|
8211
8229
|
/******************************************************************************
|
|
@@ -10439,16 +10457,17 @@ function addVlaExtension(mediaDescription) {
|
|
|
10439
10457
|
mediaDescription.addExtension({ uri: vlaExtensionUri });
|
|
10440
10458
|
}
|
|
10441
10459
|
}
|
|
10442
|
-
function
|
|
10443
|
-
|
|
10460
|
+
function setFormatParameters(mediaDescription, codecMimeType, paramsMap) {
|
|
10461
|
+
const codecName = codecMimeType.split('/')[1].toLowerCase();
|
|
10462
|
+
Object.entries(paramsMap).forEach(([param, value]) => {
|
|
10444
10463
|
[...mediaDescription.codecs.values()]
|
|
10445
|
-
.filter((ci) => ci.name &&
|
|
10464
|
+
.filter((ci) => ci.name && codecName === ci.name.toLowerCase())
|
|
10446
10465
|
.forEach((ci) => {
|
|
10447
|
-
if (value ===
|
|
10466
|
+
if (value === undefined) {
|
|
10448
10467
|
ci.fmtParams.delete(param);
|
|
10449
10468
|
}
|
|
10450
10469
|
else {
|
|
10451
|
-
ci.fmtParams.set(param,
|
|
10470
|
+
ci.fmtParams.set(param, value);
|
|
10452
10471
|
}
|
|
10453
10472
|
});
|
|
10454
10473
|
});
|
|
@@ -10563,7 +10582,9 @@ class EgressSdpMunger {
|
|
|
10563
10582
|
if (options.simulcastEnabled) {
|
|
10564
10583
|
mediaDescription.addLine(new SsrcGroupLine('SIM', this.streamIds.map((streamId) => streamId.ssrc)));
|
|
10565
10584
|
}
|
|
10566
|
-
|
|
10585
|
+
this.customCodecParameters.forEach((codecParams, codecMimeType) => {
|
|
10586
|
+
setFormatParameters(mediaDescription, codecMimeType, codecParams);
|
|
10587
|
+
});
|
|
10567
10588
|
if (options.twccDisabled) {
|
|
10568
10589
|
disableTwcc(mediaDescription);
|
|
10569
10590
|
}
|
|
@@ -10593,7 +10614,9 @@ class EgressSdpMunger {
|
|
|
10593
10614
|
ci.fmtParams.set('usedtx', mungeOptions.dtxDisabled ? '0' : '1');
|
|
10594
10615
|
});
|
|
10595
10616
|
}
|
|
10596
|
-
|
|
10617
|
+
this.customCodecParameters.forEach((codecParams, codecMimeType) => {
|
|
10618
|
+
setFormatParameters(mediaDescription, codecMimeType, codecParams);
|
|
10619
|
+
});
|
|
10597
10620
|
}
|
|
10598
10621
|
getSenderIds() {
|
|
10599
10622
|
return this.streamIds;
|
|
@@ -10601,15 +10624,11 @@ class EgressSdpMunger {
|
|
|
10601
10624
|
getEncodingIndexForStreamId(streamId) {
|
|
10602
10625
|
return this.streamIds.findIndex((currStreamId) => areStreamIdsEqual(currStreamId, streamId));
|
|
10603
10626
|
}
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
this.customCodecParameters.set(param, value);
|
|
10607
|
-
});
|
|
10627
|
+
setCustomCodecParameters(codecMimeType, parameters) {
|
|
10628
|
+
setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
|
|
10608
10629
|
}
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
this.customCodecParameters.set(param, null);
|
|
10612
|
-
});
|
|
10630
|
+
markCustomCodecParametersForDeletion(codecMimeType, parameters) {
|
|
10631
|
+
markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
|
|
10613
10632
|
}
|
|
10614
10633
|
}
|
|
10615
10634
|
|
|
@@ -11095,7 +11114,6 @@ class EventEmitter$2 extends events$1.exports.EventEmitter {
|
|
|
11095
11114
|
class IngressSdpMunger {
|
|
11096
11115
|
constructor() {
|
|
11097
11116
|
this.customCodecParameters = new Map();
|
|
11098
|
-
this.customRtxCodecParameters = new Map();
|
|
11099
11117
|
this.ssrc = generateSsrc();
|
|
11100
11118
|
}
|
|
11101
11119
|
getReceiverId() {
|
|
@@ -11107,8 +11125,9 @@ class IngressSdpMunger {
|
|
|
11107
11125
|
logErrorAndThrow(WcmeErrorType.SDP_MUNGE_MISSING_CODECS, `No codecs present in m-line with MID ${mediaDescription.mid} after filtering.`);
|
|
11108
11126
|
}
|
|
11109
11127
|
removeMidRidExtensions(mediaDescription);
|
|
11110
|
-
|
|
11111
|
-
|
|
11128
|
+
this.customCodecParameters.forEach((codecParams, codecMimeType) => {
|
|
11129
|
+
setFormatParameters(mediaDescription, codecMimeType, codecParams);
|
|
11130
|
+
});
|
|
11112
11131
|
if (options.twccDisabled) {
|
|
11113
11132
|
disableTwcc(mediaDescription);
|
|
11114
11133
|
}
|
|
@@ -11129,17 +11148,16 @@ class IngressSdpMunger {
|
|
|
11129
11148
|
if (retainCandidatesByTransportType(mediaDescription, ['udp', 'tcp'])) {
|
|
11130
11149
|
logger.log(`Some unsupported remote candidates have been removed from mid ${mediaDescription.mid}`);
|
|
11131
11150
|
}
|
|
11132
|
-
|
|
11151
|
+
const rtxParams = this.customCodecParameters.get(MediaCodecMimeType.RTX);
|
|
11152
|
+
if (rtxParams) {
|
|
11153
|
+
setFormatParameters(mediaDescription, MediaCodecMimeType.RTX, rtxParams);
|
|
11154
|
+
}
|
|
11133
11155
|
}
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
this.customCodecParameters.set(param, value);
|
|
11137
|
-
});
|
|
11156
|
+
setCustomCodecParameters(codecMimeType, parameters) {
|
|
11157
|
+
setCodecParameters(this.customCodecParameters, codecMimeType, parameters);
|
|
11138
11158
|
}
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
this.customRtxCodecParameters.set(param, value);
|
|
11142
|
-
});
|
|
11159
|
+
markCustomCodecParametersForDeletion(codecMimeType, parameters) {
|
|
11160
|
+
markCodecParametersForDeletion(this.customCodecParameters, codecMimeType, parameters);
|
|
11143
11161
|
}
|
|
11144
11162
|
reset() {
|
|
11145
11163
|
this.ssrc = generateSsrc();
|
|
@@ -11452,11 +11470,8 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
11452
11470
|
this.metadata.lastActiveSpeakerUpdateTimestamp = getCurrentTimestamp();
|
|
11453
11471
|
}
|
|
11454
11472
|
}
|
|
11455
|
-
|
|
11456
|
-
this.munger.
|
|
11457
|
-
}
|
|
11458
|
-
setRtxCodecParameters(parameters) {
|
|
11459
|
-
this.munger.setRtxCodecParameters(parameters);
|
|
11473
|
+
setCustomCodecParameters(codecMimeType, parameters) {
|
|
11474
|
+
this.munger.setCustomCodecParameters(codecMimeType, parameters);
|
|
11460
11475
|
}
|
|
11461
11476
|
}
|
|
11462
11477
|
ReceiveOnlyTransceiver.rid = '1';
|
|
@@ -15432,12 +15447,12 @@ class SendOnlyTransceiver extends Transceiver {
|
|
|
15432
15447
|
resetSdpMunger() {
|
|
15433
15448
|
this.munger.reset();
|
|
15434
15449
|
}
|
|
15435
|
-
|
|
15436
|
-
this.munger.
|
|
15450
|
+
setCustomCodecParameters(codecMimeType, codecParams) {
|
|
15451
|
+
this.munger.setCustomCodecParameters(codecMimeType, codecParams);
|
|
15437
15452
|
this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
|
|
15438
15453
|
}
|
|
15439
|
-
|
|
15440
|
-
this.munger.
|
|
15454
|
+
markCustomCodecParametersForDeletion(codecMimeType, parameters) {
|
|
15455
|
+
this.munger.markCustomCodecParametersForDeletion(codecMimeType, parameters);
|
|
15441
15456
|
this.negotiationNeeded.emit(OfferAnswerType.LocalOnly);
|
|
15442
15457
|
}
|
|
15443
15458
|
setSourceStateOverride(state) {
|
|
@@ -15498,12 +15513,26 @@ class SendSlot {
|
|
|
15498
15513
|
}
|
|
15499
15514
|
setCodecParameters(parameters) {
|
|
15500
15515
|
return __awaiter(this, void 0, void 0, function* () {
|
|
15501
|
-
|
|
15516
|
+
[MediaCodecMimeType.H264, MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
|
|
15517
|
+
this.setCustomCodecParameters(codecMimeType, parameters);
|
|
15518
|
+
});
|
|
15502
15519
|
});
|
|
15503
15520
|
}
|
|
15504
15521
|
deleteCodecParameters(parameters) {
|
|
15505
15522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
15506
|
-
|
|
15523
|
+
[MediaCodecMimeType.H264, MediaCodecMimeType.OPUS].forEach((codecMimeType) => {
|
|
15524
|
+
this.markCustomCodecParametersForDeletion(codecMimeType, parameters);
|
|
15525
|
+
});
|
|
15526
|
+
});
|
|
15527
|
+
}
|
|
15528
|
+
setCustomCodecParameters(codecMimeType, parameters) {
|
|
15529
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15530
|
+
this.sendTransceiver.setCustomCodecParameters(codecMimeType, parameters);
|
|
15531
|
+
});
|
|
15532
|
+
}
|
|
15533
|
+
markCustomCodecParametersForDeletion(codecMimeType, parameters) {
|
|
15534
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15535
|
+
this.sendTransceiver.markCustomCodecParametersForDeletion(codecMimeType, parameters);
|
|
15507
15536
|
});
|
|
15508
15537
|
}
|
|
15509
15538
|
setSourceStateOverride(state) {
|
|
@@ -15697,7 +15726,7 @@ function getWorkerManager() {
|
|
|
15697
15726
|
return WorkerManager.workerManagerInstance;
|
|
15698
15727
|
}
|
|
15699
15728
|
|
|
15700
|
-
function
|
|
15729
|
+
function mediaTypeToTrackKind(mediaType) {
|
|
15701
15730
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
|
|
15702
15731
|
? MediaStreamTrackKind.Video
|
|
15703
15732
|
: MediaStreamTrackKind.Audio;
|
|
@@ -15767,9 +15796,10 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
15767
15796
|
const slidesSceneId = generateSceneId();
|
|
15768
15797
|
const videoMainEncodingOptions = this.getVideoEncodingOptions(MediaContent.Main);
|
|
15769
15798
|
const videoSlidesEncodingOptions = this.getVideoEncodingOptions(MediaContent.Slides);
|
|
15770
|
-
this.
|
|
15799
|
+
const sendVideoCodecParams = this.getCustomSendVideoCodecParams();
|
|
15800
|
+
this.createSendTransceiver(MediaType.VideoMain, mainSceneId, videoMainEncodingOptions, sendVideoCodecParams);
|
|
15771
15801
|
this.createSendTransceiver(MediaType.AudioMain, mainSceneId);
|
|
15772
|
-
this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions);
|
|
15802
|
+
this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions, sendVideoCodecParams);
|
|
15773
15803
|
this.createSendTransceiver(MediaType.AudioSlides, slidesSceneId);
|
|
15774
15804
|
}
|
|
15775
15805
|
startWorkerIfNeeded() {
|
|
@@ -15847,10 +15877,29 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
15847
15877
|
]
|
|
15848
15878
|
: [{ active: false }];
|
|
15849
15879
|
}
|
|
15850
|
-
|
|
15880
|
+
getCustomSendVideoCodecParams() {
|
|
15881
|
+
return {
|
|
15882
|
+
[MediaCodecMimeType.H264]: {
|
|
15883
|
+
'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
|
|
15884
|
+
'max-mbps': `${defaultMaxVideoEncodeMbps}`,
|
|
15885
|
+
'max-fs': `${defaultMaxVideoEncodeFrameSize}`,
|
|
15886
|
+
},
|
|
15887
|
+
};
|
|
15888
|
+
}
|
|
15889
|
+
getCustomReceiveVideoCodecParams(mediaType) {
|
|
15890
|
+
return {
|
|
15891
|
+
[MediaCodecMimeType.H264]: {
|
|
15892
|
+
'sps-pps-idr-in-keyframe': '1',
|
|
15893
|
+
},
|
|
15894
|
+
[MediaCodecMimeType.RTX]: {
|
|
15895
|
+
'rtx-time': mediaType === MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
|
|
15896
|
+
},
|
|
15897
|
+
};
|
|
15898
|
+
}
|
|
15899
|
+
createSendTransceiver(mediaType, sceneId, sendEncodingsOptions, codecParams) {
|
|
15851
15900
|
let rtcRtpTransceiver;
|
|
15852
15901
|
try {
|
|
15853
|
-
rtcRtpTransceiver = this.pc.addTransceiver(
|
|
15902
|
+
rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
|
|
15854
15903
|
direction: 'sendrecv',
|
|
15855
15904
|
sendEncodings: sendEncodingsOptions,
|
|
15856
15905
|
});
|
|
@@ -15869,14 +15918,12 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
15869
15918
|
munger,
|
|
15870
15919
|
csi,
|
|
15871
15920
|
});
|
|
15872
|
-
let codecParameters = {
|
|
15873
|
-
'x-google-start-bitrate': `${this.options.preferredStartingBitrateKbps}`,
|
|
15874
|
-
};
|
|
15875
15921
|
if (getMediaFamily(mediaType) === MediaFamily.Video) {
|
|
15876
15922
|
transceiver.rtxEnabled = true;
|
|
15877
|
-
codecParameters = Object.assign(Object.assign({}, codecParameters), { 'max-mbps': `${defaultMaxVideoEncodeMbps}`, 'max-fs': `${defaultMaxVideoEncodeFrameSize}` });
|
|
15878
15923
|
}
|
|
15879
|
-
|
|
15924
|
+
Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
|
|
15925
|
+
transceiver.setCustomCodecParameters(codec, params);
|
|
15926
|
+
});
|
|
15880
15927
|
transceiver.twccDisabled =
|
|
15881
15928
|
getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
|
|
15882
15929
|
transceiver.dtxDisabled = mediaType !== MediaType.AudioMain || this.options.disableAudioMainDtx;
|
|
@@ -16177,8 +16224,8 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16177
16224
|
static getEncodedTransformId(mediaType, mid) {
|
|
16178
16225
|
return `INBOUND-${mediaType}-${mid}`;
|
|
16179
16226
|
}
|
|
16180
|
-
createReceiveTransceiver(mediaType) {
|
|
16181
|
-
const rtcRtpTransceiver = this.pc.addTransceiver(
|
|
16227
|
+
createReceiveTransceiver(mediaType, codecParams) {
|
|
16228
|
+
const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
|
|
16182
16229
|
direction: 'recvonly',
|
|
16183
16230
|
});
|
|
16184
16231
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
@@ -16206,14 +16253,9 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16206
16253
|
logger.warn(`Failed to setup encoded transform for audio level monitoring of mid=${mid}: ${e}`);
|
|
16207
16254
|
}
|
|
16208
16255
|
}
|
|
16209
|
-
|
|
16210
|
-
recvOnlyTransceiver.
|
|
16211
|
-
|
|
16212
|
-
});
|
|
16213
|
-
recvOnlyTransceiver.setRtxCodecParameters({
|
|
16214
|
-
'rtx-time': mediaType === MediaType.VideoMain ? defaultVideoMainRtxTime : defaultVideoSlidesRtxTime,
|
|
16215
|
-
});
|
|
16216
|
-
}
|
|
16256
|
+
Object.entries(codecParams !== null && codecParams !== void 0 ? codecParams : {}).forEach(([codec, params]) => {
|
|
16257
|
+
recvOnlyTransceiver.setCustomCodecParameters(codec, params);
|
|
16258
|
+
});
|
|
16217
16259
|
recvOnlyTransceiver.twccDisabled =
|
|
16218
16260
|
getMediaFamily(mediaType) === MediaFamily.Audio ? this.options.disableAudioTwcc : false;
|
|
16219
16261
|
this.recvTransceivers.set(mediaType, [
|
|
@@ -16232,8 +16274,11 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16232
16274
|
return new Promise((createReceiveSlotsResolve) => {
|
|
16233
16275
|
this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
|
|
16234
16276
|
const createdReceiveOnlyTransceivers = [];
|
|
16277
|
+
const codecParams = mediaTypeToTrackKind(mediaType) === MediaStreamTrackKind.Video
|
|
16278
|
+
? this.getCustomReceiveVideoCodecParams(mediaType)
|
|
16279
|
+
: undefined;
|
|
16235
16280
|
for (let i = 0; i < count; i++) {
|
|
16236
|
-
const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType);
|
|
16281
|
+
const recvOnlyTransceiver = this.createReceiveTransceiver(mediaType, codecParams);
|
|
16237
16282
|
createdReceiveOnlyTransceivers.push(recvOnlyTransceiver);
|
|
16238
16283
|
}
|
|
16239
16284
|
if (this.pc.getRemoteDescription()) {
|
|
@@ -16610,7 +16655,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16610
16655
|
const mediaContent = getMediaContent(mediaType);
|
|
16611
16656
|
const sceneId = mediaContent === MediaContent.Main ? mainSceneId : slidesSceneId;
|
|
16612
16657
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
16613
|
-
transceiver.replaceTransceiver(this.pc.addTransceiver(
|
|
16658
|
+
transceiver.replaceTransceiver(this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
|
|
16614
16659
|
direction: 'sendrecv',
|
|
16615
16660
|
sendEncodings: getMediaFamily(mediaType) === MediaFamily.Video
|
|
16616
16661
|
? this.getVideoEncodingOptions(mediaContent)
|
|
@@ -16625,7 +16670,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16625
16670
|
this.recvTransceivers.forEach((transceivers, mediaType) => {
|
|
16626
16671
|
transceivers.forEach((t) => {
|
|
16627
16672
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
16628
|
-
const rtcRtpTransceiver = this.pc.addTransceiver(
|
|
16673
|
+
const rtcRtpTransceiver = this.pc.addTransceiver(mediaTypeToTrackKind(mediaType), {
|
|
16629
16674
|
direction: 'recvonly',
|
|
16630
16675
|
});
|
|
16631
16676
|
t.replaceTransceiver(rtcRtpTransceiver);
|