livekit-client 1.2.0 → 1.2.3
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/livekit-client.esm.mjs +1007 -107
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/options.d.ts +5 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/room/DefaultReconnectPolicy.d.ts +8 -0
- package/dist/src/room/DefaultReconnectPolicy.d.ts.map +1 -0
- package/dist/src/room/PCTransport.d.ts +10 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +6 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/ReconnectPolicy.d.ts +23 -0
- package/dist/src/room/ReconnectPolicy.d.ts.map +1 -0
- package/dist/src/room/Room.d.ts +8 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +2 -2
- package/dist/src/room/participant/LocalParticipant.d.ts +3 -3
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/index.ts +2 -0
- package/src/options.ts +6 -0
- package/src/room/DefaultReconnectPolicy.ts +35 -0
- package/src/room/PCTransport.ts +113 -0
- package/src/room/RTCEngine.ts +79 -31
- package/src/room/ReconnectPolicy.ts +25 -0
- package/src/room/Room.ts +55 -30
- package/src/room/events.ts +2 -2
- package/src/room/participant/LocalParticipant.ts +56 -20
- package/src/room/participant/RemoteParticipant.ts +13 -0
- package/src/room/participant/publishUtils.ts +1 -1
- package/src/room/track/LocalVideoTrack.ts +0 -1
@@ -2997,7 +2997,7 @@ LongBits$2.prototype.length = function length() {
|
|
2997
2997
|
};
|
2998
2998
|
})(minimal$1);
|
2999
2999
|
|
3000
|
-
var writer = Writer$1;
|
3000
|
+
var writer$2 = Writer$1;
|
3001
3001
|
var util$4 = minimal$1;
|
3002
3002
|
var BufferWriter$1; // cyclic
|
3003
3003
|
|
@@ -3476,7 +3476,7 @@ Writer$1._configure = function (BufferWriter_) {
|
|
3476
3476
|
|
3477
3477
|
var writer_buffer = BufferWriter; // extends Writer
|
3478
3478
|
|
3479
|
-
var Writer = writer;
|
3479
|
+
var Writer = writer$2;
|
3480
3480
|
(BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter;
|
3481
3481
|
var util$3 = minimal$1;
|
3482
3482
|
/**
|
@@ -4193,7 +4193,7 @@ var roots = {};
|
|
4193
4193
|
|
4194
4194
|
protobuf.build = "minimal"; // Serialization
|
4195
4195
|
|
4196
|
-
protobuf.Writer = writer;
|
4196
|
+
protobuf.Writer = writer$2;
|
4197
4197
|
protobuf.BufferWriter = writer_buffer;
|
4198
4198
|
protobuf.Reader = reader;
|
4199
4199
|
protobuf.BufferReader = reader_buffer; // Utility
|
@@ -9997,8 +9997,8 @@ var RoomEvent;
|
|
9997
9997
|
* When we have encountered an error while attempting to create a track.
|
9998
9998
|
* The errors take place in getUserMedia().
|
9999
9999
|
* Use MediaDeviceFailure.getFailure(error) to get the reason of failure.
|
10000
|
-
* [[
|
10001
|
-
* an error while creating the audio or video track respectively.
|
10000
|
+
* [[LocalParticipant.lastCameraError]] and [[LocalParticipant.lastMicrophoneError]]
|
10001
|
+
* will indicate if it had an error while creating the audio or video track respectively.
|
10002
10002
|
*
|
10003
10003
|
* args: (error: Error)
|
10004
10004
|
*/
|
@@ -10265,7 +10265,7 @@ function computeBitrate(currentStats, prevStats) {
|
|
10265
10265
|
return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
|
10266
10266
|
}
|
10267
10267
|
|
10268
|
-
var version$1 = "1.2.
|
10268
|
+
var version$1 = "1.2.3";
|
10269
10269
|
|
10270
10270
|
const version = version$1;
|
10271
10271
|
const protocolVersion = 8;
|
@@ -12016,8 +12016,6 @@ class LocalVideoTrack extends LocalTrack {
|
|
12016
12016
|
}
|
12017
12017
|
|
12018
12018
|
stop() {
|
12019
|
-
this.sender = undefined;
|
12020
|
-
|
12021
12019
|
this._mediaStreamTrack.getConstraints();
|
12022
12020
|
|
12023
12021
|
this.simulcastCodecs.forEach(trackInfo => {
|
@@ -13455,7 +13453,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
|
|
13455
13453
|
encodings.push({
|
13456
13454
|
rid: videoRids[2 - i],
|
13457
13455
|
scaleResolutionDownBy: 2 ** i,
|
13458
|
-
maxBitrate: videoEncoding ? videoEncoding.maxBitrate /
|
13456
|
+
maxBitrate: videoEncoding ? videoEncoding.maxBitrate / 3 ** i : 0,
|
13459
13457
|
|
13460
13458
|
/* @ts-ignore */
|
13461
13459
|
maxFramerate: original.encoding.maxFramerate,
|
@@ -14053,6 +14051,15 @@ class RemoteParticipant extends Participant {
|
|
14053
14051
|
|
14054
14052
|
newTracks.forEach(publication => {
|
14055
14053
|
this.emit(ParticipantEvent.TrackPublished, publication);
|
14054
|
+
const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => publishedTrack.source === publication.source);
|
14055
|
+
|
14056
|
+
if (existingTrackOfSource) {
|
14057
|
+
livekitLogger.warn("received a second track publication for ".concat(this.identity, " with the same source: ").concat(publication.source), {
|
14058
|
+
oldTrack: existingTrackOfSource,
|
14059
|
+
newTrack: publication,
|
14060
|
+
participant: this
|
14061
|
+
});
|
14062
|
+
}
|
14056
14063
|
}); // detect removed tracks
|
14057
14064
|
|
14058
14065
|
this.tracks.forEach(publication => {
|
@@ -14314,8 +14321,8 @@ class LocalParticipant extends Participant {
|
|
14314
14321
|
*/
|
14315
14322
|
|
14316
14323
|
|
14317
|
-
setCameraEnabled(enabled, options) {
|
14318
|
-
return this.setTrackEnabled(Track.Source.Camera, enabled, options);
|
14324
|
+
setCameraEnabled(enabled, options, publishOptions) {
|
14325
|
+
return this.setTrackEnabled(Track.Source.Camera, enabled, options, publishOptions);
|
14319
14326
|
}
|
14320
14327
|
/**
|
14321
14328
|
* Enable or disable a participant's microphone track.
|
@@ -14325,8 +14332,8 @@ class LocalParticipant extends Participant {
|
|
14325
14332
|
*/
|
14326
14333
|
|
14327
14334
|
|
14328
|
-
setMicrophoneEnabled(enabled, options) {
|
14329
|
-
return this.setTrackEnabled(Track.Source.Microphone, enabled, options);
|
14335
|
+
setMicrophoneEnabled(enabled, options, publishOptions) {
|
14336
|
+
return this.setTrackEnabled(Track.Source.Microphone, enabled, options, publishOptions);
|
14330
14337
|
}
|
14331
14338
|
/**
|
14332
14339
|
* Start or stop sharing a participant's screen
|
@@ -14334,8 +14341,8 @@ class LocalParticipant extends Participant {
|
|
14334
14341
|
*/
|
14335
14342
|
|
14336
14343
|
|
14337
|
-
setScreenShareEnabled(enabled, options) {
|
14338
|
-
return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options);
|
14344
|
+
setScreenShareEnabled(enabled, options, publishOptions) {
|
14345
|
+
return this.setTrackEnabled(Track.Source.ScreenShare, enabled, options, publishOptions);
|
14339
14346
|
}
|
14340
14347
|
/** @internal */
|
14341
14348
|
|
@@ -14351,7 +14358,7 @@ class LocalParticipant extends Participant {
|
|
14351
14358
|
return changed;
|
14352
14359
|
}
|
14353
14360
|
|
14354
|
-
async setTrackEnabled(source, enabled, options) {
|
14361
|
+
async setTrackEnabled(source, enabled, options, publishOptions) {
|
14355
14362
|
var _a, _b;
|
14356
14363
|
|
14357
14364
|
livekitLogger.debug('setTrackEnabled', {
|
@@ -14401,7 +14408,7 @@ class LocalParticipant extends Participant {
|
|
14401
14408
|
const publishPromises = [];
|
14402
14409
|
|
14403
14410
|
for (const localTrack of localTracks) {
|
14404
|
-
publishPromises.push(this.publishTrack(localTrack));
|
14411
|
+
publishPromises.push(this.publishTrack(localTrack, publishOptions));
|
14405
14412
|
}
|
14406
14413
|
|
14407
14414
|
const publishedTracks = await Promise.all(publishPromises); // for screen share publications including audio, this will only return the screen share publication, not the screen share audio one
|
@@ -14581,7 +14588,7 @@ class LocalParticipant extends Participant {
|
|
14581
14588
|
|
14582
14589
|
|
14583
14590
|
async publishTrack(track, options) {
|
14584
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
14591
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
14585
14592
|
|
14586
14593
|
const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // convert raw media track into audio or video track
|
14587
14594
|
|
@@ -14618,6 +14625,23 @@ class LocalParticipant extends Participant {
|
|
14618
14625
|
track.source = opts.source;
|
14619
14626
|
}
|
14620
14627
|
|
14628
|
+
const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
|
14629
|
+
|
14630
|
+
if (existingTrackOfSource) {
|
14631
|
+
try {
|
14632
|
+
// throw an Error in order to capture the stack trace
|
14633
|
+
throw Error("publishing a second track with the same source: ".concat(track.source));
|
14634
|
+
} catch (e) {
|
14635
|
+
if (e instanceof Error) {
|
14636
|
+
livekitLogger.warn(e.message, {
|
14637
|
+
oldTrack: existingTrackOfSource,
|
14638
|
+
newTrack: track,
|
14639
|
+
trace: e.stack
|
14640
|
+
});
|
14641
|
+
}
|
14642
|
+
}
|
14643
|
+
}
|
14644
|
+
|
14621
14645
|
if (opts.stopMicTrackOnMute && track instanceof LocalAudioTrack) {
|
14622
14646
|
track.stopOnMute = true;
|
14623
14647
|
}
|
@@ -14725,6 +14749,10 @@ class LocalParticipant extends Participant {
|
|
14725
14749
|
track.codec = opts.videoCodec;
|
14726
14750
|
}
|
14727
14751
|
|
14752
|
+
if (track.codec === 'av1' && encodings && ((_h = encodings[0]) === null || _h === void 0 ? void 0 : _h.maxBitrate)) {
|
14753
|
+
this.engine.publisher.setTrackCodecBitrate(req.cid, track.codec, encodings[0].maxBitrate / 1000);
|
14754
|
+
}
|
14755
|
+
|
14728
14756
|
this.engine.negotiate(); // store RTPSender
|
14729
14757
|
|
14730
14758
|
track.sender = transceiver.sender;
|
@@ -14746,7 +14774,7 @@ class LocalParticipant extends Participant {
|
|
14746
14774
|
|
14747
14775
|
|
14748
14776
|
async publishAdditionalCodecForTrack(track, videoCodec, options) {
|
14749
|
-
var _a, _b, _c, _d, _e;
|
14777
|
+
var _a, _b, _c, _d, _e, _f;
|
14750
14778
|
|
14751
14779
|
const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // clear scalabilityMode setting for backup codec
|
14752
14780
|
|
@@ -14814,6 +14842,11 @@ class LocalParticipant extends Participant {
|
|
14814
14842
|
const transceiver = await this.engine.publisher.pc.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
|
14815
14843
|
this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
|
14816
14844
|
track.setSimulcastTrackSender(opts.videoCodec, transceiver.sender);
|
14845
|
+
|
14846
|
+
if (videoCodec === 'av1' && ((_f = encodings[0]) === null || _f === void 0 ? void 0 : _f.maxBitrate)) {
|
14847
|
+
this.engine.publisher.setTrackCodecBitrate(req.cid, videoCodec, encodings[0].maxBitrate / 1000);
|
14848
|
+
}
|
14849
|
+
|
14817
14850
|
this.engine.negotiate();
|
14818
14851
|
livekitLogger.debug("published ".concat(opts.videoCodec, " for track ").concat(track.sid), {
|
14819
14852
|
encodings,
|
@@ -14840,7 +14873,6 @@ class LocalParticipant extends Participant {
|
|
14840
14873
|
}
|
14841
14874
|
|
14842
14875
|
track = publication.track;
|
14843
|
-
track.sender = undefined;
|
14844
14876
|
track.off(TrackEvent.Muted, this.onTrackMuted);
|
14845
14877
|
track.off(TrackEvent.Unmuted, this.onTrackUnmuted);
|
14846
14878
|
track.off(TrackEvent.Ended, this.handleTrackEnded);
|
@@ -14855,29 +14887,19 @@ class LocalParticipant extends Participant {
|
|
14855
14887
|
track.stop();
|
14856
14888
|
}
|
14857
14889
|
|
14858
|
-
|
14859
|
-
|
14860
|
-
|
14861
|
-
|
14862
|
-
|
14863
|
-
|
14864
|
-
|
14865
|
-
|
14866
|
-
|
14867
|
-
|
14868
|
-
|
14869
|
-
(_a = this.engine.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
|
14870
|
-
this.engine.negotiate();
|
14871
|
-
} catch (e) {
|
14872
|
-
livekitLogger.warn('failed to remove track', {
|
14873
|
-
error: e,
|
14874
|
-
method: 'unpublishTrack'
|
14875
|
-
});
|
14876
|
-
}
|
14877
|
-
}
|
14878
|
-
});
|
14879
|
-
} // remove from our maps
|
14890
|
+
if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && track.sender) {
|
14891
|
+
try {
|
14892
|
+
this.engine.publisher.pc.removeTrack(track.sender);
|
14893
|
+
this.engine.negotiate();
|
14894
|
+
} catch (e) {
|
14895
|
+
livekitLogger.warn('failed to remove track', {
|
14896
|
+
error: e,
|
14897
|
+
method: 'unpublishTrack'
|
14898
|
+
});
|
14899
|
+
}
|
14900
|
+
}
|
14880
14901
|
|
14902
|
+
track.sender = undefined; // remove from our maps
|
14881
14903
|
|
14882
14904
|
this.tracks.delete(publication.trackSid);
|
14883
14905
|
|
@@ -19041,13 +19063,718 @@ function createConnectionParams(token, info, opts) {
|
|
19041
19063
|
return "?".concat(params.toString());
|
19042
19064
|
}
|
19043
19065
|
|
19066
|
+
const maxRetryDelay = 7000;
|
19067
|
+
const DEFAULT_RETRY_DELAYS_IN_MS = [0, 300, 2 * 2 * 300, 3 * 3 * 300, 4 * 4 * 300, maxRetryDelay, maxRetryDelay, maxRetryDelay, maxRetryDelay, maxRetryDelay];
|
19068
|
+
|
19069
|
+
class DefaultReconnectPolicy {
|
19070
|
+
constructor(retryDelays) {
|
19071
|
+
this._retryDelays = retryDelays !== undefined ? [...retryDelays] : DEFAULT_RETRY_DELAYS_IN_MS;
|
19072
|
+
}
|
19073
|
+
|
19074
|
+
nextRetryDelayInMs(context) {
|
19075
|
+
if (context.retryCount >= this._retryDelays.length) return null;
|
19076
|
+
const retryDelay = this._retryDelays[context.retryCount];
|
19077
|
+
if (context.retryCount <= 1) return retryDelay;
|
19078
|
+
return retryDelay + Math.random() * 1000;
|
19079
|
+
}
|
19080
|
+
|
19081
|
+
}
|
19082
|
+
|
19083
|
+
var parser$1 = {};
|
19084
|
+
|
19085
|
+
var grammar$2 = {exports: {}};
|
19086
|
+
|
19087
|
+
var grammar$1 = grammar$2.exports = {
|
19088
|
+
v: [{
|
19089
|
+
name: 'version',
|
19090
|
+
reg: /^(\d*)$/
|
19091
|
+
}],
|
19092
|
+
o: [{
|
19093
|
+
// o=- 20518 0 IN IP4 203.0.113.1
|
19094
|
+
// NB: sessionId will be a String in most cases because it is huge
|
19095
|
+
name: 'origin',
|
19096
|
+
reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
|
19097
|
+
names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
|
19098
|
+
format: '%s %s %d %s IP%d %s'
|
19099
|
+
}],
|
19100
|
+
// default parsing of these only (though some of these feel outdated)
|
19101
|
+
s: [{
|
19102
|
+
name: 'name'
|
19103
|
+
}],
|
19104
|
+
i: [{
|
19105
|
+
name: 'description'
|
19106
|
+
}],
|
19107
|
+
u: [{
|
19108
|
+
name: 'uri'
|
19109
|
+
}],
|
19110
|
+
e: [{
|
19111
|
+
name: 'email'
|
19112
|
+
}],
|
19113
|
+
p: [{
|
19114
|
+
name: 'phone'
|
19115
|
+
}],
|
19116
|
+
z: [{
|
19117
|
+
name: 'timezones'
|
19118
|
+
}],
|
19119
|
+
// TODO: this one can actually be parsed properly...
|
19120
|
+
r: [{
|
19121
|
+
name: 'repeats'
|
19122
|
+
}],
|
19123
|
+
// TODO: this one can also be parsed properly
|
19124
|
+
// k: [{}], // outdated thing ignored
|
19125
|
+
t: [{
|
19126
|
+
// t=0 0
|
19127
|
+
name: 'timing',
|
19128
|
+
reg: /^(\d*) (\d*)/,
|
19129
|
+
names: ['start', 'stop'],
|
19130
|
+
format: '%d %d'
|
19131
|
+
}],
|
19132
|
+
c: [{
|
19133
|
+
// c=IN IP4 10.47.197.26
|
19134
|
+
name: 'connection',
|
19135
|
+
reg: /^IN IP(\d) (\S*)/,
|
19136
|
+
names: ['version', 'ip'],
|
19137
|
+
format: 'IN IP%d %s'
|
19138
|
+
}],
|
19139
|
+
b: [{
|
19140
|
+
// b=AS:4000
|
19141
|
+
push: 'bandwidth',
|
19142
|
+
reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
|
19143
|
+
names: ['type', 'limit'],
|
19144
|
+
format: '%s:%s'
|
19145
|
+
}],
|
19146
|
+
m: [{
|
19147
|
+
// m=video 51744 RTP/AVP 126 97 98 34 31
|
19148
|
+
// NB: special - pushes to session
|
19149
|
+
// TODO: rtp/fmtp should be filtered by the payloads found here?
|
19150
|
+
reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
|
19151
|
+
names: ['type', 'port', 'protocol', 'payloads'],
|
19152
|
+
format: '%s %d %s %s'
|
19153
|
+
}],
|
19154
|
+
a: [{
|
19155
|
+
// a=rtpmap:110 opus/48000/2
|
19156
|
+
push: 'rtp',
|
19157
|
+
reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
|
19158
|
+
names: ['payload', 'codec', 'rate', 'encoding'],
|
19159
|
+
format: function (o) {
|
19160
|
+
return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
|
19161
|
+
}
|
19162
|
+
}, {
|
19163
|
+
// a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
|
19164
|
+
// a=fmtp:111 minptime=10; useinbandfec=1
|
19165
|
+
push: 'fmtp',
|
19166
|
+
reg: /^fmtp:(\d*) ([\S| ]*)/,
|
19167
|
+
names: ['payload', 'config'],
|
19168
|
+
format: 'fmtp:%d %s'
|
19169
|
+
}, {
|
19170
|
+
// a=control:streamid=0
|
19171
|
+
name: 'control',
|
19172
|
+
reg: /^control:(.*)/,
|
19173
|
+
format: 'control:%s'
|
19174
|
+
}, {
|
19175
|
+
// a=rtcp:65179 IN IP4 193.84.77.194
|
19176
|
+
name: 'rtcp',
|
19177
|
+
reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
|
19178
|
+
names: ['port', 'netType', 'ipVer', 'address'],
|
19179
|
+
format: function (o) {
|
19180
|
+
return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
|
19181
|
+
}
|
19182
|
+
}, {
|
19183
|
+
// a=rtcp-fb:98 trr-int 100
|
19184
|
+
push: 'rtcpFbTrrInt',
|
19185
|
+
reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
|
19186
|
+
names: ['payload', 'value'],
|
19187
|
+
format: 'rtcp-fb:%s trr-int %d'
|
19188
|
+
}, {
|
19189
|
+
// a=rtcp-fb:98 nack rpsi
|
19190
|
+
push: 'rtcpFb',
|
19191
|
+
reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
|
19192
|
+
names: ['payload', 'type', 'subtype'],
|
19193
|
+
format: function (o) {
|
19194
|
+
return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
|
19195
|
+
}
|
19196
|
+
}, {
|
19197
|
+
// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
|
19198
|
+
// a=extmap:1/recvonly URI-gps-string
|
19199
|
+
// a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
|
19200
|
+
push: 'ext',
|
19201
|
+
reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
|
19202
|
+
names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
|
19203
|
+
format: function (o) {
|
19204
|
+
return 'extmap:%d' + (o.direction ? '/%s' : '%v') + (o['encrypt-uri'] ? ' %s' : '%v') + ' %s' + (o.config ? ' %s' : '');
|
19205
|
+
}
|
19206
|
+
}, {
|
19207
|
+
// a=extmap-allow-mixed
|
19208
|
+
name: 'extmapAllowMixed',
|
19209
|
+
reg: /^(extmap-allow-mixed)/
|
19210
|
+
}, {
|
19211
|
+
// a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
|
19212
|
+
push: 'crypto',
|
19213
|
+
reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
|
19214
|
+
names: ['id', 'suite', 'config', 'sessionConfig'],
|
19215
|
+
format: function (o) {
|
19216
|
+
return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
|
19217
|
+
}
|
19218
|
+
}, {
|
19219
|
+
// a=setup:actpass
|
19220
|
+
name: 'setup',
|
19221
|
+
reg: /^setup:(\w*)/,
|
19222
|
+
format: 'setup:%s'
|
19223
|
+
}, {
|
19224
|
+
// a=connection:new
|
19225
|
+
name: 'connectionType',
|
19226
|
+
reg: /^connection:(new|existing)/,
|
19227
|
+
format: 'connection:%s'
|
19228
|
+
}, {
|
19229
|
+
// a=mid:1
|
19230
|
+
name: 'mid',
|
19231
|
+
reg: /^mid:([^\s]*)/,
|
19232
|
+
format: 'mid:%s'
|
19233
|
+
}, {
|
19234
|
+
// a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
|
19235
|
+
name: 'msid',
|
19236
|
+
reg: /^msid:(.*)/,
|
19237
|
+
format: 'msid:%s'
|
19238
|
+
}, {
|
19239
|
+
// a=ptime:20
|
19240
|
+
name: 'ptime',
|
19241
|
+
reg: /^ptime:(\d*(?:\.\d*)*)/,
|
19242
|
+
format: 'ptime:%d'
|
19243
|
+
}, {
|
19244
|
+
// a=maxptime:60
|
19245
|
+
name: 'maxptime',
|
19246
|
+
reg: /^maxptime:(\d*(?:\.\d*)*)/,
|
19247
|
+
format: 'maxptime:%d'
|
19248
|
+
}, {
|
19249
|
+
// a=sendrecv
|
19250
|
+
name: 'direction',
|
19251
|
+
reg: /^(sendrecv|recvonly|sendonly|inactive)/
|
19252
|
+
}, {
|
19253
|
+
// a=ice-lite
|
19254
|
+
name: 'icelite',
|
19255
|
+
reg: /^(ice-lite)/
|
19256
|
+
}, {
|
19257
|
+
// a=ice-ufrag:F7gI
|
19258
|
+
name: 'iceUfrag',
|
19259
|
+
reg: /^ice-ufrag:(\S*)/,
|
19260
|
+
format: 'ice-ufrag:%s'
|
19261
|
+
}, {
|
19262
|
+
// a=ice-pwd:x9cml/YzichV2+XlhiMu8g
|
19263
|
+
name: 'icePwd',
|
19264
|
+
reg: /^ice-pwd:(\S*)/,
|
19265
|
+
format: 'ice-pwd:%s'
|
19266
|
+
}, {
|
19267
|
+
// a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
|
19268
|
+
name: 'fingerprint',
|
19269
|
+
reg: /^fingerprint:(\S*) (\S*)/,
|
19270
|
+
names: ['type', 'hash'],
|
19271
|
+
format: 'fingerprint:%s %s'
|
19272
|
+
}, {
|
19273
|
+
// a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
19274
|
+
// a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
|
19275
|
+
// a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
|
19276
|
+
// a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
|
19277
|
+
// a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
|
19278
|
+
push: 'candidates',
|
19279
|
+
reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
|
19280
|
+
names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
|
19281
|
+
format: function (o) {
|
19282
|
+
var str = 'candidate:%s %d %s %d %s %d typ %s';
|
19283
|
+
str += o.raddr != null ? ' raddr %s rport %d' : '%v%v'; // NB: candidate has three optional chunks, so %void middles one if it's missing
|
19284
|
+
|
19285
|
+
str += o.tcptype != null ? ' tcptype %s' : '%v';
|
19286
|
+
|
19287
|
+
if (o.generation != null) {
|
19288
|
+
str += ' generation %d';
|
19289
|
+
}
|
19290
|
+
|
19291
|
+
str += o['network-id'] != null ? ' network-id %d' : '%v';
|
19292
|
+
str += o['network-cost'] != null ? ' network-cost %d' : '%v';
|
19293
|
+
return str;
|
19294
|
+
}
|
19295
|
+
}, {
|
19296
|
+
// a=end-of-candidates (keep after the candidates line for readability)
|
19297
|
+
name: 'endOfCandidates',
|
19298
|
+
reg: /^(end-of-candidates)/
|
19299
|
+
}, {
|
19300
|
+
// a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
|
19301
|
+
name: 'remoteCandidates',
|
19302
|
+
reg: /^remote-candidates:(.*)/,
|
19303
|
+
format: 'remote-candidates:%s'
|
19304
|
+
}, {
|
19305
|
+
// a=ice-options:google-ice
|
19306
|
+
name: 'iceOptions',
|
19307
|
+
reg: /^ice-options:(\S*)/,
|
19308
|
+
format: 'ice-options:%s'
|
19309
|
+
}, {
|
19310
|
+
// a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
|
19311
|
+
push: 'ssrcs',
|
19312
|
+
reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
|
19313
|
+
names: ['id', 'attribute', 'value'],
|
19314
|
+
format: function (o) {
|
19315
|
+
var str = 'ssrc:%d';
|
19316
|
+
|
19317
|
+
if (o.attribute != null) {
|
19318
|
+
str += ' %s';
|
19319
|
+
|
19320
|
+
if (o.value != null) {
|
19321
|
+
str += ':%s';
|
19322
|
+
}
|
19323
|
+
}
|
19324
|
+
|
19325
|
+
return str;
|
19326
|
+
}
|
19327
|
+
}, {
|
19328
|
+
// a=ssrc-group:FEC 1 2
|
19329
|
+
// a=ssrc-group:FEC-FR 3004364195 1080772241
|
19330
|
+
push: 'ssrcGroups',
|
19331
|
+
// token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
|
19332
|
+
reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
|
19333
|
+
names: ['semantics', 'ssrcs'],
|
19334
|
+
format: 'ssrc-group:%s %s'
|
19335
|
+
}, {
|
19336
|
+
// a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
|
19337
|
+
name: 'msidSemantic',
|
19338
|
+
reg: /^msid-semantic:\s?(\w*) (\S*)/,
|
19339
|
+
names: ['semantic', 'token'],
|
19340
|
+
format: 'msid-semantic: %s %s' // space after ':' is not accidental
|
19341
|
+
|
19342
|
+
}, {
|
19343
|
+
// a=group:BUNDLE audio video
|
19344
|
+
push: 'groups',
|
19345
|
+
reg: /^group:(\w*) (.*)/,
|
19346
|
+
names: ['type', 'mids'],
|
19347
|
+
format: 'group:%s %s'
|
19348
|
+
}, {
|
19349
|
+
// a=rtcp-mux
|
19350
|
+
name: 'rtcpMux',
|
19351
|
+
reg: /^(rtcp-mux)/
|
19352
|
+
}, {
|
19353
|
+
// a=rtcp-rsize
|
19354
|
+
name: 'rtcpRsize',
|
19355
|
+
reg: /^(rtcp-rsize)/
|
19356
|
+
}, {
|
19357
|
+
// a=sctpmap:5000 webrtc-datachannel 1024
|
19358
|
+
name: 'sctpmap',
|
19359
|
+
reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
|
19360
|
+
names: ['sctpmapNumber', 'app', 'maxMessageSize'],
|
19361
|
+
format: function (o) {
|
19362
|
+
return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
|
19363
|
+
}
|
19364
|
+
}, {
|
19365
|
+
// a=x-google-flag:conference
|
19366
|
+
name: 'xGoogleFlag',
|
19367
|
+
reg: /^x-google-flag:([^\s]*)/,
|
19368
|
+
format: 'x-google-flag:%s'
|
19369
|
+
}, {
|
19370
|
+
// a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
|
19371
|
+
push: 'rids',
|
19372
|
+
reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
|
19373
|
+
names: ['id', 'direction', 'params'],
|
19374
|
+
format: function (o) {
|
19375
|
+
return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
|
19376
|
+
}
|
19377
|
+
}, {
|
19378
|
+
// a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
|
19379
|
+
// a=imageattr:* send [x=800,y=640] recv *
|
19380
|
+
// a=imageattr:100 recv [x=320,y=240]
|
19381
|
+
push: 'imageattrs',
|
19382
|
+
reg: new RegExp( // a=imageattr:97
|
19383
|
+
'^imageattr:(\\d+|\\*)' + // send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
|
19384
|
+
'[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' + // recv [x=330,y=250]
|
19385
|
+
'(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
|
19386
|
+
names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
|
19387
|
+
format: function (o) {
|
19388
|
+
return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
|
19389
|
+
}
|
19390
|
+
}, {
|
19391
|
+
// a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
|
19392
|
+
// a=simulcast:recv 1;4,5 send 6;7
|
19393
|
+
name: 'simulcast',
|
19394
|
+
reg: new RegExp( // a=simulcast:
|
19395
|
+
'^simulcast:' + // send 1,2,3;~4,~5
|
19396
|
+
'(send|recv) ([a-zA-Z0-9\\-_~;,]+)' + // space + recv 6;~7,~8
|
19397
|
+
'(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' + // end
|
19398
|
+
'$'),
|
19399
|
+
names: ['dir1', 'list1', 'dir2', 'list2'],
|
19400
|
+
format: function (o) {
|
19401
|
+
return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
|
19402
|
+
}
|
19403
|
+
}, {
|
19404
|
+
// old simulcast draft 03 (implemented by Firefox)
|
19405
|
+
// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
|
19406
|
+
// a=simulcast: recv pt=97;98 send pt=97
|
19407
|
+
// a=simulcast: send rid=5;6;7 paused=6,7
|
19408
|
+
name: 'simulcast_03',
|
19409
|
+
reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
|
19410
|
+
names: ['value'],
|
19411
|
+
format: 'simulcast: %s'
|
19412
|
+
}, {
|
19413
|
+
// a=framerate:25
|
19414
|
+
// a=framerate:29.97
|
19415
|
+
name: 'framerate',
|
19416
|
+
reg: /^framerate:(\d+(?:$|\.\d+))/,
|
19417
|
+
format: 'framerate:%s'
|
19418
|
+
}, {
|
19419
|
+
// RFC4570
|
19420
|
+
// a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
|
19421
|
+
name: 'sourceFilter',
|
19422
|
+
reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
|
19423
|
+
names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
|
19424
|
+
format: 'source-filter: %s %s %s %s %s'
|
19425
|
+
}, {
|
19426
|
+
// a=bundle-only
|
19427
|
+
name: 'bundleOnly',
|
19428
|
+
reg: /^(bundle-only)/
|
19429
|
+
}, {
|
19430
|
+
// a=label:1
|
19431
|
+
name: 'label',
|
19432
|
+
reg: /^label:(.+)/,
|
19433
|
+
format: 'label:%s'
|
19434
|
+
}, {
|
19435
|
+
// RFC version 26 for SCTP over DTLS
|
19436
|
+
// https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
|
19437
|
+
name: 'sctpPort',
|
19438
|
+
reg: /^sctp-port:(\d+)$/,
|
19439
|
+
format: 'sctp-port:%s'
|
19440
|
+
}, {
|
19441
|
+
// RFC version 26 for SCTP over DTLS
|
19442
|
+
// https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
|
19443
|
+
name: 'maxMessageSize',
|
19444
|
+
reg: /^max-message-size:(\d+)$/,
|
19445
|
+
format: 'max-message-size:%s'
|
19446
|
+
}, {
|
19447
|
+
// RFC7273
|
19448
|
+
// a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
|
19449
|
+
push: 'tsRefClocks',
|
19450
|
+
reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
|
19451
|
+
names: ['clksrc', 'clksrcExt'],
|
19452
|
+
format: function (o) {
|
19453
|
+
return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
|
19454
|
+
}
|
19455
|
+
}, {
|
19456
|
+
// RFC7273
|
19457
|
+
// a=mediaclk:direct=963214424
|
19458
|
+
name: 'mediaClk',
|
19459
|
+
reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
|
19460
|
+
names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
|
19461
|
+
format: function (o) {
|
19462
|
+
var str = 'mediaclk:';
|
19463
|
+
str += o.id != null ? 'id=%s %s' : '%v%s';
|
19464
|
+
str += o.mediaClockValue != null ? '=%s' : '';
|
19465
|
+
str += o.rateNumerator != null ? ' rate=%s' : '';
|
19466
|
+
str += o.rateDenominator != null ? '/%s' : '';
|
19467
|
+
return str;
|
19468
|
+
}
|
19469
|
+
}, {
|
19470
|
+
// a=keywds:keywords
|
19471
|
+
name: 'keywords',
|
19472
|
+
reg: /^keywds:(.+)$/,
|
19473
|
+
format: 'keywds:%s'
|
19474
|
+
}, {
|
19475
|
+
// a=content:main
|
19476
|
+
name: 'content',
|
19477
|
+
reg: /^content:(.+)/,
|
19478
|
+
format: 'content:%s'
|
19479
|
+
}, // BFCP https://tools.ietf.org/html/rfc4583
|
19480
|
+
{
|
19481
|
+
// a=floorctrl:c-s
|
19482
|
+
name: 'bfcpFloorCtrl',
|
19483
|
+
reg: /^floorctrl:(c-only|s-only|c-s)/,
|
19484
|
+
format: 'floorctrl:%s'
|
19485
|
+
}, {
|
19486
|
+
// a=confid:1
|
19487
|
+
name: 'bfcpConfId',
|
19488
|
+
reg: /^confid:(\d+)/,
|
19489
|
+
format: 'confid:%s'
|
19490
|
+
}, {
|
19491
|
+
// a=userid:1
|
19492
|
+
name: 'bfcpUserId',
|
19493
|
+
reg: /^userid:(\d+)/,
|
19494
|
+
format: 'userid:%s'
|
19495
|
+
}, {
|
19496
|
+
// a=floorid:1
|
19497
|
+
name: 'bfcpFloorId',
|
19498
|
+
reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
|
19499
|
+
names: ['id', 'mStream'],
|
19500
|
+
format: 'floorid:%s mstrm:%s'
|
19501
|
+
}, {
|
19502
|
+
// any a= that we don't understand is kept verbatim on media.invalid
|
19503
|
+
push: 'invalid',
|
19504
|
+
names: ['value']
|
19505
|
+
}]
|
19506
|
+
}; // set sensible defaults to avoid polluting the grammar with boring details
|
19507
|
+
|
19508
|
+
Object.keys(grammar$1).forEach(function (key) {
|
19509
|
+
var objs = grammar$1[key];
|
19510
|
+
objs.forEach(function (obj) {
|
19511
|
+
if (!obj.reg) {
|
19512
|
+
obj.reg = /(.*)/;
|
19513
|
+
}
|
19514
|
+
|
19515
|
+
if (!obj.format) {
|
19516
|
+
obj.format = '%s';
|
19517
|
+
}
|
19518
|
+
});
|
19519
|
+
});
|
19520
|
+
|
19521
|
+
(function (exports) {
|
19522
|
+
var toIntIfInt = function (v) {
|
19523
|
+
return String(Number(v)) === v ? Number(v) : v;
|
19524
|
+
};
|
19525
|
+
|
19526
|
+
var attachProperties = function (match, location, names, rawName) {
|
19527
|
+
if (rawName && !names) {
|
19528
|
+
location[rawName] = toIntIfInt(match[1]);
|
19529
|
+
} else {
|
19530
|
+
for (var i = 0; i < names.length; i += 1) {
|
19531
|
+
if (match[i + 1] != null) {
|
19532
|
+
location[names[i]] = toIntIfInt(match[i + 1]);
|
19533
|
+
}
|
19534
|
+
}
|
19535
|
+
}
|
19536
|
+
};
|
19537
|
+
|
19538
|
+
var parseReg = function (obj, location, content) {
|
19539
|
+
var needsBlank = obj.name && obj.names;
|
19540
|
+
|
19541
|
+
if (obj.push && !location[obj.push]) {
|
19542
|
+
location[obj.push] = [];
|
19543
|
+
} else if (needsBlank && !location[obj.name]) {
|
19544
|
+
location[obj.name] = {};
|
19545
|
+
}
|
19546
|
+
|
19547
|
+
var keyLocation = obj.push ? {} : // blank object that will be pushed
|
19548
|
+
needsBlank ? location[obj.name] : location; // otherwise, named location or root
|
19549
|
+
|
19550
|
+
attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
|
19551
|
+
|
19552
|
+
if (obj.push) {
|
19553
|
+
location[obj.push].push(keyLocation);
|
19554
|
+
}
|
19555
|
+
};
|
19556
|
+
|
19557
|
+
var grammar = grammar$2.exports;
|
19558
|
+
var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
|
19559
|
+
|
19560
|
+
exports.parse = function (sdp) {
|
19561
|
+
var session = {},
|
19562
|
+
media = [],
|
19563
|
+
location = session; // points at where properties go under (one of the above)
|
19564
|
+
// parse lines we understand
|
19565
|
+
|
19566
|
+
sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
|
19567
|
+
var type = l[0];
|
19568
|
+
var content = l.slice(2);
|
19569
|
+
|
19570
|
+
if (type === 'm') {
|
19571
|
+
media.push({
|
19572
|
+
rtp: [],
|
19573
|
+
fmtp: []
|
19574
|
+
});
|
19575
|
+
location = media[media.length - 1]; // point at latest media line
|
19576
|
+
}
|
19577
|
+
|
19578
|
+
for (var j = 0; j < (grammar[type] || []).length; j += 1) {
|
19579
|
+
var obj = grammar[type][j];
|
19580
|
+
|
19581
|
+
if (obj.reg.test(content)) {
|
19582
|
+
return parseReg(obj, location, content);
|
19583
|
+
}
|
19584
|
+
}
|
19585
|
+
});
|
19586
|
+
session.media = media; // link it up
|
19587
|
+
|
19588
|
+
return session;
|
19589
|
+
};
|
19590
|
+
|
19591
|
+
var paramReducer = function (acc, expr) {
|
19592
|
+
var s = expr.split(/=(.+)/, 2);
|
19593
|
+
|
19594
|
+
if (s.length === 2) {
|
19595
|
+
acc[s[0]] = toIntIfInt(s[1]);
|
19596
|
+
} else if (s.length === 1 && expr.length > 1) {
|
19597
|
+
acc[s[0]] = undefined;
|
19598
|
+
}
|
19599
|
+
|
19600
|
+
return acc;
|
19601
|
+
};
|
19602
|
+
|
19603
|
+
exports.parseParams = function (str) {
|
19604
|
+
return str.split(/;\s?/).reduce(paramReducer, {});
|
19605
|
+
}; // For backward compatibility - alias will be removed in 3.0.0
|
19606
|
+
|
19607
|
+
|
19608
|
+
exports.parseFmtpConfig = exports.parseParams;
|
19609
|
+
|
19610
|
+
exports.parsePayloads = function (str) {
|
19611
|
+
return str.toString().split(' ').map(Number);
|
19612
|
+
};
|
19613
|
+
|
19614
|
+
exports.parseRemoteCandidates = function (str) {
|
19615
|
+
var candidates = [];
|
19616
|
+
var parts = str.split(' ').map(toIntIfInt);
|
19617
|
+
|
19618
|
+
for (var i = 0; i < parts.length; i += 3) {
|
19619
|
+
candidates.push({
|
19620
|
+
component: parts[i],
|
19621
|
+
ip: parts[i + 1],
|
19622
|
+
port: parts[i + 2]
|
19623
|
+
});
|
19624
|
+
}
|
19625
|
+
|
19626
|
+
return candidates;
|
19627
|
+
};
|
19628
|
+
|
19629
|
+
exports.parseImageAttributes = function (str) {
|
19630
|
+
return str.split(' ').map(function (item) {
|
19631
|
+
return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
|
19632
|
+
});
|
19633
|
+
};
|
19634
|
+
|
19635
|
+
exports.parseSimulcastStreamList = function (str) {
|
19636
|
+
return str.split(';').map(function (stream) {
|
19637
|
+
return stream.split(',').map(function (format) {
|
19638
|
+
var scid,
|
19639
|
+
paused = false;
|
19640
|
+
|
19641
|
+
if (format[0] !== '~') {
|
19642
|
+
scid = toIntIfInt(format);
|
19643
|
+
} else {
|
19644
|
+
scid = toIntIfInt(format.substring(1, format.length));
|
19645
|
+
paused = true;
|
19646
|
+
}
|
19647
|
+
|
19648
|
+
return {
|
19649
|
+
scid: scid,
|
19650
|
+
paused: paused
|
19651
|
+
};
|
19652
|
+
});
|
19653
|
+
});
|
19654
|
+
};
|
19655
|
+
})(parser$1);
|
19656
|
+
|
19657
|
+
var grammar = grammar$2.exports; // customized util.format - discards excess arguments and can void middle ones
|
19658
|
+
|
19659
|
+
var formatRegExp = /%[sdv%]/g;
|
19660
|
+
|
19661
|
+
var format = function (formatStr) {
|
19662
|
+
var i = 1;
|
19663
|
+
var args = arguments;
|
19664
|
+
var len = args.length;
|
19665
|
+
return formatStr.replace(formatRegExp, function (x) {
|
19666
|
+
if (i >= len) {
|
19667
|
+
return x; // missing argument
|
19668
|
+
}
|
19669
|
+
|
19670
|
+
var arg = args[i];
|
19671
|
+
i += 1;
|
19672
|
+
|
19673
|
+
switch (x) {
|
19674
|
+
case '%%':
|
19675
|
+
return '%';
|
19676
|
+
|
19677
|
+
case '%s':
|
19678
|
+
return String(arg);
|
19679
|
+
|
19680
|
+
case '%d':
|
19681
|
+
return Number(arg);
|
19682
|
+
|
19683
|
+
case '%v':
|
19684
|
+
return '';
|
19685
|
+
}
|
19686
|
+
}); // NB: we discard excess arguments - they are typically undefined from makeLine
|
19687
|
+
};
|
19688
|
+
|
19689
|
+
var makeLine = function (type, obj, location) {
|
19690
|
+
var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
|
19691
|
+
var args = [type + '=' + str];
|
19692
|
+
|
19693
|
+
if (obj.names) {
|
19694
|
+
for (var i = 0; i < obj.names.length; i += 1) {
|
19695
|
+
var n = obj.names[i];
|
19696
|
+
|
19697
|
+
if (obj.name) {
|
19698
|
+
args.push(location[obj.name][n]);
|
19699
|
+
} else {
|
19700
|
+
// for mLine and push attributes
|
19701
|
+
args.push(location[obj.names[i]]);
|
19702
|
+
}
|
19703
|
+
}
|
19704
|
+
} else {
|
19705
|
+
args.push(location[obj.name]);
|
19706
|
+
}
|
19707
|
+
|
19708
|
+
return format.apply(null, args);
|
19709
|
+
}; // RFC specified order
|
19710
|
+
// TODO: extend this with all the rest
|
19711
|
+
|
19712
|
+
|
19713
|
+
var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
|
19714
|
+
var defaultInnerOrder = ['i', 'c', 'b', 'a'];
|
19715
|
+
|
19716
|
+
var writer$1 = function (session, opts) {
|
19717
|
+
opts = opts || {}; // ensure certain properties exist
|
19718
|
+
|
19719
|
+
if (session.version == null) {
|
19720
|
+
session.version = 0; // 'v=0' must be there (only defined version atm)
|
19721
|
+
}
|
19722
|
+
|
19723
|
+
if (session.name == null) {
|
19724
|
+
session.name = ' '; // 's= ' must be there if no meaningful name set
|
19725
|
+
}
|
19726
|
+
|
19727
|
+
session.media.forEach(function (mLine) {
|
19728
|
+
if (mLine.payloads == null) {
|
19729
|
+
mLine.payloads = '';
|
19730
|
+
}
|
19731
|
+
});
|
19732
|
+
var outerOrder = opts.outerOrder || defaultOuterOrder;
|
19733
|
+
var innerOrder = opts.innerOrder || defaultInnerOrder;
|
19734
|
+
var sdp = []; // loop through outerOrder for matching properties on session
|
19735
|
+
|
19736
|
+
outerOrder.forEach(function (type) {
|
19737
|
+
grammar[type].forEach(function (obj) {
|
19738
|
+
if (obj.name in session && session[obj.name] != null) {
|
19739
|
+
sdp.push(makeLine(type, obj, session));
|
19740
|
+
} else if (obj.push in session && session[obj.push] != null) {
|
19741
|
+
session[obj.push].forEach(function (el) {
|
19742
|
+
sdp.push(makeLine(type, obj, el));
|
19743
|
+
});
|
19744
|
+
}
|
19745
|
+
});
|
19746
|
+
}); // then for each media line, follow the innerOrder
|
19747
|
+
|
19748
|
+
session.media.forEach(function (mLine) {
|
19749
|
+
sdp.push(makeLine('m', grammar.m[0], mLine));
|
19750
|
+
innerOrder.forEach(function (type) {
|
19751
|
+
grammar[type].forEach(function (obj) {
|
19752
|
+
if (obj.name in mLine && mLine[obj.name] != null) {
|
19753
|
+
sdp.push(makeLine(type, obj, mLine));
|
19754
|
+
} else if (obj.push in mLine && mLine[obj.push] != null) {
|
19755
|
+
mLine[obj.push].forEach(function (el) {
|
19756
|
+
sdp.push(makeLine(type, obj, el));
|
19757
|
+
});
|
19758
|
+
}
|
19759
|
+
});
|
19760
|
+
});
|
19761
|
+
});
|
19762
|
+
return sdp.join('\r\n') + '\r\n';
|
19763
|
+
};
|
19764
|
+
|
19765
|
+
var parser = parser$1;
|
19766
|
+
var writer = writer$1;
|
19767
|
+
var write = writer;
|
19768
|
+
var parse = parser.parse;
|
19769
|
+
|
19044
19770
|
/** @internal */
|
19045
19771
|
|
19046
19772
|
class PCTransport {
|
19047
19773
|
constructor(config) {
|
19048
19774
|
this.pendingCandidates = [];
|
19049
19775
|
this.restartingIce = false;
|
19050
|
-
this.renegotiate = false;
|
19776
|
+
this.renegotiate = false;
|
19777
|
+
this.trackBitrates = []; // debounced negotiate interface
|
19051
19778
|
|
19052
19779
|
this.negotiate = r(() => {
|
19053
19780
|
this.createAndSendOffer();
|
@@ -19082,6 +19809,8 @@ class PCTransport {
|
|
19082
19809
|
}
|
19083
19810
|
|
19084
19811
|
async createAndSendOffer(options) {
|
19812
|
+
var _a;
|
19813
|
+
|
19085
19814
|
if (this.onOffer === undefined) {
|
19086
19815
|
return;
|
19087
19816
|
}
|
@@ -19112,21 +19841,114 @@ class PCTransport {
|
|
19112
19841
|
|
19113
19842
|
livekitLogger.debug('starting to negotiate');
|
19114
19843
|
const offer = await this.pc.createOffer(options);
|
19844
|
+
const sdpParsed = parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
|
19845
|
+
sdpParsed.media.forEach(media => {
|
19846
|
+
if (media.type === 'audio') {
|
19847
|
+
ensureAudioNack(media);
|
19848
|
+
} else if (media.type === 'video') {
|
19849
|
+
// mung sdp for codec bitrate setting that can't apply by sendEncoding
|
19850
|
+
this.trackBitrates.some(trackbr => {
|
19851
|
+
if (!media.msid || !media.msid.includes(trackbr.sid)) {
|
19852
|
+
return false;
|
19853
|
+
}
|
19854
|
+
|
19855
|
+
let codecPayload = 0;
|
19856
|
+
media.rtp.some(rtp => {
|
19857
|
+
if (rtp.codec.toUpperCase() === trackbr.codec.toUpperCase()) {
|
19858
|
+
codecPayload = rtp.payload;
|
19859
|
+
return true;
|
19860
|
+
}
|
19861
|
+
|
19862
|
+
return false;
|
19863
|
+
}); // add x-google-max-bitrate to fmtp line if not exist
|
19864
|
+
|
19865
|
+
if (codecPayload > 0) {
|
19866
|
+
if (!media.fmtp.some(fmtp => {
|
19867
|
+
if (fmtp.payload === codecPayload) {
|
19868
|
+
if (!fmtp.config.includes('x-google-max-bitrate')) {
|
19869
|
+
fmtp.config += ";x-google-max-bitrate=".concat(trackbr.maxbr);
|
19870
|
+
}
|
19871
|
+
|
19872
|
+
return true;
|
19873
|
+
}
|
19874
|
+
|
19875
|
+
return false;
|
19876
|
+
})) {
|
19877
|
+
media.fmtp.push({
|
19878
|
+
payload: codecPayload,
|
19879
|
+
config: "x-google-max-bitrate=".concat(trackbr.maxbr)
|
19880
|
+
});
|
19881
|
+
}
|
19882
|
+
}
|
19883
|
+
|
19884
|
+
return true;
|
19885
|
+
});
|
19886
|
+
}
|
19887
|
+
});
|
19888
|
+
offer.sdp = write(sdpParsed);
|
19889
|
+
this.trackBitrates = [];
|
19115
19890
|
await this.pc.setLocalDescription(offer);
|
19116
19891
|
this.onOffer(offer);
|
19117
19892
|
}
|
19118
19893
|
|
19894
|
+
async createAndSetAnswer() {
|
19895
|
+
var _a;
|
19896
|
+
|
19897
|
+
const answer = await this.pc.createAnswer();
|
19898
|
+
const sdpParsed = parse((_a = answer.sdp) !== null && _a !== void 0 ? _a : '');
|
19899
|
+
sdpParsed.media.forEach(media => {
|
19900
|
+
if (media.type === 'audio') {
|
19901
|
+
ensureAudioNack(media);
|
19902
|
+
}
|
19903
|
+
});
|
19904
|
+
answer.sdp = write(sdpParsed);
|
19905
|
+
await this.pc.setLocalDescription(answer);
|
19906
|
+
return answer;
|
19907
|
+
}
|
19908
|
+
|
19909
|
+
setTrackCodecBitrate(sid, codec, maxbr) {
|
19910
|
+
this.trackBitrates.push({
|
19911
|
+
sid,
|
19912
|
+
codec,
|
19913
|
+
maxbr
|
19914
|
+
});
|
19915
|
+
}
|
19916
|
+
|
19119
19917
|
close() {
|
19120
19918
|
this.pc.close();
|
19121
19919
|
}
|
19122
19920
|
|
19123
19921
|
}
|
19124
19922
|
|
19923
|
+
function ensureAudioNack(media) {
|
19924
|
+
// found opus codec to add nack fb
|
19925
|
+
let opusPayload = 0;
|
19926
|
+
media.rtp.some(rtp => {
|
19927
|
+
if (rtp.codec === 'opus') {
|
19928
|
+
opusPayload = rtp.payload;
|
19929
|
+
return true;
|
19930
|
+
}
|
19931
|
+
|
19932
|
+
return false;
|
19933
|
+
}); // add nack rtcpfb if not exist
|
19934
|
+
|
19935
|
+
if (opusPayload > 0) {
|
19936
|
+
if (!media.rtcpFb) {
|
19937
|
+
media.rtcpFb = [];
|
19938
|
+
}
|
19939
|
+
|
19940
|
+
if (!media.rtcpFb.some(fb => fb.payload === opusPayload && fb.type === 'nack')) {
|
19941
|
+
media.rtcpFb.push({
|
19942
|
+
payload: opusPayload,
|
19943
|
+
type: 'nack'
|
19944
|
+
});
|
19945
|
+
}
|
19946
|
+
}
|
19947
|
+
}
|
19948
|
+
|
19125
19949
|
const lossyDataChannel = '_lossy';
|
19126
19950
|
const reliableDataChannel = '_reliable';
|
19127
|
-
const maxReconnectRetries = 10;
|
19128
19951
|
const minReconnectWait = 2 * 1000;
|
19129
|
-
const maxReconnectDuration = 60 * 1000;
|
19130
19952
|
const maxICEConnectTimeout = 15 * 1000;
|
19131
19953
|
var PCState;
|
19132
19954
|
|
@@ -19141,8 +19963,14 @@ var PCState;
|
|
19141
19963
|
|
19142
19964
|
|
19143
19965
|
class RTCEngine extends events.exports.EventEmitter {
|
19144
|
-
constructor() {
|
19966
|
+
constructor(options) {
|
19967
|
+
var _this;
|
19968
|
+
|
19969
|
+
var _a;
|
19970
|
+
|
19145
19971
|
super();
|
19972
|
+
_this = this;
|
19973
|
+
this.options = options;
|
19146
19974
|
this.rtcConfig = {};
|
19147
19975
|
this.subscriberPrimary = false;
|
19148
19976
|
this.pcState = PCState.New;
|
@@ -19217,53 +20045,85 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19217
20045
|
// after a number of retries, we'll close and give up permanently
|
19218
20046
|
|
19219
20047
|
|
19220
|
-
this.handleDisconnect = connection
|
19221
|
-
|
20048
|
+
this.handleDisconnect = function (connection) {
|
20049
|
+
let signalEvents = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
20050
|
+
|
20051
|
+
if (_this._isClosed) {
|
19222
20052
|
return;
|
19223
20053
|
}
|
19224
20054
|
|
19225
20055
|
livekitLogger.debug("".concat(connection, " disconnected"));
|
19226
20056
|
|
19227
|
-
if (
|
20057
|
+
if (_this.reconnectAttempts === 0) {
|
19228
20058
|
// only reset start time on the first try
|
19229
|
-
|
20059
|
+
_this.reconnectStart = Date.now();
|
19230
20060
|
}
|
19231
20061
|
|
19232
|
-
const
|
19233
|
-
|
20062
|
+
const disconnect = duration => {
|
20063
|
+
livekitLogger.info("could not recover connection after ".concat(_this.reconnectAttempts, " attempts, ").concat(duration, "ms. giving up"));
|
20064
|
+
|
20065
|
+
_this.emit(EngineEvent.Disconnected);
|
20066
|
+
|
20067
|
+
_this.close();
|
20068
|
+
};
|
20069
|
+
|
20070
|
+
const duration = Date.now() - _this.reconnectStart;
|
20071
|
+
|
20072
|
+
const delay = _this.getNextRetryDelay({
|
20073
|
+
elapsedMs: duration,
|
20074
|
+
retryCount: _this.reconnectAttempts
|
20075
|
+
});
|
20076
|
+
|
20077
|
+
if (delay === null) {
|
20078
|
+
disconnect(duration);
|
20079
|
+
return;
|
20080
|
+
}
|
20081
|
+
|
20082
|
+
livekitLogger.debug("reconnecting in ".concat(delay, "ms"));
|
20083
|
+
|
20084
|
+
if (_this.reconnectTimeout) {
|
20085
|
+
clearTimeout(_this.reconnectTimeout);
|
20086
|
+
}
|
20087
|
+
|
20088
|
+
_this.reconnectTimeout = setTimeout(async () => {
|
19234
20089
|
var _a, _b, _c;
|
19235
20090
|
|
19236
|
-
if (
|
20091
|
+
if (_this._isClosed) {
|
19237
20092
|
return;
|
19238
20093
|
} // guard for attempting reconnection multiple times while one attempt is still not finished
|
19239
20094
|
|
19240
20095
|
|
19241
|
-
if (
|
20096
|
+
if (_this.attemptingReconnect) {
|
19242
20097
|
return;
|
19243
20098
|
}
|
19244
20099
|
|
19245
20100
|
if (isFireFox() || // TODO remove once clientConfiguration handles firefox case server side
|
19246
|
-
((_a =
|
20101
|
+
((_a = _this.clientConfiguration) === null || _a === void 0 ? void 0 : _a.resumeConnection) === ClientConfigSetting.DISABLED || // signaling state could change to closed due to hardware sleep
|
19247
20102
|
// those connections cannot be resumed
|
19248
|
-
((_c = (_b =
|
19249
|
-
|
20103
|
+
((_c = (_b = _this.primaryPC) === null || _b === void 0 ? void 0 : _b.signalingState) !== null && _c !== void 0 ? _c : 'closed') === 'closed') {
|
20104
|
+
_this.fullReconnectOnNext = true;
|
19250
20105
|
}
|
19251
20106
|
|
19252
20107
|
try {
|
19253
|
-
|
20108
|
+
_this.attemptingReconnect = true;
|
19254
20109
|
|
19255
|
-
if (
|
19256
|
-
await
|
20110
|
+
if (_this.fullReconnectOnNext) {
|
20111
|
+
await _this.restartConnection(signalEvents);
|
19257
20112
|
} else {
|
19258
|
-
await
|
20113
|
+
await _this.resumeConnection(signalEvents);
|
19259
20114
|
}
|
19260
20115
|
|
19261
|
-
|
19262
|
-
|
20116
|
+
_this.reconnectAttempts = 0;
|
20117
|
+
_this.fullReconnectOnNext = false;
|
20118
|
+
|
20119
|
+
if (_this.reconnectTimeout) {
|
20120
|
+
clearTimeout(_this.reconnectTimeout);
|
20121
|
+
}
|
19263
20122
|
} catch (e) {
|
19264
|
-
|
20123
|
+
_this.reconnectAttempts += 1;
|
19265
20124
|
let reconnectRequired = false;
|
19266
20125
|
let recoverable = true;
|
20126
|
+
let requireSignalEvents = false;
|
19267
20127
|
|
19268
20128
|
if (e instanceof UnexpectedConnectionState) {
|
19269
20129
|
livekitLogger.debug('received unrecoverable error', {
|
@@ -19274,35 +20134,29 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19274
20134
|
} else if (!(e instanceof SignalReconnectError)) {
|
19275
20135
|
// cannot resume
|
19276
20136
|
reconnectRequired = true;
|
19277
|
-
} // when we flip from resume to reconnect
|
19278
|
-
//
|
20137
|
+
} // when we flip from resume to reconnect
|
20138
|
+
// we need to fire the right reconnecting events
|
19279
20139
|
|
19280
20140
|
|
19281
|
-
if (reconnectRequired && !
|
19282
|
-
|
19283
|
-
|
19284
|
-
}
|
19285
|
-
|
19286
|
-
const duration = Date.now() - this.reconnectStart;
|
19287
|
-
|
19288
|
-
if (this.reconnectAttempts >= maxReconnectRetries || duration > maxReconnectDuration) {
|
19289
|
-
recoverable = false;
|
20141
|
+
if (reconnectRequired && !_this.fullReconnectOnNext) {
|
20142
|
+
_this.fullReconnectOnNext = true;
|
20143
|
+
requireSignalEvents = true;
|
19290
20144
|
}
|
19291
20145
|
|
19292
20146
|
if (recoverable) {
|
19293
|
-
|
20147
|
+
_this.handleDisconnect('reconnect', requireSignalEvents);
|
19294
20148
|
} else {
|
19295
|
-
|
19296
|
-
this.emit(EngineEvent.Disconnected);
|
19297
|
-
this.close();
|
20149
|
+
disconnect(Date.now() - _this.reconnectStart);
|
19298
20150
|
}
|
19299
20151
|
} finally {
|
19300
|
-
|
20152
|
+
_this.attemptingReconnect = false;
|
19301
20153
|
}
|
19302
20154
|
}, delay);
|
19303
20155
|
};
|
19304
20156
|
|
19305
20157
|
this.client = new SignalClient();
|
20158
|
+
this.client.signalLatency = this.options.expSignalLatency;
|
20159
|
+
this.reconnectPolicy = (_a = this.options.reconnectPolicy) !== null && _a !== void 0 ? _a : new DefaultReconnectPolicy();
|
19306
20160
|
}
|
19307
20161
|
|
19308
20162
|
get isClosed() {
|
@@ -19366,8 +20220,16 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19366
20220
|
throw new TrackInvalidError('a track with the same ID has already been published');
|
19367
20221
|
}
|
19368
20222
|
|
19369
|
-
return new Promise(resolve => {
|
19370
|
-
|
20223
|
+
return new Promise((resolve, reject) => {
|
20224
|
+
const publicationTimeout = setTimeout(() => {
|
20225
|
+
reject(new ConnectionError('publication of local track timed out, no response from server'));
|
20226
|
+
}, 15000);
|
20227
|
+
|
20228
|
+
this.pendingTrackResolvers[req.cid] = info => {
|
20229
|
+
clearTimeout(publicationTimeout);
|
20230
|
+
resolve(info);
|
20231
|
+
};
|
20232
|
+
|
19371
20233
|
this.client.sendAddTrack(req);
|
19372
20234
|
});
|
19373
20235
|
}
|
@@ -19541,8 +20403,7 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19541
20403
|
});
|
19542
20404
|
await this.subscriber.setRemoteDescription(sd); // answer the offer
|
19543
20405
|
|
19544
|
-
const answer = await this.subscriber.
|
19545
|
-
await this.subscriber.pc.setLocalDescription(answer);
|
20406
|
+
const answer = await this.subscriber.createAndSetAnswer();
|
19546
20407
|
this.client.sendAnswer(answer);
|
19547
20408
|
};
|
19548
20409
|
|
@@ -19615,7 +20476,22 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19615
20476
|
this.reliableDC.onerror = this.handleDataError;
|
19616
20477
|
}
|
19617
20478
|
|
20479
|
+
getNextRetryDelay(context) {
|
20480
|
+
try {
|
20481
|
+
return this.reconnectPolicy.nextRetryDelayInMs(context);
|
20482
|
+
} catch (e) {
|
20483
|
+
livekitLogger.warn('encountered error in reconnect policy', {
|
20484
|
+
error: e
|
20485
|
+
});
|
20486
|
+
} // error in user code with provided reconnect policy, stop reconnecting
|
20487
|
+
|
20488
|
+
|
20489
|
+
return null;
|
20490
|
+
}
|
20491
|
+
|
19618
20492
|
async restartConnection() {
|
20493
|
+
let emitRestarting = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20494
|
+
|
19619
20495
|
var _a, _b;
|
19620
20496
|
|
19621
20497
|
if (!this.url || !this.token) {
|
@@ -19625,7 +20501,7 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19625
20501
|
|
19626
20502
|
livekitLogger.info("reconnecting, attempt: ".concat(this.reconnectAttempts));
|
19627
20503
|
|
19628
|
-
if (this.reconnectAttempts === 0) {
|
20504
|
+
if (emitRestarting || this.reconnectAttempts === 0) {
|
19629
20505
|
this.emit(EngineEvent.Restarting);
|
19630
20506
|
}
|
19631
20507
|
|
@@ -19654,6 +20530,8 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19654
20530
|
}
|
19655
20531
|
|
19656
20532
|
async resumeConnection() {
|
20533
|
+
let emitResuming = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20534
|
+
|
19657
20535
|
var _a;
|
19658
20536
|
|
19659
20537
|
if (!this.url || !this.token) {
|
@@ -19668,14 +20546,20 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19668
20546
|
|
19669
20547
|
livekitLogger.info("resuming signal connection, attempt ".concat(this.reconnectAttempts));
|
19670
20548
|
|
19671
|
-
if (this.reconnectAttempts === 0) {
|
20549
|
+
if (emitResuming || this.reconnectAttempts === 0) {
|
19672
20550
|
this.emit(EngineEvent.Resuming);
|
19673
20551
|
}
|
19674
20552
|
|
19675
20553
|
try {
|
19676
20554
|
await this.client.reconnect(this.url, this.token);
|
19677
20555
|
} catch (e) {
|
19678
|
-
|
20556
|
+
let message = '';
|
20557
|
+
|
20558
|
+
if (e instanceof Error) {
|
20559
|
+
message = e.message;
|
20560
|
+
}
|
20561
|
+
|
20562
|
+
throw new SignalReconnectError(message);
|
19679
20563
|
}
|
19680
20564
|
|
19681
20565
|
this.emit(EngineEvent.SignalResumed);
|
@@ -19983,23 +20867,7 @@ class Room extends events.exports.EventEmitter {
|
|
19983
20867
|
this.localParticipant.identity = pi.identity;
|
19984
20868
|
this.localParticipant.updateInfo(pi); // forward metadata changed for the local participant
|
19985
20869
|
|
19986
|
-
this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged,
|
19987
|
-
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
|
19988
|
-
}).on(ParticipantEvent.TrackMuted, pub => {
|
19989
|
-
this.emit(RoomEvent.TrackMuted, pub, this.localParticipant);
|
19990
|
-
}).on(ParticipantEvent.TrackUnmuted, pub => {
|
19991
|
-
this.emit(RoomEvent.TrackUnmuted, pub, this.localParticipant);
|
19992
|
-
}).on(ParticipantEvent.LocalTrackPublished, pub => {
|
19993
|
-
this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
|
19994
|
-
}).on(ParticipantEvent.LocalTrackUnpublished, pub => {
|
19995
|
-
this.emit(RoomEvent.LocalTrackUnpublished, pub, this.localParticipant);
|
19996
|
-
}).on(ParticipantEvent.ConnectionQualityChanged, quality => {
|
19997
|
-
this.emit(RoomEvent.ConnectionQualityChanged, quality, this.localParticipant);
|
19998
|
-
}).on(ParticipantEvent.MediaDevicesError, e => {
|
19999
|
-
this.emit(RoomEvent.MediaDevicesError, e);
|
20000
|
-
}).on(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions => {
|
20001
|
-
this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
|
20002
|
-
}); // populate remote participants, these should not trigger new events
|
20870
|
+
this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).on(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).on(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).on(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).on(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).on(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).on(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).on(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged); // populate remote participants, these should not trigger new events
|
20003
20871
|
|
20004
20872
|
joinResponse.otherParticipants.forEach(info => {
|
20005
20873
|
if (info.sid !== this.localParticipant.sid && info.identity !== this.localParticipant.identity) {
|
@@ -20342,6 +21210,38 @@ class Room extends events.exports.EventEmitter {
|
|
20342
21210
|
});
|
20343
21211
|
};
|
20344
21212
|
|
21213
|
+
this.onLocalParticipantMetadataChanged = metadata => {
|
21214
|
+
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
|
21215
|
+
};
|
21216
|
+
|
21217
|
+
this.onLocalTrackMuted = pub => {
|
21218
|
+
this.emit(RoomEvent.TrackMuted, pub, this.localParticipant);
|
21219
|
+
};
|
21220
|
+
|
21221
|
+
this.onLocalTrackUnmuted = pub => {
|
21222
|
+
this.emit(RoomEvent.TrackUnmuted, pub, this.localParticipant);
|
21223
|
+
};
|
21224
|
+
|
21225
|
+
this.onLocalTrackPublished = pub => {
|
21226
|
+
this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
|
21227
|
+
};
|
21228
|
+
|
21229
|
+
this.onLocalTrackUnpublished = pub => {
|
21230
|
+
this.emit(RoomEvent.LocalTrackUnpublished, pub, this.localParticipant);
|
21231
|
+
};
|
21232
|
+
|
21233
|
+
this.onLocalConnectionQualityChanged = quality => {
|
21234
|
+
this.emit(RoomEvent.ConnectionQualityChanged, quality, this.localParticipant);
|
21235
|
+
};
|
21236
|
+
|
21237
|
+
this.onMediaDevicesError = e => {
|
21238
|
+
this.emit(RoomEvent.MediaDevicesError, e);
|
21239
|
+
};
|
21240
|
+
|
21241
|
+
this.onLocalParticipantPermissionsChanged = prevPermissions => {
|
21242
|
+
this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
|
21243
|
+
};
|
21244
|
+
|
20345
21245
|
this.participants = new Map();
|
20346
21246
|
this.identityToSid = new Map();
|
20347
21247
|
this.options = options || {};
|
@@ -20357,8 +21257,7 @@ class Room extends events.exports.EventEmitter {
|
|
20357
21257
|
return;
|
20358
21258
|
}
|
20359
21259
|
|
20360
|
-
this.engine = new RTCEngine();
|
20361
|
-
this.engine.client.signalLatency = this.options.expSignalLatency;
|
21260
|
+
this.engine = new RTCEngine(this.options);
|
20362
21261
|
this.engine.client.onParticipantUpdate = this.handleParticipantUpdates;
|
20363
21262
|
this.engine.client.onRoomUpdate = this.handleRoomUpdate;
|
20364
21263
|
this.engine.client.onSpeakersChanged = this.handleSpeakersChanged;
|
@@ -20639,6 +21538,7 @@ class Room extends events.exports.EventEmitter {
|
|
20639
21538
|
p.unpublishTrack(pub.trackSid);
|
20640
21539
|
});
|
20641
21540
|
});
|
21541
|
+
this.localParticipant.off(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).off(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).off(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).off(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).off(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).off(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).off(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).off(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
|
20642
21542
|
this.localParticipant.tracks.forEach(pub => {
|
20643
21543
|
var _a, _b;
|
20644
21544
|
|
@@ -20996,5 +21896,5 @@ async function createLocalScreenTracks(options) {
|
|
20996
21896
|
return localTracks;
|
20997
21897
|
}
|
20998
21898
|
|
20999
|
-
export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, DisconnectReason, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, protocolVersion, setLogExtension, setLogLevel, version };
|
21899
|
+
export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, DefaultReconnectPolicy, DisconnectReason, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, protocolVersion, setLogExtension, setLogLevel, version };
|
21000
21900
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|