@webex/web-client-media-engine 2.0.4 → 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 +81 -95
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +81 -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,13 @@ 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('dummy', 1, 'udp', 1, '0.0.0.0', 1, 'host'));
|
|
9196
|
+
}
|
|
9197
|
+
});
|
|
9198
|
+
}
|
|
9174
9199
|
function hasSimulcast(av) {
|
|
9175
9200
|
return !!av.simulcast || av.ssrcGroups.map((sg) => sg.semantics).some((sem) => sem === 'SIM');
|
|
9176
9201
|
}
|
|
@@ -13105,59 +13130,6 @@ function setLogHandler(logHandler) {
|
|
|
13105
13130
|
Logger$2.setHandler(logHandler);
|
|
13106
13131
|
}
|
|
13107
13132
|
|
|
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
13133
|
function toMediaStreamTrackKind(mediaType) {
|
|
13162
13134
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
|
|
13163
13135
|
? exports.MediaStreamTrackKind.Video
|
|
@@ -13244,7 +13216,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13244
13216
|
(_a = this.pc) === null || _a === void 0 ? void 0 : _a.close();
|
|
13245
13217
|
this.pc = new PeerConnection({
|
|
13246
13218
|
iceServers: this.options.iceServers,
|
|
13247
|
-
bundlePolicy:
|
|
13219
|
+
bundlePolicy: this.options.bundlePolicy,
|
|
13248
13220
|
});
|
|
13249
13221
|
this.pc.on(PeerConnection.Events.ConnectionStateChange, (state) => this.emit(exports.MultistreamConnectionEventNames.ConnectionStateUpdate, state));
|
|
13250
13222
|
this.attachMetricsObserver();
|
|
@@ -13628,6 +13600,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13628
13600
|
}
|
|
13629
13601
|
return new Promise((createOfferResolve) => {
|
|
13630
13602
|
this.offerAnswerQueue.push(() => __awaiter(this, void 0, void 0, function* () {
|
|
13603
|
+
var _a;
|
|
13631
13604
|
if (this.setAnswerResolve !== undefined) {
|
|
13632
13605
|
throw new Error(`Tried to start a new createOffer flow before the old one had finished`);
|
|
13633
13606
|
}
|
|
@@ -13640,12 +13613,8 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13640
13613
|
}
|
|
13641
13614
|
offer.sdp = this.preProcessLocalOffer(offer.sdp);
|
|
13642
13615
|
yield this.pc.setLocalDescription(offer);
|
|
13643
|
-
const
|
|
13644
|
-
|
|
13645
|
-
createOfferResolve({
|
|
13646
|
-
sdp: sdpToSend,
|
|
13647
|
-
type: offerWithCandidates.type,
|
|
13648
|
-
});
|
|
13616
|
+
const sdpToSend = this.prepareLocalOfferForRemoteServer((_a = this.pc.getLocalDescription()) === null || _a === void 0 ? void 0 : _a.sdp);
|
|
13617
|
+
createOfferResolve({ type: 'offer', sdp: sdpToSend });
|
|
13649
13618
|
yield setAnswerPromise;
|
|
13650
13619
|
}));
|
|
13651
13620
|
});
|
|
@@ -13754,6 +13723,7 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13754
13723
|
});
|
|
13755
13724
|
injectJmpAttributes(parsed, csiMap, this.options.streamSignalingMode);
|
|
13756
13725
|
filterRecvOnlyMlines(parsed);
|
|
13726
|
+
injectDummyCandidates(parsed);
|
|
13757
13727
|
parsed.avMedia
|
|
13758
13728
|
.filter((av) => av.direction === 'sendrecv' && av.type === 'video')
|
|
13759
13729
|
.forEach((av) => {
|
|
@@ -13766,6 +13736,13 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13766
13736
|
});
|
|
13767
13737
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13768
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
|
+
}
|
|
13769
13746
|
}
|
|
13770
13747
|
return parsed.toString();
|
|
13771
13748
|
}
|
|
@@ -13776,6 +13753,15 @@ class MultistreamConnection extends EventEmitter {
|
|
|
13776
13753
|
matchMlinesInAnswer(parsedOffer, parsedAnswer, this.streamSignalerManager);
|
|
13777
13754
|
if (getBrowserDetails().name === 'Firefox') {
|
|
13778
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
|
+
}
|
|
13779
13765
|
}
|
|
13780
13766
|
return parsedAnswer.toString();
|
|
13781
13767
|
}
|