@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/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();
|
|
@@ -9171,6 +9189,15 @@ function injectJmpAttributes(parsedSdp, csiMap, streamSignalingMode) {
|
|
|
9171
9189
|
}
|
|
9172
9190
|
});
|
|
9173
9191
|
}
|
|
9192
|
+
function injectDummyCandidates(parsedSdp) {
|
|
9193
|
+
parsedSdp.media.forEach((mLine) => {
|
|
9194
|
+
if (mLine.iceInfo.candidates.length === 0) {
|
|
9195
|
+
mLine.addLine(new CandidateLine('dummy1', 1, 'udp', 1, '0.0.0.0', 1, 'host'));
|
|
9196
|
+
mLine.addLine(new CandidateLine('dummy2', 2, 'tcp', 2, '0.0.0.0', 2, 'host'));
|
|
9197
|
+
mLine.addLine(new CandidateLine('dummy3', 3, 'udp', 3, '0.0.0.0', 3, 'relay'));
|
|
9198
|
+
}
|
|
9199
|
+
});
|
|
9200
|
+
}
|
|
9174
9201
|
function hasSimulcast(av) {
|
|
9175
9202
|
return !!av.simulcast || av.ssrcGroups.map((sg) => sg.semantics).some((sem) => sem === 'SIM');
|
|
9176
9203
|
}
|
|
@@ -13105,59 +13132,6 @@ function setLogHandler(logHandler) {
|
|
|
13105
13132
|
Logger$2.setHandler(logHandler);
|
|
13106
13133
|
}
|
|
13107
13134
|
|
|
13108
|
-
function deepCopy(source) {
|
|
13109
|
-
return Array.isArray(source)
|
|
13110
|
-
? source.map((item) => deepCopy(item))
|
|
13111
|
-
: source instanceof Map
|
|
13112
|
-
? new Map(source)
|
|
13113
|
-
: source instanceof Date
|
|
13114
|
-
? new Date(source.getTime())
|
|
13115
|
-
: source && typeof source === 'object'
|
|
13116
|
-
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
13117
|
-
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop));
|
|
13118
|
-
o[prop] = deepCopy(source[prop]);
|
|
13119
|
-
return o;
|
|
13120
|
-
}, Object.create(Object.getPrototypeOf(source)))
|
|
13121
|
-
: source;
|
|
13122
|
-
}
|
|
13123
|
-
|
|
13124
|
-
function matchMlinesInAnswer(parsedOffer, parsedAnswer, streamSignalerManager) {
|
|
13125
|
-
parsedAnswer.session.groups = parsedOffer.session.groups;
|
|
13126
|
-
parsedAnswer.media = parsedOffer.media.map((offerMline) => {
|
|
13127
|
-
if (!offerMline.mid) {
|
|
13128
|
-
throw new Error(`Offer mline is missing MID`);
|
|
13129
|
-
}
|
|
13130
|
-
const answerMline = parsedAnswer.media.find((m) => m.mid === offerMline.mid);
|
|
13131
|
-
if (answerMline) {
|
|
13132
|
-
if (answerMline instanceof AvMediaDescription) {
|
|
13133
|
-
[...answerMline.codecs.values()].forEach((ci) => {
|
|
13134
|
-
ci.fmtParams.set('x-google-start-bitrate', '60000');
|
|
13135
|
-
});
|
|
13136
|
-
}
|
|
13137
|
-
return answerMline;
|
|
13138
|
-
}
|
|
13139
|
-
if (!(offerMline instanceof AvMediaDescription)) {
|
|
13140
|
-
throw new Error(`Answer is missing a non-media mline: ${offerMline.mid}`);
|
|
13141
|
-
}
|
|
13142
|
-
const startingMline = parsedAnswer.avMedia.find((m) => m.type === offerMline.type);
|
|
13143
|
-
if (!startingMline) {
|
|
13144
|
-
throw new Error(`Answer has no mline of type ${offerMline.type}, can't generate synthetic answer mline for mid ${offerMline.mid}`);
|
|
13145
|
-
}
|
|
13146
|
-
const fakeCorrespondingMline = deepCopy(startingMline);
|
|
13147
|
-
fakeCorrespondingMline.mid = offerMline.mid;
|
|
13148
|
-
fakeCorrespondingMline.simulcast = undefined;
|
|
13149
|
-
if (offerMline.direction === 'sendrecv' || offerMline.direction === 'sendonly') {
|
|
13150
|
-
fakeCorrespondingMline.direction = 'recvonly';
|
|
13151
|
-
}
|
|
13152
|
-
if (offerMline.direction === 'recvonly') {
|
|
13153
|
-
fakeCorrespondingMline.direction = 'sendonly';
|
|
13154
|
-
const ingressSignaler = streamSignalerManager.getIngressStreamSignalerOrThrow(offerMline.mid);
|
|
13155
|
-
ingressSignaler.signalRemoteStreams(fakeCorrespondingMline);
|
|
13156
|
-
}
|
|
13157
|
-
return fakeCorrespondingMline;
|
|
13158
|
-
});
|
|
13159
|
-
}
|
|
13160
|
-
|
|
13161
13135
|
function toMediaStreamTrackKind(mediaType) {
|
|
13162
13136
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
|
|
13163
13137
|
? exports.MediaStreamTrackKind.Video
|
|
@@ -13244,7 +13218,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13244
13218
|
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.close();
|
|
13245
13219
|
this.pc = new PeerConnection({
|
|
13246
13220
|
iceServers: this.options.iceServers,
|
|
13247
|
-
bundlePolicy:
|
|
13221
|
+
bundlePolicy: this.options.bundlePolicy,
|
|
13248
13222
|
});
|
|
13249
13223
|
this.pc.on(PeerConnection.Events.ConnectionStateChange, (state) => this.emit(exports.MultistreamConnectionEventNames.ConnectionStateUpdate, state));
|
|
13250
13224
|
this.attachMetricsObserver();
|
|
@@ -13628,6 +13602,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13628
13602
|
}
|
|
13629
13603
|
return new Promise((createOfferResolve) => {
|
|
13630
13604
|
this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
|
|
13605
|
+
var _a;
|
|
13631
13606
|
if (this.setAnswerResolve !== undefined) {
|
|
13632
13607
|
throw new Error(`Tried to start a new createOffer flow before the old one had finished`);
|
|
13633
13608
|
}
|
|
@@ -13640,12 +13615,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13640
13615
|
}
|
|
13641
13616
|
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
13642
13617
|
yield this.pc.setLocalDescription(offer);
|
|
13643
|
-
const
|
|
13644
|
-
|
|
13645
|
-
createOfferResolve({
|
|
13646
|
-
sdp: sdpToSend,
|
|
13647
|
-
type: offerWithCandidates.type,
|
|
13648
|
-
});
|
|
13618
|
+
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
13619
|
+
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
13649
13620
|
yield setAnswerPromise;
|
|
13650
13621
|
}));
|
|
13651
13622
|
});
|
|
@@ -13754,6 +13725,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13754
13725
|
});
|
|
13755
13726
|
injectJmpAttributes(parsed, csiMap, this.options.streamSignalingMode);
|
|
13756
13727
|
filterRecvOnlyMlines(parsed);
|
|
13728
|
+
injectDummyCandidates(parsed);
|
|
13757
13729
|
parsed.avMedia
|
|
13758
13730
|
.filter((av) => av.direction === 'sendrecv' && av.type === 'video')
|
|
13759
13731
|
.forEach((av) => {
|
|
@@ -13766,6 +13738,13 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13766
13738
|
});
|
|
13767
13739
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13768
13740
|
setupBundle(parsed, this.options.bundlePolicy, this.midMap);
|
|
13741
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13742
|
+
parsed.media.forEach((mline, index) => {
|
|
13743
|
+
if (index > 0) {
|
|
13744
|
+
mline.port = parsed.media[0].port;
|
|
13745
|
+
}
|
|
13746
|
+
});
|
|
13747
|
+
}
|
|
13769
13748
|
}
|
|
13770
13749
|
return parsed.toString();
|
|
13771
13750
|
}
|
|
@@ -13776,6 +13755,15 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13776
13755
|
matchMlinesInAnswer(parsedOffer, parsedAnswer, this.streamSignalerManager);
|
|
13777
13756
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13778
13757
|
setupBundle(parsedAnswer, this.options.bundlePolicy, this.midMap);
|
|
13758
|
+
if (this.options.bundlePolicy === 'max-bundle') {
|
|
13759
|
+
const { ufrag, pwd } = parsedAnswer.media[0].iceInfo;
|
|
13760
|
+
parsedAnswer.media.forEach((mline, index) => {
|
|
13761
|
+
if (index > 0) {
|
|
13762
|
+
mline.iceInfo.ufrag = ufrag;
|
|
13763
|
+
mline.iceInfo.pwd = pwd;
|
|
13764
|
+
}
|
|
13765
|
+
});
|
|
13766
|
+
}
|
|
13779
13767
|
}
|
|
13780
13768
|
return parsedAnswer.toString();
|
|
13781
13769
|
}
|