@webex/web-client-media-engine 2.0.4 → 2.0.6
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 +83 -95
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +83 -95
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -5130,41 +5130,6 @@ class PeerConnection extends EventEmitter$2 {
|
|
|
5130
5130
|
}
|
|
5131
5131
|
PeerConnection.Events = PeerConnectionEvents;
|
|
5132
5132
|
|
|
5133
|
-
/**
|
|
5134
|
-
* Wait until the given peer connection has finished gathering ICE candidates and, when it has,
|
|
5135
|
-
* return the local description with the candidates.
|
|
5136
|
-
*
|
|
5137
|
-
* @param peerConnection - The PeerConnection to use.
|
|
5138
|
-
* @returns A Promise that resolves with the local description with the ICE candidates in it.
|
|
5139
|
-
*/
|
|
5140
|
-
function getLocalDescriptionWithIceCandidates(peerConnection) {
|
|
5141
|
-
return new Promise((resolve, reject) => {
|
|
5142
|
-
/**
|
|
5143
|
-
* A helper method to retrieve the local description and resolve, if one is found, or reject
|
|
5144
|
-
* with an error if it's not.
|
|
5145
|
-
*/
|
|
5146
|
-
const getLocalDescAndResolve = () => {
|
|
5147
|
-
const localDesc = peerConnection.getLocalDescription();
|
|
5148
|
-
if (localDesc) {
|
|
5149
|
-
resolve(localDesc);
|
|
5150
|
-
}
|
|
5151
|
-
else {
|
|
5152
|
-
reject(new Error('Local description was null'));
|
|
5153
|
-
}
|
|
5154
|
-
};
|
|
5155
|
-
peerConnection.on(PeerConnection.Events.IceGatheringStateChange, (e) => {
|
|
5156
|
-
if (e.target.iceGatheringState === 'complete') {
|
|
5157
|
-
getLocalDescAndResolve();
|
|
5158
|
-
}
|
|
5159
|
-
// TODO(brian): throw an error if we see an error iceGatheringState
|
|
5160
|
-
});
|
|
5161
|
-
// It's possible ICE gathering is already done
|
|
5162
|
-
if (peerConnection.iceGatheringState === 'complete') {
|
|
5163
|
-
getLocalDescAndResolve();
|
|
5164
|
-
}
|
|
5165
|
-
});
|
|
5166
|
-
}
|
|
5167
|
-
|
|
5168
5133
|
var MediaCodecMimeType;
|
|
5169
5134
|
(function (MediaCodecMimeType) {
|
|
5170
5135
|
MediaCodecMimeType["H264"] = "video/H264";
|
|
@@ -9003,6 +8968,59 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
9003
8968
|
}
|
|
9004
8969
|
ReceiveOnlyTransceiver.rid = '1';
|
|
9005
8970
|
|
|
8971
|
+
function deepCopy(source) {
|
|
8972
|
+
return Array.isArray(source)
|
|
8973
|
+
? source.map((item) => deepCopy(item))
|
|
8974
|
+
: source instanceof Map
|
|
8975
|
+
? new Map(source)
|
|
8976
|
+
: source instanceof Date
|
|
8977
|
+
? new Date(source.getTime())
|
|
8978
|
+
: source && typeof source === 'object'
|
|
8979
|
+
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
8980
|
+
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop));
|
|
8981
|
+
o[prop] = deepCopy(source[prop]);
|
|
8982
|
+
return o;
|
|
8983
|
+
}, Object.create(Object.getPrototypeOf(source)))
|
|
8984
|
+
: source;
|
|
8985
|
+
}
|
|
8986
|
+
|
|
8987
|
+
function matchMlinesInAnswer(parsedOffer, parsedAnswer, streamSignalerManager) {
|
|
8988
|
+
parsedAnswer.session.groups = parsedOffer.session.groups;
|
|
8989
|
+
parsedAnswer.media = parsedOffer.media.map((offerMline) => {
|
|
8990
|
+
if (!offerMline.mid) {
|
|
8991
|
+
throw new Error(`Offer mline is missing MID`);
|
|
8992
|
+
}
|
|
8993
|
+
const answerMline = parsedAnswer.media.find((m) => m.mid === offerMline.mid);
|
|
8994
|
+
if (answerMline) {
|
|
8995
|
+
if (answerMline instanceof AvMediaDescription) {
|
|
8996
|
+
[...answerMline.codecs.values()].forEach((ci) => {
|
|
8997
|
+
ci.fmtParams.set('x-google-start-bitrate', '60000');
|
|
8998
|
+
});
|
|
8999
|
+
}
|
|
9000
|
+
return answerMline;
|
|
9001
|
+
}
|
|
9002
|
+
if (!(offerMline instanceof AvMediaDescription)) {
|
|
9003
|
+
throw new Error(`Answer is missing a non-media mline: ${offerMline.mid}`);
|
|
9004
|
+
}
|
|
9005
|
+
const startingMline = parsedAnswer.avMedia.find((m) => m.type === offerMline.type);
|
|
9006
|
+
if (!startingMline) {
|
|
9007
|
+
throw new Error(`Answer has no mline of type ${offerMline.type}, can't generate synthetic answer mline for mid ${offerMline.mid}`);
|
|
9008
|
+
}
|
|
9009
|
+
const fakeCorrespondingMline = deepCopy(startingMline);
|
|
9010
|
+
fakeCorrespondingMline.mid = offerMline.mid;
|
|
9011
|
+
fakeCorrespondingMline.simulcast = undefined;
|
|
9012
|
+
if (offerMline.direction === 'sendrecv' || offerMline.direction === 'sendonly') {
|
|
9013
|
+
fakeCorrespondingMline.direction = 'recvonly';
|
|
9014
|
+
}
|
|
9015
|
+
if (offerMline.direction === 'recvonly') {
|
|
9016
|
+
fakeCorrespondingMline.direction = 'sendonly';
|
|
9017
|
+
const ingressSignaler = streamSignalerManager.getIngressStreamSignalerOrThrow(offerMline.mid);
|
|
9018
|
+
ingressSignaler.signalRemoteStreams(fakeCorrespondingMline);
|
|
9019
|
+
}
|
|
9020
|
+
return fakeCorrespondingMline;
|
|
9021
|
+
});
|
|
9022
|
+
}
|
|
9023
|
+
|
|
9006
9024
|
class JmpLine extends Line {
|
|
9007
9025
|
constructor(versions) {
|
|
9008
9026
|
super();
|
|
@@ -9167,6 +9185,15 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
|
|
|
9167
9185
|
}
|
|
9168
9186
|
});
|
|
9169
9187
|
}
|
|
9188
|
+
function injectDummyCandidates(parsedSdp) {
|
|
9189
|
+
parsedSdp.media.forEach((mLine) => {
|
|
9190
|
+
if (mLine.iceInfo.candidates.length === 0) {
|
|
9191
|
+
mLine.addLine(new CandidateLine('dummy1', 1, 'udp', 1, '0.0.0.0', 1, 'host'));
|
|
9192
|
+
mLine.addLine(new CandidateLine('dummy2', 2, 'tcp', 2, '0.0.0.0', 2, 'host'));
|
|
9193
|
+
mLine.addLine(new CandidateLine('dummy3', 3, 'udp', 3, '0.0.0.0', 3, 'relay'));
|
|
9194
|
+
}
|
|
9195
|
+
});
|
|
9196
|
+
}
|
|
9170
9197
|
function hasSimulcast(av) {
|
|
9171
9198
|
return !!av.simulcast || av.ssrcGroups.map((sg) => sg.semantics).some((sem) => sem === 'SIM');
|
|
9172
9199
|
}
|
|
@@ -13101,59 +13128,6 @@ function setLogHandler(logHandler) {
|
|
|
13101
13128
|
Logger$2.setHandler(logHandler);
|
|
13102
13129
|
}
|
|
13103
13130
|
|
|
13104
|
-
function deepCopy(source) {
|
|
13105
|
-
return Array.isArray(source)
|
|
13106
|
-
? source.map((item) => deepCopy(item))
|
|
13107
|
-
: source instanceof Map
|
|
13108
|
-
? new Map(source)
|
|
13109
|
-
: source instanceof Date
|
|
13110
|
-
? new Date(source.getTime())
|
|
13111
|
-
: source && typeof source === 'object'
|
|
13112
|
-
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
13113
|
-
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop));
|
|
13114
|
-
o[prop] = deepCopy(source[prop]);
|
|
13115
|
-
return o;
|
|
13116
|
-
}, Object.create(Object.getPrototypeOf(source)))
|
|
13117
|
-
: source;
|
|
13118
|
-
}
|
|
13119
|
-
|
|
13120
|
-
function matchMlinesInAnswer(parsedOffer, parsedAnswer, streamSignalerManager) {
|
|
13121
|
-
parsedAnswer.session.groups = parsedOffer.session.groups;
|
|
13122
|
-
parsedAnswer.media = parsedOffer.media.map((offerMline) => {
|
|
13123
|
-
if (!offerMline.mid) {
|
|
13124
|
-
throw new Error(`Offer mline is missing MID`);
|
|
13125
|
-
}
|
|
13126
|
-
const answerMline = parsedAnswer.media.find((m) => m.mid === offerMline.mid);
|
|
13127
|
-
if (answerMline) {
|
|
13128
|
-
if (answerMline instanceof AvMediaDescription) {
|
|
13129
|
-
[...answerMline.codecs.values()].forEach((ci) => {
|
|
13130
|
-
ci.fmtParams.set('x-google-start-bitrate', '60000');
|
|
13131
|
-
});
|
|
13132
|
-
}
|
|
13133
|
-
return answerMline;
|
|
13134
|
-
}
|
|
13135
|
-
if (!(offerMline instanceof AvMediaDescription)) {
|
|
13136
|
-
throw new Error(`Answer is missing a non-media mline: ${offerMline.mid}`);
|
|
13137
|
-
}
|
|
13138
|
-
const startingMline = parsedAnswer.avMedia.find((m) => m.type === offerMline.type);
|
|
13139
|
-
if (!startingMline) {
|
|
13140
|
-
throw new Error(`Answer has no mline of type ${offerMline.type}, can't generate synthetic answer mline for mid ${offerMline.mid}`);
|
|
13141
|
-
}
|
|
13142
|
-
const fakeCorrespondingMline = deepCopy(startingMline);
|
|
13143
|
-
fakeCorrespondingMline.mid = offerMline.mid;
|
|
13144
|
-
fakeCorrespondingMline.simulcast = undefined;
|
|
13145
|
-
if (offerMline.direction === 'sendrecv' || offerMline.direction === 'sendonly') {
|
|
13146
|
-
fakeCorrespondingMline.direction = 'recvonly';
|
|
13147
|
-
}
|
|
13148
|
-
if (offerMline.direction === 'recvonly') {
|
|
13149
|
-
fakeCorrespondingMline.direction = 'sendonly';
|
|
13150
|
-
const ingressSignaler = streamSignalerManager.getIngressStreamSignalerOrThrow(offerMline.mid);
|
|
13151
|
-
ingressSignaler.signalRemoteStreams(fakeCorrespondingMline);
|
|
13152
|
-
}
|
|
13153
|
-
return fakeCorrespondingMline;
|
|
13154
|
-
});
|
|
13155
|
-
}
|
|
13156
|
-
|
|
13157
13131
|
function toMediaStreamTrackKind(mediaType) {
|
|
13158
13132
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
|
|
13159
13133
|
? MediaStreamTrackKind.Video
|
|
@@ -13240,7 +13214,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13240
13214
|
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.close();
|
|
13241
13215
|
this.pc = new PeerConnection({
|
|
13242
13216
|
iceServers: this.options.iceServers,
|
|
13243
|
-
bundlePolicy:
|
|
13217
|
+
bundlePolicy: this.options.bundlePolicy,
|
|
13244
13218
|
});
|
|
13245
13219
|
this.pc.on(PeerConnection.Events.ConnectionStateChange, (state) => this.emit(MultistreamConnectionEventNames.ConnectionStateUpdate, state));
|
|
13246
13220
|
this.attachMetricsObserver();
|
|
@@ -13624,6 +13598,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13624
13598
|
}
|
|
13625
13599
|
return new Promise((createOfferResolve) => {
|
|
13626
13600
|
this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
|
|
13601
|
+
var _a;
|
|
13627
13602
|
if (this.setAnswerResolve !== undefined) {
|
|
13628
13603
|
throw new Error(`Tried to start a new createOffer flow before the old one had finished`);
|
|
13629
13604
|
}
|
|
@@ -13636,12 +13611,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13636
13611
|
}
|
|
13637
13612
|
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
13638
13613
|
yield this.pc.setLocalDescription(offer);
|
|
13639
|
-
const
|
|
13640
|
-
|
|
13641
|
-
createOfferResolve({
|
|
13642
|
-
sdp: sdpToSend,
|
|
13643
|
-
type: offerWithCandidates.type,
|
|
13644
|
-
});
|
|
13614
|
+
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
13615
|
+
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
13645
13616
|
yield setAnswerPromise;
|
|
13646
13617
|
}));
|
|
13647
13618
|
});
|
|
@@ -13750,6 +13721,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13750
13721
|
});
|
|
13751
13722
|
injectJmpAttributes(parsed, csiMap, this.options.streamSignalingMode);
|
|
13752
13723
|
filterRecvOnlyMlines(parsed);
|
|
13724
|
+
injectDummyCandidates(parsed);
|
|
13753
13725
|
parsed.avMedia
|
|
13754
13726
|
.filter((av) => av.direction === 'sendrecv' && av.type === 'video')
|
|
13755
13727
|
.forEach((av) => {
|
|
@@ -13762,6 +13734,13 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13762
13734
|
});
|
|
13763
13735
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13764
13736
|
setupBundle(parsed, this.options.bundlePolicy, this.midMap);
|
|
13737
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13738
|
+
parsed.media.forEach((mline, index) => {
|
|
13739
|
+
if (index > 0) {
|
|
13740
|
+
mline.port = parsed.media[0].port;
|
|
13741
|
+
}
|
|
13742
|
+
});
|
|
13743
|
+
}
|
|
13765
13744
|
}
|
|
13766
13745
|
return parsed.toString();
|
|
13767
13746
|
}
|
|
@@ -13772,6 +13751,15 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13772
13751
|
matchMlinesInAnswer(parsedOffer, parsedAnswer, this.streamSignalerManager);
|
|
13773
13752
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13774
13753
|
setupBundle(parsedAnswer, this.options.bundlePolicy, this.midMap);
|
|
13754
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13755
|
+
const { ufrag, pwd } = parsedAnswer.media[0].iceInfo;
|
|
13756
|
+
parsedAnswer.media.forEach((mline, index) => {
|
|
13757
|
+
if (index > 0) {
|
|
13758
|
+
mline.iceInfo.ufrag = ufrag;
|
|
13759
|
+
mline.iceInfo.pwd = pwd;
|
|
13760
|
+
}
|
|
13761
|
+
});
|
|
13762
|
+
}
|
|
13775
13763
|
}
|
|
13776
13764
|
return parsedAnswer.toString();
|
|
13777
13765
|
}
|