@webex/web-client-media-engine 2.0.3 → 2.0.5
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 +91 -94
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +91 -94
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -5134,41 +5134,6 @@ class PeerConnection extends EventEmitter$2 {
|
|
|
5134
5134
|
}
|
|
5135
5135
|
PeerConnection.Events = PeerConnectionEvents;
|
|
5136
5136
|
|
|
5137
|
-
/**
|
|
5138
|
-
* Wait until the given peer connection has finished gathering ICE candidates and, when it has,
|
|
5139
|
-
* return the local description with the candidates.
|
|
5140
|
-
*
|
|
5141
|
-
* @param peerConnection - The PeerConnection to use.
|
|
5142
|
-
* @returns A Promise that resolves with the local description with the ICE candidates in it.
|
|
5143
|
-
*/
|
|
5144
|
-
function getLocalDescriptionWithIceCandidates(peerConnection) {
|
|
5145
|
-
return new Promise((resolve, reject) => {
|
|
5146
|
-
/**
|
|
5147
|
-
* A helper method to retrieve the local description and resolve, if one is found, or reject
|
|
5148
|
-
* with an error if it's not.
|
|
5149
|
-
*/
|
|
5150
|
-
const getLocalDescAndResolve = () => {
|
|
5151
|
-
const localDesc = peerConnection.getLocalDescription();
|
|
5152
|
-
if (localDesc) {
|
|
5153
|
-
resolve(localDesc);
|
|
5154
|
-
}
|
|
5155
|
-
else {
|
|
5156
|
-
reject(new Error('Local description was null'));
|
|
5157
|
-
}
|
|
5158
|
-
};
|
|
5159
|
-
peerConnection.on(PeerConnection.Events.IceGatheringStateChange, (e) => {
|
|
5160
|
-
if (e.target.iceGatheringState === 'complete') {
|
|
5161
|
-
getLocalDescAndResolve();
|
|
5162
|
-
}
|
|
5163
|
-
// TODO(brian): throw an error if we see an error iceGatheringState
|
|
5164
|
-
});
|
|
5165
|
-
// It's possible ICE gathering is already done
|
|
5166
|
-
if (peerConnection.iceGatheringState === 'complete') {
|
|
5167
|
-
getLocalDescAndResolve();
|
|
5168
|
-
}
|
|
5169
|
-
});
|
|
5170
|
-
}
|
|
5171
|
-
|
|
5172
5137
|
exports.MediaCodecMimeType = void 0;
|
|
5173
5138
|
(function (MediaCodecMimeType) {
|
|
5174
5139
|
MediaCodecMimeType["H264"] = "video/H264";
|
|
@@ -9007,6 +8972,59 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
9007
8972
|
}
|
|
9008
8973
|
ReceiveOnlyTransceiver.rid = '1';
|
|
9009
8974
|
|
|
8975
|
+
function deepCopy(source) {
|
|
8976
|
+
return Array.isArray(source)
|
|
8977
|
+
? source.map((item) => deepCopy(item))
|
|
8978
|
+
: source instanceof Map
|
|
8979
|
+
? new Map(source)
|
|
8980
|
+
: source instanceof Date
|
|
8981
|
+
? new Date(source.getTime())
|
|
8982
|
+
: source && typeof source === 'object'
|
|
8983
|
+
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
8984
|
+
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop));
|
|
8985
|
+
o[prop] = deepCopy(source[prop]);
|
|
8986
|
+
return o;
|
|
8987
|
+
}, Object.create(Object.getPrototypeOf(source)))
|
|
8988
|
+
: source;
|
|
8989
|
+
}
|
|
8990
|
+
|
|
8991
|
+
function matchMlinesInAnswer(parsedOffer, parsedAnswer, streamSignalerManager) {
|
|
8992
|
+
parsedAnswer.session.groups = parsedOffer.session.groups;
|
|
8993
|
+
parsedAnswer.media = parsedOffer.media.map((offerMline) => {
|
|
8994
|
+
if (!offerMline.mid) {
|
|
8995
|
+
throw new Error(`Offer mline is missing MID`);
|
|
8996
|
+
}
|
|
8997
|
+
const answerMline = parsedAnswer.media.find((m) => m.mid === offerMline.mid);
|
|
8998
|
+
if (answerMline) {
|
|
8999
|
+
if (answerMline instanceof AvMediaDescription) {
|
|
9000
|
+
[...answerMline.codecs.values()].forEach((ci) => {
|
|
9001
|
+
ci.fmtParams.set('x-google-start-bitrate', '60000');
|
|
9002
|
+
});
|
|
9003
|
+
}
|
|
9004
|
+
return answerMline;
|
|
9005
|
+
}
|
|
9006
|
+
if (!(offerMline instanceof AvMediaDescription)) {
|
|
9007
|
+
throw new Error(`Answer is missing a non-media mline: ${offerMline.mid}`);
|
|
9008
|
+
}
|
|
9009
|
+
const startingMline = parsedAnswer.avMedia.find((m) => m.type === offerMline.type);
|
|
9010
|
+
if (!startingMline) {
|
|
9011
|
+
throw new Error(`Answer has no mline of type ${offerMline.type}, can't generate synthetic answer mline for mid ${offerMline.mid}`);
|
|
9012
|
+
}
|
|
9013
|
+
const fakeCorrespondingMline = deepCopy(startingMline);
|
|
9014
|
+
fakeCorrespondingMline.mid = offerMline.mid;
|
|
9015
|
+
fakeCorrespondingMline.simulcast = undefined;
|
|
9016
|
+
if (offerMline.direction === 'sendrecv' || offerMline.direction === 'sendonly') {
|
|
9017
|
+
fakeCorrespondingMline.direction = 'recvonly';
|
|
9018
|
+
}
|
|
9019
|
+
if (offerMline.direction === 'recvonly') {
|
|
9020
|
+
fakeCorrespondingMline.direction = 'sendonly';
|
|
9021
|
+
const ingressSignaler = streamSignalerManager.getIngressStreamSignalerOrThrow(offerMline.mid);
|
|
9022
|
+
ingressSignaler.signalRemoteStreams(fakeCorrespondingMline);
|
|
9023
|
+
}
|
|
9024
|
+
return fakeCorrespondingMline;
|
|
9025
|
+
});
|
|
9026
|
+
}
|
|
9027
|
+
|
|
9010
9028
|
class JmpLine extends Line {
|
|
9011
9029
|
constructor(versions) {
|
|
9012
9030
|
super();
|
|
@@ -9071,22 +9089,6 @@ DefaultSdpGrammar.addParser('a', JmpLine.fromSdpLine);
|
|
|
9071
9089
|
DefaultSdpGrammar.addParser('a', JmpSourceLine.fromSdpLine);
|
|
9072
9090
|
DefaultSdpGrammar.addParser('a', JmpStreamIdModeLine.fromSdpLine);
|
|
9073
9091
|
|
|
9074
|
-
function deepCopy(source) {
|
|
9075
|
-
return Array.isArray(source)
|
|
9076
|
-
? source.map((item) => deepCopy(item))
|
|
9077
|
-
: source instanceof Map
|
|
9078
|
-
? new Map(source)
|
|
9079
|
-
: source instanceof Date
|
|
9080
|
-
? new Date(source.getTime())
|
|
9081
|
-
: source && typeof source === 'object'
|
|
9082
|
-
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
9083
|
-
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop));
|
|
9084
|
-
o[prop] = deepCopy(source[prop]);
|
|
9085
|
-
return o;
|
|
9086
|
-
}, Object.create(Object.getPrototypeOf(source)))
|
|
9087
|
-
: source;
|
|
9088
|
-
}
|
|
9089
|
-
|
|
9090
9092
|
function getMediaTypeForMline(mLine) {
|
|
9091
9093
|
var _a, _b;
|
|
9092
9094
|
let mediaFamily;
|
|
@@ -9156,42 +9158,6 @@ function filterRecvOnlyMlines(parsedSdp) {
|
|
|
9156
9158
|
g.mids = g.mids.filter((m) => filteredMids.includes(m));
|
|
9157
9159
|
});
|
|
9158
9160
|
}
|
|
9159
|
-
function matchMlinesInAnswer(parsedOffer, parsedAnswer, streamSignalerManager) {
|
|
9160
|
-
parsedAnswer.session.groups = parsedOffer.session.groups;
|
|
9161
|
-
parsedAnswer.media = parsedOffer.media.map((offerMline) => {
|
|
9162
|
-
if (!offerMline.mid) {
|
|
9163
|
-
throw new Error(`Offer mline is missing MID`);
|
|
9164
|
-
}
|
|
9165
|
-
const answerMline = parsedAnswer.media.find((m) => m.mid === offerMline.mid);
|
|
9166
|
-
if (answerMline) {
|
|
9167
|
-
if (answerMline instanceof AvMediaDescription) {
|
|
9168
|
-
[...answerMline.codecs.values()].forEach((ci) => {
|
|
9169
|
-
ci.fmtParams.set('x-google-start-bitrate', '60000');
|
|
9170
|
-
});
|
|
9171
|
-
}
|
|
9172
|
-
return answerMline;
|
|
9173
|
-
}
|
|
9174
|
-
if (!(offerMline instanceof AvMediaDescription)) {
|
|
9175
|
-
throw new Error(`Answer is missing a non-media mline: ${offerMline.mid}`);
|
|
9176
|
-
}
|
|
9177
|
-
const startingMline = parsedAnswer.avMedia.find((m) => m.type === offerMline.type);
|
|
9178
|
-
if (!startingMline) {
|
|
9179
|
-
throw new Error(`Answer has no mline of type ${offerMline.type}, can't generate synthetic answer mline for mid ${offerMline.mid}`);
|
|
9180
|
-
}
|
|
9181
|
-
const fakeCorrespondingMline = deepCopy(startingMline);
|
|
9182
|
-
fakeCorrespondingMline.mid = offerMline.mid;
|
|
9183
|
-
fakeCorrespondingMline.simulcast = undefined;
|
|
9184
|
-
if (offerMline.direction === 'sendrecv' || offerMline.direction === 'sendonly') {
|
|
9185
|
-
fakeCorrespondingMline.direction = 'recvonly';
|
|
9186
|
-
}
|
|
9187
|
-
if (offerMline.direction === 'recvonly') {
|
|
9188
|
-
fakeCorrespondingMline.direction = 'sendonly';
|
|
9189
|
-
const ingressSignaler = streamSignalerManager.getIngressStreamSignalerOrThrow(offerMline.mid);
|
|
9190
|
-
ingressSignaler.signalRemoteStreams(fakeCorrespondingMline);
|
|
9191
|
-
}
|
|
9192
|
-
return fakeCorrespondingMline;
|
|
9193
|
-
});
|
|
9194
|
-
}
|
|
9195
9161
|
function injectContentTypes(sdp, contentTypeMap) {
|
|
9196
9162
|
contentTypeMap.forEach((mediaContent, mid) => {
|
|
9197
9163
|
const mline = sdp.media.find((m) => m.mid === mid);
|
|
@@ -9223,8 +9189,23 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
|
|
|
9223
9189
|
}
|
|
9224
9190
|
});
|
|
9225
9191
|
}
|
|
9192
|
+
function injectDummyCandidates(parsedSdp) {
|
|
9193
|
+
parsedSdp.media.forEach((mLine) => {
|
|
9194
|
+
if (mLine.iceInfo.candidates.length === 0) {
|
|
9195
|
+
mLine.addLine(new CandidateLine('dummy', 1, 'udp', 1, '0.0.0.0', 1, 'host'));
|
|
9196
|
+
}
|
|
9197
|
+
});
|
|
9198
|
+
}
|
|
9226
9199
|
function hasSimulcast(av) {
|
|
9227
9200
|
return !!av.simulcast || av.ssrcGroups.map((sg) => sg.semantics).some((sem) => sem === 'SIM');
|
|
9201
|
+
}
|
|
9202
|
+
function addVlaExtension(mLine) {
|
|
9203
|
+
const vlaUri = 'http://www.webrtc.org/experiments/rtp-hdrext/video-layers-allocation00';
|
|
9204
|
+
if (mLine.extMaps.findIndex((extMapLine) => extMapLine.uri === vlaUri) === -1) {
|
|
9205
|
+
const maxIdValue = Math.max(...mLine.extMaps.map((extMapLine) => extMapLine.id), 0);
|
|
9206
|
+
const videoLayersAllocationLine = new ExtMapLine(maxIdValue + 1, vlaUri, undefined);
|
|
9207
|
+
mLine.extMaps.push(videoLayersAllocationLine);
|
|
9208
|
+
}
|
|
9228
9209
|
}
|
|
9229
9210
|
|
|
9230
9211
|
class SendOnlyTransceiver extends Transceiver {
|
|
@@ -9386,6 +9367,7 @@ class RidEgressStreamSignaler {
|
|
|
9386
9367
|
if (simulcastEnabled) {
|
|
9387
9368
|
mLine.rids = this.streamIds.map((streamId, index) => new RidLine(streamId.rid, 'send', `max-fs=${simulcastMaxFrameSizes[index]}`));
|
|
9388
9369
|
mLine.simulcast = new SimulcastLine(SimulcastLayerList.fromString('low;medium;high'), new SimulcastLayerList());
|
|
9370
|
+
addVlaExtension(mLine);
|
|
9389
9371
|
}
|
|
9390
9372
|
}
|
|
9391
9373
|
getSenderIds() {
|
|
@@ -9492,6 +9474,7 @@ class SsrcEgressStreamSignaler {
|
|
|
9492
9474
|
});
|
|
9493
9475
|
if (simulcastEnabled) {
|
|
9494
9476
|
mLine.addLine(new SsrcGroupLine('SIM', this.streamIds.map((streamId) => streamId.ssrc)));
|
|
9477
|
+
addVlaExtension(mLine);
|
|
9495
9478
|
}
|
|
9496
9479
|
}
|
|
9497
9480
|
getSenderIds() {
|
|
@@ -13233,7 +13216,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13233
13216
|
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.close();
|
|
13234
13217
|
this.pc = new PeerConnection({
|
|
13235
13218
|
iceServers: this.options.iceServers,
|
|
13236
|
-
bundlePolicy:
|
|
13219
|
+
bundlePolicy: this.options.bundlePolicy,
|
|
13237
13220
|
});
|
|
13238
13221
|
this.pc.on(PeerConnection.Events.ConnectionStateChange, (state) => this.emit(exports.MultistreamConnectionEventNames.ConnectionStateUpdate, state));
|
|
13239
13222
|
this.attachMetricsObserver();
|
|
@@ -13617,6 +13600,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13617
13600
|
}
|
|
13618
13601
|
return new Promise((createOfferResolve) => {
|
|
13619
13602
|
this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
|
|
13603
|
+
var _a;
|
|
13620
13604
|
if (this.setAnswerResolve !== undefined) {
|
|
13621
13605
|
throw new Error(`Tried to start a new createOffer flow before the old one had finished`);
|
|
13622
13606
|
}
|
|
@@ -13629,12 +13613,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13629
13613
|
}
|
|
13630
13614
|
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
13631
13615
|
yield this.pc.setLocalDescription(offer);
|
|
13632
|
-
const
|
|
13633
|
-
|
|
13634
|
-
createOfferResolve({
|
|
13635
|
-
sdp: sdpToSend,
|
|
13636
|
-
type: offerWithCandidates.type,
|
|
13637
|
-
});
|
|
13616
|
+
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
13617
|
+
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
13638
13618
|
yield setAnswerPromise;
|
|
13639
13619
|
}));
|
|
13640
13620
|
});
|
|
@@ -13743,6 +13723,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13743
13723
|
});
|
|
13744
13724
|
injectJmpAttributes(parsed, csiMap, this.options.streamSignalingMode);
|
|
13745
13725
|
filterRecvOnlyMlines(parsed);
|
|
13726
|
+
injectDummyCandidates(parsed);
|
|
13746
13727
|
parsed.avMedia
|
|
13747
13728
|
.filter((av) => av.direction === 'sendrecv' && av.type === 'video')
|
|
13748
13729
|
.forEach((av) => {
|
|
@@ -13755,6 +13736,13 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13755
13736
|
});
|
|
13756
13737
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13757
13738
|
setupBundle(parsed, this.options.bundlePolicy, this.midMap);
|
|
13739
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13740
|
+
parsed.media.forEach((mline, index) => {
|
|
13741
|
+
if (index > 0) {
|
|
13742
|
+
mline.port = parsed.media[0].port;
|
|
13743
|
+
}
|
|
13744
|
+
});
|
|
13745
|
+
}
|
|
13758
13746
|
}
|
|
13759
13747
|
return parsed.toString();
|
|
13760
13748
|
}
|
|
@@ -13765,6 +13753,15 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13765
13753
|
matchMlinesInAnswer(parsedOffer, parsedAnswer, this.streamSignalerManager);
|
|
13766
13754
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13767
13755
|
setupBundle(parsedAnswer, this.options.bundlePolicy, this.midMap);
|
|
13756
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13757
|
+
const { ufrag, pwd } = parsedAnswer.media[0].iceInfo;
|
|
13758
|
+
parsedAnswer.media.forEach((mline, index) => {
|
|
13759
|
+
if (index > 0) {
|
|
13760
|
+
mline.iceInfo.ufrag = ufrag;
|
|
13761
|
+
mline.iceInfo.pwd = pwd;
|
|
13762
|
+
}
|
|
13763
|
+
});
|
|
13764
|
+
}
|
|
13768
13765
|
}
|
|
13769
13766
|
return parsedAnswer.toString();
|
|
13770
13767
|
}
|