livekit-client 1.2.2 → 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 +972 -109
- 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 +1 -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.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 +91 -17
- 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 +30 -16
- package/src/room/participant/RemoteParticipant.ts +13 -0
- 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 => {
|
@@ -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 => {
|
@@ -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
|
}
|
@@ -14849,7 +14873,6 @@ class LocalParticipant extends Participant {
|
|
14849
14873
|
}
|
14850
14874
|
|
14851
14875
|
track = publication.track;
|
14852
|
-
track.sender = undefined;
|
14853
14876
|
track.off(TrackEvent.Muted, this.onTrackMuted);
|
14854
14877
|
track.off(TrackEvent.Unmuted, this.onTrackUnmuted);
|
14855
14878
|
track.off(TrackEvent.Ended, this.handleTrackEnded);
|
@@ -14864,29 +14887,19 @@ class LocalParticipant extends Participant {
|
|
14864
14887
|
track.stop();
|
14865
14888
|
}
|
14866
14889
|
|
14867
|
-
|
14868
|
-
|
14869
|
-
|
14870
|
-
|
14871
|
-
|
14872
|
-
|
14873
|
-
|
14874
|
-
|
14875
|
-
|
14876
|
-
|
14877
|
-
|
14878
|
-
(_a = this.engine.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
|
14879
|
-
this.engine.negotiate();
|
14880
|
-
} catch (e) {
|
14881
|
-
livekitLogger.warn('failed to remove track', {
|
14882
|
-
error: e,
|
14883
|
-
method: 'unpublishTrack'
|
14884
|
-
});
|
14885
|
-
}
|
14886
|
-
}
|
14887
|
-
});
|
14888
|
-
} // 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
|
+
}
|
14889
14901
|
|
14902
|
+
track.sender = undefined; // remove from our maps
|
14890
14903
|
|
14891
14904
|
this.tracks.delete(publication.trackSid);
|
14892
14905
|
|
@@ -19050,6 +19063,710 @@ function createConnectionParams(token, info, opts) {
|
|
19050
19063
|
return "?".concat(params.toString());
|
19051
19064
|
}
|
19052
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
|
+
|
19053
19770
|
/** @internal */
|
19054
19771
|
|
19055
19772
|
class PCTransport {
|
@@ -19092,6 +19809,8 @@ class PCTransport {
|
|
19092
19809
|
}
|
19093
19810
|
|
19094
19811
|
async createAndSendOffer(options) {
|
19812
|
+
var _a;
|
19813
|
+
|
19095
19814
|
if (this.onOffer === undefined) {
|
19096
19815
|
return;
|
19097
19816
|
}
|
@@ -19121,30 +19840,72 @@ class PCTransport {
|
|
19121
19840
|
|
19122
19841
|
|
19123
19842
|
livekitLogger.debug('starting to negotiate');
|
19124
|
-
const offer = await this.pc.createOffer(options);
|
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
|
+
}
|
19125
19854
|
|
19126
|
-
|
19127
|
-
|
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
|
+
}
|
19128
19861
|
|
19129
|
-
|
19130
|
-
|
19862
|
+
return false;
|
19863
|
+
}); // add x-google-max-bitrate to fmtp line if not exist
|
19131
19864
|
|
19132
|
-
|
19133
|
-
|
19134
|
-
|
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
|
+
}
|
19135
19871
|
|
19136
|
-
|
19137
|
-
|
19138
|
-
|
19139
|
-
|
19140
|
-
|
19141
|
-
|
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
|
+
}
|
19142
19887
|
});
|
19888
|
+
offer.sdp = write(sdpParsed);
|
19143
19889
|
this.trackBitrates = [];
|
19144
19890
|
await this.pc.setLocalDescription(offer);
|
19145
19891
|
this.onOffer(offer);
|
19146
19892
|
}
|
19147
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
|
+
|
19148
19909
|
setTrackCodecBitrate(sid, codec, maxbr) {
|
19149
19910
|
this.trackBitrates.push({
|
19150
19911
|
sid,
|
@@ -19159,11 +19920,35 @@ class PCTransport {
|
|
19159
19920
|
|
19160
19921
|
}
|
19161
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
|
+
|
19162
19949
|
const lossyDataChannel = '_lossy';
|
19163
19950
|
const reliableDataChannel = '_reliable';
|
19164
|
-
const maxReconnectRetries = 10;
|
19165
19951
|
const minReconnectWait = 2 * 1000;
|
19166
|
-
const maxReconnectDuration = 60 * 1000;
|
19167
19952
|
const maxICEConnectTimeout = 15 * 1000;
|
19168
19953
|
var PCState;
|
19169
19954
|
|
@@ -19178,8 +19963,14 @@ var PCState;
|
|
19178
19963
|
|
19179
19964
|
|
19180
19965
|
class RTCEngine extends events.exports.EventEmitter {
|
19181
|
-
constructor() {
|
19966
|
+
constructor(options) {
|
19967
|
+
var _this;
|
19968
|
+
|
19969
|
+
var _a;
|
19970
|
+
|
19182
19971
|
super();
|
19972
|
+
_this = this;
|
19973
|
+
this.options = options;
|
19183
19974
|
this.rtcConfig = {};
|
19184
19975
|
this.subscriberPrimary = false;
|
19185
19976
|
this.pcState = PCState.New;
|
@@ -19254,53 +20045,85 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19254
20045
|
// after a number of retries, we'll close and give up permanently
|
19255
20046
|
|
19256
20047
|
|
19257
|
-
this.handleDisconnect = connection
|
19258
|
-
|
20048
|
+
this.handleDisconnect = function (connection) {
|
20049
|
+
let signalEvents = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
20050
|
+
|
20051
|
+
if (_this._isClosed) {
|
19259
20052
|
return;
|
19260
20053
|
}
|
19261
20054
|
|
19262
20055
|
livekitLogger.debug("".concat(connection, " disconnected"));
|
19263
20056
|
|
19264
|
-
if (
|
20057
|
+
if (_this.reconnectAttempts === 0) {
|
19265
20058
|
// only reset start time on the first try
|
19266
|
-
|
20059
|
+
_this.reconnectStart = Date.now();
|
20060
|
+
}
|
20061
|
+
|
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;
|
19267
20080
|
}
|
19268
20081
|
|
19269
|
-
|
19270
|
-
|
20082
|
+
livekitLogger.debug("reconnecting in ".concat(delay, "ms"));
|
20083
|
+
|
20084
|
+
if (_this.reconnectTimeout) {
|
20085
|
+
clearTimeout(_this.reconnectTimeout);
|
20086
|
+
}
|
20087
|
+
|
20088
|
+
_this.reconnectTimeout = setTimeout(async () => {
|
19271
20089
|
var _a, _b, _c;
|
19272
20090
|
|
19273
|
-
if (
|
20091
|
+
if (_this._isClosed) {
|
19274
20092
|
return;
|
19275
20093
|
} // guard for attempting reconnection multiple times while one attempt is still not finished
|
19276
20094
|
|
19277
20095
|
|
19278
|
-
if (
|
20096
|
+
if (_this.attemptingReconnect) {
|
19279
20097
|
return;
|
19280
20098
|
}
|
19281
20099
|
|
19282
20100
|
if (isFireFox() || // TODO remove once clientConfiguration handles firefox case server side
|
19283
|
-
((_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
|
19284
20102
|
// those connections cannot be resumed
|
19285
|
-
((_c = (_b =
|
19286
|
-
|
20103
|
+
((_c = (_b = _this.primaryPC) === null || _b === void 0 ? void 0 : _b.signalingState) !== null && _c !== void 0 ? _c : 'closed') === 'closed') {
|
20104
|
+
_this.fullReconnectOnNext = true;
|
19287
20105
|
}
|
19288
20106
|
|
19289
20107
|
try {
|
19290
|
-
|
20108
|
+
_this.attemptingReconnect = true;
|
19291
20109
|
|
19292
|
-
if (
|
19293
|
-
await
|
20110
|
+
if (_this.fullReconnectOnNext) {
|
20111
|
+
await _this.restartConnection(signalEvents);
|
19294
20112
|
} else {
|
19295
|
-
await
|
20113
|
+
await _this.resumeConnection(signalEvents);
|
19296
20114
|
}
|
19297
20115
|
|
19298
|
-
|
19299
|
-
|
20116
|
+
_this.reconnectAttempts = 0;
|
20117
|
+
_this.fullReconnectOnNext = false;
|
20118
|
+
|
20119
|
+
if (_this.reconnectTimeout) {
|
20120
|
+
clearTimeout(_this.reconnectTimeout);
|
20121
|
+
}
|
19300
20122
|
} catch (e) {
|
19301
|
-
|
20123
|
+
_this.reconnectAttempts += 1;
|
19302
20124
|
let reconnectRequired = false;
|
19303
20125
|
let recoverable = true;
|
20126
|
+
let requireSignalEvents = false;
|
19304
20127
|
|
19305
20128
|
if (e instanceof UnexpectedConnectionState) {
|
19306
20129
|
livekitLogger.debug('received unrecoverable error', {
|
@@ -19311,35 +20134,29 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19311
20134
|
} else if (!(e instanceof SignalReconnectError)) {
|
19312
20135
|
// cannot resume
|
19313
20136
|
reconnectRequired = true;
|
19314
|
-
} // when we flip from resume to reconnect
|
19315
|
-
//
|
19316
|
-
|
19317
|
-
|
19318
|
-
if (reconnectRequired && !this.fullReconnectOnNext) {
|
19319
|
-
this.fullReconnectOnNext = true;
|
19320
|
-
this.reconnectAttempts = 0;
|
19321
|
-
}
|
20137
|
+
} // when we flip from resume to reconnect
|
20138
|
+
// we need to fire the right reconnecting events
|
19322
20139
|
|
19323
|
-
const duration = Date.now() - this.reconnectStart;
|
19324
20140
|
|
19325
|
-
if (
|
19326
|
-
|
20141
|
+
if (reconnectRequired && !_this.fullReconnectOnNext) {
|
20142
|
+
_this.fullReconnectOnNext = true;
|
20143
|
+
requireSignalEvents = true;
|
19327
20144
|
}
|
19328
20145
|
|
19329
20146
|
if (recoverable) {
|
19330
|
-
|
20147
|
+
_this.handleDisconnect('reconnect', requireSignalEvents);
|
19331
20148
|
} else {
|
19332
|
-
|
19333
|
-
this.emit(EngineEvent.Disconnected);
|
19334
|
-
this.close();
|
20149
|
+
disconnect(Date.now() - _this.reconnectStart);
|
19335
20150
|
}
|
19336
20151
|
} finally {
|
19337
|
-
|
20152
|
+
_this.attemptingReconnect = false;
|
19338
20153
|
}
|
19339
20154
|
}, delay);
|
19340
20155
|
};
|
19341
20156
|
|
19342
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();
|
19343
20160
|
}
|
19344
20161
|
|
19345
20162
|
get isClosed() {
|
@@ -19403,8 +20220,16 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19403
20220
|
throw new TrackInvalidError('a track with the same ID has already been published');
|
19404
20221
|
}
|
19405
20222
|
|
19406
|
-
return new Promise(resolve => {
|
19407
|
-
|
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
|
+
|
19408
20233
|
this.client.sendAddTrack(req);
|
19409
20234
|
});
|
19410
20235
|
}
|
@@ -19578,8 +20403,7 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19578
20403
|
});
|
19579
20404
|
await this.subscriber.setRemoteDescription(sd); // answer the offer
|
19580
20405
|
|
19581
|
-
const answer = await this.subscriber.
|
19582
|
-
await this.subscriber.pc.setLocalDescription(answer);
|
20406
|
+
const answer = await this.subscriber.createAndSetAnswer();
|
19583
20407
|
this.client.sendAnswer(answer);
|
19584
20408
|
};
|
19585
20409
|
|
@@ -19652,7 +20476,22 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19652
20476
|
this.reliableDC.onerror = this.handleDataError;
|
19653
20477
|
}
|
19654
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
|
+
|
19655
20492
|
async restartConnection() {
|
20493
|
+
let emitRestarting = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20494
|
+
|
19656
20495
|
var _a, _b;
|
19657
20496
|
|
19658
20497
|
if (!this.url || !this.token) {
|
@@ -19662,7 +20501,7 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19662
20501
|
|
19663
20502
|
livekitLogger.info("reconnecting, attempt: ".concat(this.reconnectAttempts));
|
19664
20503
|
|
19665
|
-
if (this.reconnectAttempts === 0) {
|
20504
|
+
if (emitRestarting || this.reconnectAttempts === 0) {
|
19666
20505
|
this.emit(EngineEvent.Restarting);
|
19667
20506
|
}
|
19668
20507
|
|
@@ -19691,6 +20530,8 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19691
20530
|
}
|
19692
20531
|
|
19693
20532
|
async resumeConnection() {
|
20533
|
+
let emitResuming = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
20534
|
+
|
19694
20535
|
var _a;
|
19695
20536
|
|
19696
20537
|
if (!this.url || !this.token) {
|
@@ -19705,14 +20546,20 @@ class RTCEngine extends events.exports.EventEmitter {
|
|
19705
20546
|
|
19706
20547
|
livekitLogger.info("resuming signal connection, attempt ".concat(this.reconnectAttempts));
|
19707
20548
|
|
19708
|
-
if (this.reconnectAttempts === 0) {
|
20549
|
+
if (emitResuming || this.reconnectAttempts === 0) {
|
19709
20550
|
this.emit(EngineEvent.Resuming);
|
19710
20551
|
}
|
19711
20552
|
|
19712
20553
|
try {
|
19713
20554
|
await this.client.reconnect(this.url, this.token);
|
19714
20555
|
} catch (e) {
|
19715
|
-
|
20556
|
+
let message = '';
|
20557
|
+
|
20558
|
+
if (e instanceof Error) {
|
20559
|
+
message = e.message;
|
20560
|
+
}
|
20561
|
+
|
20562
|
+
throw new SignalReconnectError(message);
|
19716
20563
|
}
|
19717
20564
|
|
19718
20565
|
this.emit(EngineEvent.SignalResumed);
|
@@ -20020,23 +20867,7 @@ class Room extends events.exports.EventEmitter {
|
|
20020
20867
|
this.localParticipant.identity = pi.identity;
|
20021
20868
|
this.localParticipant.updateInfo(pi); // forward metadata changed for the local participant
|
20022
20869
|
|
20023
|
-
this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged,
|
20024
|
-
this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
|
20025
|
-
}).on(ParticipantEvent.TrackMuted, pub => {
|
20026
|
-
this.emit(RoomEvent.TrackMuted, pub, this.localParticipant);
|
20027
|
-
}).on(ParticipantEvent.TrackUnmuted, pub => {
|
20028
|
-
this.emit(RoomEvent.TrackUnmuted, pub, this.localParticipant);
|
20029
|
-
}).on(ParticipantEvent.LocalTrackPublished, pub => {
|
20030
|
-
this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
|
20031
|
-
}).on(ParticipantEvent.LocalTrackUnpublished, pub => {
|
20032
|
-
this.emit(RoomEvent.LocalTrackUnpublished, pub, this.localParticipant);
|
20033
|
-
}).on(ParticipantEvent.ConnectionQualityChanged, quality => {
|
20034
|
-
this.emit(RoomEvent.ConnectionQualityChanged, quality, this.localParticipant);
|
20035
|
-
}).on(ParticipantEvent.MediaDevicesError, e => {
|
20036
|
-
this.emit(RoomEvent.MediaDevicesError, e);
|
20037
|
-
}).on(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions => {
|
20038
|
-
this.emit(RoomEvent.ParticipantPermissionsChanged, prevPermissions, this.localParticipant);
|
20039
|
-
}); // 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
|
20040
20871
|
|
20041
20872
|
joinResponse.otherParticipants.forEach(info => {
|
20042
20873
|
if (info.sid !== this.localParticipant.sid && info.identity !== this.localParticipant.identity) {
|
@@ -20379,6 +21210,38 @@ class Room extends events.exports.EventEmitter {
|
|
20379
21210
|
});
|
20380
21211
|
};
|
20381
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
|
+
|
20382
21245
|
this.participants = new Map();
|
20383
21246
|
this.identityToSid = new Map();
|
20384
21247
|
this.options = options || {};
|
@@ -20394,8 +21257,7 @@ class Room extends events.exports.EventEmitter {
|
|
20394
21257
|
return;
|
20395
21258
|
}
|
20396
21259
|
|
20397
|
-
this.engine = new RTCEngine();
|
20398
|
-
this.engine.client.signalLatency = this.options.expSignalLatency;
|
21260
|
+
this.engine = new RTCEngine(this.options);
|
20399
21261
|
this.engine.client.onParticipantUpdate = this.handleParticipantUpdates;
|
20400
21262
|
this.engine.client.onRoomUpdate = this.handleRoomUpdate;
|
20401
21263
|
this.engine.client.onSpeakersChanged = this.handleSpeakersChanged;
|
@@ -20676,6 +21538,7 @@ class Room extends events.exports.EventEmitter {
|
|
20676
21538
|
p.unpublishTrack(pub.trackSid);
|
20677
21539
|
});
|
20678
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);
|
20679
21542
|
this.localParticipant.tracks.forEach(pub => {
|
20680
21543
|
var _a, _b;
|
20681
21544
|
|
@@ -21033,5 +21896,5 @@ async function createLocalScreenTracks(options) {
|
|
21033
21896
|
return localTracks;
|
21034
21897
|
}
|
21035
21898
|
|
21036
|
-
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 };
|
21037
21900
|
//# sourceMappingURL=livekit-client.esm.mjs.map
|