livekit-client 1.1.0 → 1.1.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 +245 -94
- 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/proto/livekit_rtc.d.ts +7 -0
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +5 -1
- 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 +2 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/proto/livekit_rtc.ts +12 -0
- package/src/room/Room.ts +40 -15
- package/src/room/participant/LocalParticipant.ts +128 -55
- package/src/room/participant/RemoteParticipant.ts +5 -11
- package/src/room/track/LocalVideoTrack.ts +34 -7
- package/src/room/track/RemoteVideoTrack.ts +32 -4
- package/src/room/utils.ts +3 -2
@@ -7049,7 +7049,8 @@ function createBaseAddTrackRequest() {
|
|
7049
7049
|
disableDtx: false,
|
7050
7050
|
source: 0,
|
7051
7051
|
layers: [],
|
7052
|
-
simulcastCodecs: []
|
7052
|
+
simulcastCodecs: [],
|
7053
|
+
sid: ''
|
7053
7054
|
};
|
7054
7055
|
}
|
7055
7056
|
|
@@ -7097,6 +7098,10 @@ const AddTrackRequest = {
|
|
7097
7098
|
SimulcastCodec.encode(v, writer.uint32(82).fork()).ldelim();
|
7098
7099
|
}
|
7099
7100
|
|
7101
|
+
if (message.sid !== '') {
|
7102
|
+
writer.uint32(90).string(message.sid);
|
7103
|
+
}
|
7104
|
+
|
7100
7105
|
return writer;
|
7101
7106
|
},
|
7102
7107
|
|
@@ -7149,6 +7154,10 @@ const AddTrackRequest = {
|
|
7149
7154
|
message.simulcastCodecs.push(SimulcastCodec.decode(reader, reader.uint32()));
|
7150
7155
|
break;
|
7151
7156
|
|
7157
|
+
case 11:
|
7158
|
+
message.sid = reader.string();
|
7159
|
+
break;
|
7160
|
+
|
7152
7161
|
default:
|
7153
7162
|
reader.skipType(tag & 7);
|
7154
7163
|
break;
|
@@ -7169,7 +7178,8 @@ const AddTrackRequest = {
|
|
7169
7178
|
disableDtx: isSet(object.disableDtx) ? Boolean(object.disableDtx) : false,
|
7170
7179
|
source: isSet(object.source) ? trackSourceFromJSON(object.source) : 0,
|
7171
7180
|
layers: Array.isArray(object === null || object === void 0 ? void 0 : object.layers) ? object.layers.map(e => VideoLayer.fromJSON(e)) : [],
|
7172
|
-
simulcastCodecs: Array.isArray(object === null || object === void 0 ? void 0 : object.simulcastCodecs) ? object.simulcastCodecs.map(e => SimulcastCodec.fromJSON(e)) : []
|
7181
|
+
simulcastCodecs: Array.isArray(object === null || object === void 0 ? void 0 : object.simulcastCodecs) ? object.simulcastCodecs.map(e => SimulcastCodec.fromJSON(e)) : [],
|
7182
|
+
sid: isSet(object.sid) ? String(object.sid) : ''
|
7173
7183
|
};
|
7174
7184
|
},
|
7175
7185
|
|
@@ -7196,11 +7206,12 @@ const AddTrackRequest = {
|
|
7196
7206
|
obj.simulcastCodecs = [];
|
7197
7207
|
}
|
7198
7208
|
|
7209
|
+
message.sid !== undefined && (obj.sid = message.sid);
|
7199
7210
|
return obj;
|
7200
7211
|
},
|
7201
7212
|
|
7202
7213
|
fromPartial(object) {
|
7203
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
7214
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
7204
7215
|
|
7205
7216
|
const message = createBaseAddTrackRequest();
|
7206
7217
|
message.cid = (_a = object.cid) !== null && _a !== void 0 ? _a : '';
|
@@ -7213,6 +7224,7 @@ const AddTrackRequest = {
|
|
7213
7224
|
message.source = (_h = object.source) !== null && _h !== void 0 ? _h : 0;
|
7214
7225
|
message.layers = ((_j = object.layers) === null || _j === void 0 ? void 0 : _j.map(e => VideoLayer.fromPartial(e))) || [];
|
7215
7226
|
message.simulcastCodecs = ((_k = object.simulcastCodecs) === null || _k === void 0 ? void 0 : _k.map(e => SimulcastCodec.fromPartial(e))) || [];
|
7227
|
+
message.sid = (_l = object.sid) !== null && _l !== void 0 ? _l : '';
|
7216
7228
|
return message;
|
7217
7229
|
}
|
7218
7230
|
|
@@ -10058,7 +10070,7 @@ function computeBitrate(currentStats, prevStats) {
|
|
10058
10070
|
return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
|
10059
10071
|
}
|
10060
10072
|
|
10061
|
-
var version$1 = "1.1.
|
10073
|
+
var version$1 = "1.1.3";
|
10062
10074
|
|
10063
10075
|
const version = version$1;
|
10064
10076
|
const protocolVersion = 8;
|
@@ -10130,9 +10142,10 @@ function getEmptyVideoStreamTrack() {
|
|
10130
10142
|
var _a;
|
10131
10143
|
|
10132
10144
|
if (!emptyVideoStreamTrack) {
|
10133
|
-
const canvas = document.createElement('canvas');
|
10134
|
-
|
10135
|
-
canvas.
|
10145
|
+
const canvas = document.createElement('canvas'); // the canvas size is set to 16, because electron apps seem to fail with smaller values
|
10146
|
+
|
10147
|
+
canvas.width = 16;
|
10148
|
+
canvas.height = 16;
|
10136
10149
|
(_a = canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.fillRect(0, 0, canvas.width, canvas.height); // @ts-ignore
|
10137
10150
|
|
10138
10151
|
const emptyStream = canvas.captureStream();
|
@@ -11514,6 +11527,7 @@ class LocalAudioTrack extends LocalTrack {
|
|
11514
11527
|
|
11515
11528
|
}
|
11516
11529
|
|
11530
|
+
const refreshSubscribedCodecAfterNewCodec = 5000;
|
11517
11531
|
class LocalVideoTrack extends LocalTrack {
|
11518
11532
|
constructor(mediaTrack, constraints) {
|
11519
11533
|
super(mediaTrack, Track.Kind.Video, constraints);
|
@@ -11730,7 +11744,14 @@ class LocalVideoTrack extends LocalTrack {
|
|
11730
11744
|
return;
|
11731
11745
|
}
|
11732
11746
|
|
11733
|
-
simulcastCodecInfo.sender = sender;
|
11747
|
+
simulcastCodecInfo.sender = sender; // browser will reenable disabled codec/layers after new codec has been published,
|
11748
|
+
// so refresh subscribedCodecs after publish a new codec
|
11749
|
+
|
11750
|
+
setTimeout(() => {
|
11751
|
+
if (this.subscribedCodecs) {
|
11752
|
+
this.setPublishingCodecs(this.subscribedCodecs);
|
11753
|
+
}
|
11754
|
+
}, refreshSubscribedCodecAfterNewCodec);
|
11734
11755
|
}
|
11735
11756
|
/**
|
11736
11757
|
* @internal
|
@@ -11739,25 +11760,41 @@ class LocalVideoTrack extends LocalTrack {
|
|
11739
11760
|
|
11740
11761
|
|
11741
11762
|
async setPublishingCodecs(codecs) {
|
11742
|
-
livekitLogger.debug('setting publishing codecs',
|
11763
|
+
livekitLogger.debug('setting publishing codecs', {
|
11764
|
+
codecs,
|
11765
|
+
currentCodec: this.codec
|
11766
|
+
}); // only enable simulcast codec for preference codec setted
|
11767
|
+
|
11768
|
+
if (!this.codec && codecs.length > 0) {
|
11769
|
+
await this.setPublishingLayers(codecs[0].qualities);
|
11770
|
+
return [];
|
11771
|
+
}
|
11772
|
+
|
11773
|
+
this.subscribedCodecs = codecs;
|
11774
|
+
const newCodecs = [];
|
11743
11775
|
|
11744
11776
|
for await (const codec of codecs) {
|
11745
|
-
if (this.codec === codec.codec) {
|
11777
|
+
if (!this.codec || this.codec === codec.codec) {
|
11746
11778
|
await this.setPublishingLayers(codec.qualities);
|
11747
11779
|
} else {
|
11748
11780
|
const simulcastCodecInfo = this.simulcastCodecs.get(codec.codec);
|
11749
11781
|
livekitLogger.debug("try setPublishingCodec for ".concat(codec.codec), simulcastCodecInfo);
|
11750
11782
|
|
11751
11783
|
if (!simulcastCodecInfo || !simulcastCodecInfo.sender) {
|
11752
|
-
|
11753
|
-
|
11754
|
-
|
11755
|
-
|
11784
|
+
for (const q of codec.qualities) {
|
11785
|
+
if (q.enabled) {
|
11786
|
+
newCodecs.push(codec.codec);
|
11787
|
+
break;
|
11788
|
+
}
|
11789
|
+
}
|
11790
|
+
} else if (simulcastCodecInfo.encodings) {
|
11756
11791
|
livekitLogger.debug("try setPublishingLayersForSender ".concat(codec.codec));
|
11757
11792
|
await setPublishingLayersForSender(simulcastCodecInfo.sender, simulcastCodecInfo.encodings, codec.qualities);
|
11758
11793
|
}
|
11759
11794
|
}
|
11760
11795
|
}
|
11796
|
+
|
11797
|
+
return newCodecs;
|
11761
11798
|
}
|
11762
11799
|
/**
|
11763
11800
|
* @internal
|
@@ -12188,6 +12225,8 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
12188
12225
|
|
12189
12226
|
this.debouncedHandleResize();
|
12190
12227
|
this.updateVisibility();
|
12228
|
+
} else {
|
12229
|
+
livekitLogger.warn('visibility resize observer not triggered');
|
12191
12230
|
}
|
12192
12231
|
}
|
12193
12232
|
/**
|
@@ -12336,9 +12375,7 @@ class RemoteVideoTrack extends RemoteTrack {
|
|
12336
12375
|
}
|
12337
12376
|
|
12338
12377
|
class HTMLElementInfo {
|
12339
|
-
constructor(element) {
|
12340
|
-
let visible = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
12341
|
-
|
12378
|
+
constructor(element, visible) {
|
12342
12379
|
this.onVisibilityChanged = entry => {
|
12343
12380
|
var _a;
|
12344
12381
|
|
@@ -12355,7 +12392,7 @@ class HTMLElementInfo {
|
|
12355
12392
|
};
|
12356
12393
|
|
12357
12394
|
this.element = element;
|
12358
|
-
this.visible = visible;
|
12395
|
+
this.visible = visible !== null && visible !== void 0 ? visible : isElementInViewport(element);
|
12359
12396
|
this.visibilityChangedAt = 0;
|
12360
12397
|
}
|
12361
12398
|
|
@@ -12364,7 +12401,7 @@ class HTMLElementInfo {
|
|
12364
12401
|
}
|
12365
12402
|
|
12366
12403
|
height() {
|
12367
|
-
return this.element.
|
12404
|
+
return this.element.clientHeight;
|
12368
12405
|
}
|
12369
12406
|
|
12370
12407
|
observe() {
|
@@ -12386,6 +12423,29 @@ class HTMLElementInfo {
|
|
12386
12423
|
(_b = getResizeObserver()) === null || _b === void 0 ? void 0 : _b.unobserve(this.element);
|
12387
12424
|
}
|
12388
12425
|
|
12426
|
+
} // does not account for occlusion by other elements
|
12427
|
+
|
12428
|
+
|
12429
|
+
function isElementInViewport(el) {
|
12430
|
+
let top = el.offsetTop;
|
12431
|
+
let left = el.offsetLeft;
|
12432
|
+
const width = el.offsetWidth;
|
12433
|
+
const height = el.offsetHeight;
|
12434
|
+
const {
|
12435
|
+
hidden
|
12436
|
+
} = el;
|
12437
|
+
const {
|
12438
|
+
opacity,
|
12439
|
+
display
|
12440
|
+
} = getComputedStyle(el);
|
12441
|
+
|
12442
|
+
while (el.offsetParent) {
|
12443
|
+
el = el.offsetParent;
|
12444
|
+
top += el.offsetTop;
|
12445
|
+
left += el.offsetLeft;
|
12446
|
+
}
|
12447
|
+
|
12448
|
+
return top < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && top + height > window.pageYOffset && left + width > window.pageXOffset && !hidden && (opacity !== '' ? parseFloat(opacity) > 0 : true) && display !== 'none';
|
12389
12449
|
}
|
12390
12450
|
|
12391
12451
|
class TrackPublication extends events.exports.EventEmitter {
|
@@ -13358,9 +13418,7 @@ class RemoteParticipant extends Participant {
|
|
13358
13418
|
|
13359
13419
|
|
13360
13420
|
static fromParticipantInfo(signalClient, pi) {
|
13361
|
-
|
13362
|
-
rp.updateInfo(pi);
|
13363
|
-
return rp;
|
13421
|
+
return new RemoteParticipant(signalClient, pi.sid, pi.identity);
|
13364
13422
|
}
|
13365
13423
|
|
13366
13424
|
addTrackPublication(publication) {
|
@@ -13501,7 +13559,6 @@ class RemoteParticipant extends Participant {
|
|
13501
13559
|
|
13502
13560
|
|
13503
13561
|
updateInfo(info) {
|
13504
|
-
const alreadyHasMetadata = this.hasMetadata;
|
13505
13562
|
super.updateInfo(info); // we are getting a list of all available tracks, reconcile in here
|
13506
13563
|
// and send out events for changes
|
13507
13564
|
// reconcile track publications, publish events only if metadata is already there
|
@@ -13529,14 +13586,11 @@ class RemoteParticipant extends Participant {
|
|
13529
13586
|
}
|
13530
13587
|
|
13531
13588
|
validTracks.set(ti.sid, publication);
|
13532
|
-
}); //
|
13533
|
-
|
13534
|
-
if (alreadyHasMetadata) {
|
13535
|
-
newTracks.forEach(publication => {
|
13536
|
-
this.emit(ParticipantEvent.TrackPublished, publication);
|
13537
|
-
});
|
13538
|
-
} // detect removed tracks
|
13589
|
+
}); // always emit events for new publications, Room will not forward them unless it's ready
|
13539
13590
|
|
13591
|
+
newTracks.forEach(publication => {
|
13592
|
+
this.emit(ParticipantEvent.TrackPublished, publication);
|
13593
|
+
}); // detect removed tracks
|
13540
13594
|
|
13541
13595
|
this.tracks.forEach(publication => {
|
13542
13596
|
if (!validTracks.has(publication.trackSid)) {
|
@@ -13605,7 +13659,7 @@ class RemoteParticipant extends Participant {
|
|
13605
13659
|
|
13606
13660
|
}
|
13607
13661
|
|
13608
|
-
const
|
13662
|
+
const compatibleCodec = 'vp8';
|
13609
13663
|
class LocalParticipant extends Participant {
|
13610
13664
|
/** @internal */
|
13611
13665
|
constructor(sid, identity, engine, options) {
|
@@ -13654,8 +13708,8 @@ class LocalParticipant extends Participant {
|
|
13654
13708
|
this.onTrackMuted(track, track.isMuted);
|
13655
13709
|
};
|
13656
13710
|
|
13657
|
-
this.handleSubscribedQualityUpdate = update => {
|
13658
|
-
var _a, _b
|
13711
|
+
this.handleSubscribedQualityUpdate = async update => {
|
13712
|
+
var _a, _b;
|
13659
13713
|
|
13660
13714
|
if (!((_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.dynacast)) {
|
13661
13715
|
return;
|
@@ -13672,9 +13726,18 @@ class LocalParticipant extends Participant {
|
|
13672
13726
|
}
|
13673
13727
|
|
13674
13728
|
if (update.subscribedCodecs.length > 0) {
|
13675
|
-
(
|
13729
|
+
if (!pub.videoTrack) {
|
13730
|
+
return;
|
13731
|
+
}
|
13732
|
+
|
13733
|
+
const newCodecs = await pub.videoTrack.setPublishingCodecs(update.subscribedCodecs);
|
13734
|
+
|
13735
|
+
for await (const codec of newCodecs) {
|
13736
|
+
livekitLogger.debug("publish ".concat(codec, " for ").concat(pub.videoTrack.sid));
|
13737
|
+
await this.publishAdditionalCodecForTrack(pub.videoTrack, codec, pub.options);
|
13738
|
+
}
|
13676
13739
|
} else if (update.subscribedQualities.length > 0) {
|
13677
|
-
(
|
13740
|
+
(_b = pub.videoTrack) === null || _b === void 0 ? void 0 : _b.setPublishingLayers(update.subscribedQualities);
|
13678
13741
|
}
|
13679
13742
|
};
|
13680
13743
|
|
@@ -14088,7 +14151,6 @@ class LocalParticipant extends Participant {
|
|
14088
14151
|
|
14089
14152
|
let encodings;
|
14090
14153
|
let simEncodings;
|
14091
|
-
let simulcastTracks;
|
14092
14154
|
|
14093
14155
|
if (track.kind === Track.Kind.Video) {
|
14094
14156
|
// TODO: support react native, which doesn't expose getSettings
|
@@ -14099,26 +14161,30 @@ class LocalParticipant extends Participant {
|
|
14099
14161
|
req.width = width !== null && width !== void 0 ? width : 0;
|
14100
14162
|
req.height = height !== null && height !== void 0 ? height : 0; // for svc codecs, disable simulcast and use vp8 for backup codec
|
14101
14163
|
|
14102
|
-
if (track instanceof LocalVideoTrack
|
14103
|
-
|
14104
|
-
|
14105
|
-
|
14106
|
-
|
14107
|
-
|
14108
|
-
|
14109
|
-
|
14110
|
-
|
14111
|
-
|
14112
|
-
|
14113
|
-
|
14114
|
-
|
14115
|
-
|
14116
|
-
|
14117
|
-
|
14118
|
-
|
14119
|
-
|
14120
|
-
|
14121
|
-
|
14164
|
+
if (track instanceof LocalVideoTrack) {
|
14165
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'vp9' || (opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'av1') {
|
14166
|
+
// set scalabilityMode to 'L3T3' by default
|
14167
|
+
opts.scalabilityMode = (_g = opts.scalabilityMode) !== null && _g !== void 0 ? _g : 'L3T3'; // add backup codec track
|
14168
|
+
|
14169
|
+
const simOpts = _objectSpread2({}, opts);
|
14170
|
+
|
14171
|
+
simOpts.simulcast = true;
|
14172
|
+
simOpts.scalabilityMode = undefined;
|
14173
|
+
simEncodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, width, height, simOpts);
|
14174
|
+
} // set vp8 codec as backup for any other codecs
|
14175
|
+
|
14176
|
+
|
14177
|
+
if (opts.videoCodec && opts.videoCodec !== 'vp8') {
|
14178
|
+
req.simulcastCodecs = [{
|
14179
|
+
codec: opts.videoCodec,
|
14180
|
+
cid: track.mediaStreamTrack.id,
|
14181
|
+
enableSimulcastLayers: true
|
14182
|
+
}, {
|
14183
|
+
codec: compatibleCodec,
|
14184
|
+
cid: '',
|
14185
|
+
enableSimulcastLayers: true
|
14186
|
+
}];
|
14187
|
+
}
|
14122
14188
|
}
|
14123
14189
|
|
14124
14190
|
encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, width, height, opts);
|
@@ -14163,24 +14229,6 @@ class LocalParticipant extends Participant {
|
|
14163
14229
|
track.codec = opts.videoCodec;
|
14164
14230
|
}
|
14165
14231
|
|
14166
|
-
const localTrack = track;
|
14167
|
-
|
14168
|
-
if (simulcastTracks) {
|
14169
|
-
for await (const simulcastTrack of simulcastTracks) {
|
14170
|
-
const simTransceiverInit = {
|
14171
|
-
direction: 'sendonly'
|
14172
|
-
};
|
14173
|
-
|
14174
|
-
if (simulcastTrack.encodings) {
|
14175
|
-
simTransceiverInit.sendEncodings = simulcastTrack.encodings;
|
14176
|
-
}
|
14177
|
-
|
14178
|
-
const simTransceiver = await this.engine.publisher.pc.addTransceiver(simulcastTrack.mediaStreamTrack, simTransceiverInit);
|
14179
|
-
this.setPreferredCodec(simTransceiver, localTrack.kind, simulcastTrack.codec);
|
14180
|
-
localTrack.setSimulcastTrackSender(simulcastTrack.codec, simTransceiver.sender);
|
14181
|
-
}
|
14182
|
-
}
|
14183
|
-
|
14184
14232
|
this.engine.negotiate(); // store RTPSender
|
14185
14233
|
|
14186
14234
|
track.sender = transceiver.sender;
|
@@ -14196,6 +14244,86 @@ class LocalParticipant extends Participant {
|
|
14196
14244
|
this.emit(ParticipantEvent.LocalTrackPublished, publication);
|
14197
14245
|
return publication;
|
14198
14246
|
}
|
14247
|
+
/** @internal
|
14248
|
+
* publish additional codec to existing track
|
14249
|
+
*/
|
14250
|
+
|
14251
|
+
|
14252
|
+
async publishAdditionalCodecForTrack(track, videoCodec, options) {
|
14253
|
+
var _a, _b, _c, _d, _e;
|
14254
|
+
|
14255
|
+
const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // clear scalabilityMode setting for backup codec
|
14256
|
+
|
14257
|
+
|
14258
|
+
opts.scalabilityMode = undefined;
|
14259
|
+
opts.videoCodec = videoCodec; // is it not published? if so skip
|
14260
|
+
|
14261
|
+
let existingPublication;
|
14262
|
+
this.tracks.forEach(publication => {
|
14263
|
+
if (!publication.track) {
|
14264
|
+
return;
|
14265
|
+
}
|
14266
|
+
|
14267
|
+
if (publication.track === track) {
|
14268
|
+
existingPublication = publication;
|
14269
|
+
}
|
14270
|
+
});
|
14271
|
+
|
14272
|
+
if (!existingPublication) {
|
14273
|
+
throw new TrackInvalidError('track is not published');
|
14274
|
+
}
|
14275
|
+
|
14276
|
+
if (!(track instanceof LocalVideoTrack)) {
|
14277
|
+
throw new TrackInvalidError('track is not a video track');
|
14278
|
+
}
|
14279
|
+
|
14280
|
+
const settings = track.mediaStreamTrack.getSettings();
|
14281
|
+
const width = (_b = settings.width) !== null && _b !== void 0 ? _b : (_c = track.dimensions) === null || _c === void 0 ? void 0 : _c.width;
|
14282
|
+
const height = (_d = settings.height) !== null && _d !== void 0 ? _d : (_e = track.dimensions) === null || _e === void 0 ? void 0 : _e.height;
|
14283
|
+
const encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, width, height, opts);
|
14284
|
+
const simulcastTrack = track.addSimulcastTrack(opts.videoCodec, encodings);
|
14285
|
+
const req = AddTrackRequest.fromPartial({
|
14286
|
+
cid: simulcastTrack.mediaStreamTrack.id,
|
14287
|
+
type: Track.kindToProto(track.kind),
|
14288
|
+
muted: track.isMuted,
|
14289
|
+
source: Track.sourceToProto(track.source),
|
14290
|
+
sid: track.sid,
|
14291
|
+
simulcastCodecs: [{
|
14292
|
+
codec: opts.videoCodec,
|
14293
|
+
cid: simulcastTrack.mediaStreamTrack.id,
|
14294
|
+
enableSimulcastLayers: opts.simulcast
|
14295
|
+
}]
|
14296
|
+
});
|
14297
|
+
req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
|
14298
|
+
|
14299
|
+
if (!this.engine || this.engine.isClosed) {
|
14300
|
+
throw new UnexpectedConnectionState('cannot publish track when not connected');
|
14301
|
+
}
|
14302
|
+
|
14303
|
+
const ti = await this.engine.addTrack(req);
|
14304
|
+
|
14305
|
+
if (!this.engine.publisher) {
|
14306
|
+
throw new UnexpectedConnectionState('publisher is closed');
|
14307
|
+
}
|
14308
|
+
|
14309
|
+
const transceiverInit = {
|
14310
|
+
direction: 'sendonly'
|
14311
|
+
};
|
14312
|
+
|
14313
|
+
if (encodings) {
|
14314
|
+
transceiverInit.sendEncodings = encodings;
|
14315
|
+
} // addTransceiver for react-native is async. web is synchronous, but await won't effect it.
|
14316
|
+
|
14317
|
+
|
14318
|
+
const transceiver = await this.engine.publisher.pc.addTransceiver(simulcastTrack.mediaStreamTrack, transceiverInit);
|
14319
|
+
this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
|
14320
|
+
track.setSimulcastTrackSender(opts.videoCodec, transceiver.sender);
|
14321
|
+
this.engine.negotiate();
|
14322
|
+
livekitLogger.debug("published ".concat(opts.videoCodec, " for track ").concat(track.sid), {
|
14323
|
+
encodings,
|
14324
|
+
trackInfo: ti
|
14325
|
+
});
|
14326
|
+
}
|
14199
14327
|
|
14200
14328
|
unpublishTrack(track, stopOnUnpublish) {
|
14201
14329
|
var _a, _b; // look through all published tracks to find the right ones
|
@@ -19266,8 +19394,6 @@ class Room extends events.exports.EventEmitter {
|
|
19266
19394
|
constructor(options) {
|
19267
19395
|
var _this;
|
19268
19396
|
|
19269
|
-
var _a, _b;
|
19270
|
-
|
19271
19397
|
super();
|
19272
19398
|
_this = this;
|
19273
19399
|
this.state = ConnectionState.Disconnected;
|
@@ -19692,14 +19818,6 @@ class Room extends events.exports.EventEmitter {
|
|
19692
19818
|
this.participants = new Map();
|
19693
19819
|
this.identityToSid = new Map();
|
19694
19820
|
this.options = options || {};
|
19695
|
-
|
19696
|
-
switch ((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.publishDefaults) === null || _b === void 0 ? void 0 : _b.videoCodec) {
|
19697
|
-
case 'av1':
|
19698
|
-
case 'vp9':
|
19699
|
-
this.options.publishDefaults.simulcast = undefined;
|
19700
|
-
break;
|
19701
|
-
}
|
19702
|
-
|
19703
19821
|
this.options.audioCaptureDefaults = _objectSpread2(_objectSpread2({}, audioDefaults), options === null || options === void 0 ? void 0 : options.audioCaptureDefaults);
|
19704
19822
|
this.options.videoCaptureDefaults = _objectSpread2(_objectSpread2({}, videoDefaults), options === null || options === void 0 ? void 0 : options.videoCaptureDefaults);
|
19705
19823
|
this.options.publishDefaults = _objectSpread2(_objectSpread2({}, publishDefaults), options === null || options === void 0 ? void 0 : options.publishDefaults);
|
@@ -19914,6 +20032,22 @@ class Room extends events.exports.EventEmitter {
|
|
19914
20032
|
}
|
19915
20033
|
|
19916
20034
|
onTrackAdded(mediaTrack, stream, receiver) {
|
20035
|
+
// don't fire onSubscribed when connecting
|
20036
|
+
// WebRTC fires onTrack as soon as setRemoteDescription is called on the offer
|
20037
|
+
// at that time, ICE connectivity has not been established so the track is not
|
20038
|
+
// technically subscribed.
|
20039
|
+
// We'll defer these events until when the room is connected or eventually disconnected.
|
20040
|
+
if (this.state === ConnectionState.Connecting || this.state === ConnectionState.Reconnecting) {
|
20041
|
+
setTimeout(() => {
|
20042
|
+
this.onTrackAdded(mediaTrack, stream, receiver);
|
20043
|
+
}, 10);
|
20044
|
+
return;
|
20045
|
+
}
|
20046
|
+
|
20047
|
+
if (this.state === ConnectionState.Disconnected) {
|
20048
|
+
livekitLogger.warn('skipping incoming track after Room disconnected');
|
20049
|
+
}
|
20050
|
+
|
19917
20051
|
const parts = unpackStreamId(stream.id);
|
19918
20052
|
const participantId = parts[0];
|
19919
20053
|
let trackId = parts[1];
|
@@ -20030,7 +20164,7 @@ class Room extends events.exports.EventEmitter {
|
|
20030
20164
|
|
20031
20165
|
|
20032
20166
|
participant.on(ParticipantEvent.TrackPublished, trackPublication => {
|
20033
|
-
this.
|
20167
|
+
this.emitWhenConnected(RoomEvent.TrackPublished, trackPublication, participant);
|
20034
20168
|
}).on(ParticipantEvent.TrackSubscribed, (track, publication) => {
|
20035
20169
|
// monitor playback status
|
20036
20170
|
if (track.kind === Track.Kind.Audio) {
|
@@ -20040,22 +20174,27 @@ class Room extends events.exports.EventEmitter {
|
|
20040
20174
|
|
20041
20175
|
this.emit(RoomEvent.TrackSubscribed, track, publication, participant);
|
20042
20176
|
}).on(ParticipantEvent.TrackUnpublished, publication => {
|
20043
|
-
this.
|
20177
|
+
this.emitWhenConnected(RoomEvent.TrackUnpublished, publication, participant);
|
20044
20178
|
}).on(ParticipantEvent.TrackUnsubscribed, (track, publication) => {
|
20045
20179
|
this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);
|
20046
20180
|
}).on(ParticipantEvent.TrackSubscriptionFailed, sid => {
|
20047
20181
|
this.emit(RoomEvent.TrackSubscriptionFailed, sid, participant);
|
20048
20182
|
}).on(ParticipantEvent.TrackMuted, pub => {
|
20049
|
-
this.
|
20183
|
+
this.emitWhenConnected(RoomEvent.TrackMuted, pub, participant);
|
20050
20184
|
}).on(ParticipantEvent.TrackUnmuted, pub => {
|
20051
|
-
this.
|
20185
|
+
this.emitWhenConnected(RoomEvent.TrackUnmuted, pub, participant);
|
20052
20186
|
}).on(ParticipantEvent.ParticipantMetadataChanged, metadata => {
|
20053
|
-
this.
|
20187
|
+
this.emitWhenConnected(RoomEvent.ParticipantMetadataChanged, metadata, participant);
|
20054
20188
|
}).on(ParticipantEvent.ConnectionQualityChanged, quality => {
|
20055
|
-
this.
|
20189
|
+
this.emitWhenConnected(RoomEvent.ConnectionQualityChanged, quality, participant);
|
20056
20190
|
}).on(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions => {
|
20057
|
-
this.
|
20058
|
-
});
|
20191
|
+
this.emitWhenConnected(RoomEvent.ParticipantPermissionsChanged, prevPermissions, participant);
|
20192
|
+
}); // update info at the end after callbacks have been set up
|
20193
|
+
|
20194
|
+
if (info) {
|
20195
|
+
participant.updateInfo(info);
|
20196
|
+
}
|
20197
|
+
|
20059
20198
|
return participant;
|
20060
20199
|
}
|
20061
20200
|
|
@@ -20121,12 +20260,24 @@ class Room extends events.exports.EventEmitter {
|
|
20121
20260
|
this.state = state;
|
20122
20261
|
this.emit(RoomEvent.ConnectionStateChanged, this.state);
|
20123
20262
|
return true;
|
20263
|
+
}
|
20264
|
+
|
20265
|
+
emitWhenConnected(event) {
|
20266
|
+
if (this.state === ConnectionState.Connected) {
|
20267
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
20268
|
+
args[_key - 1] = arguments[_key];
|
20269
|
+
}
|
20270
|
+
|
20271
|
+
return this.emit(event, ...args);
|
20272
|
+
}
|
20273
|
+
|
20274
|
+
return false;
|
20124
20275
|
} // /** @internal */
|
20125
20276
|
|
20126
20277
|
|
20127
20278
|
emit(event) {
|
20128
|
-
for (var
|
20129
|
-
args[
|
20279
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
20280
|
+
args[_key2 - 1] = arguments[_key2];
|
20130
20281
|
}
|
20131
20282
|
|
20132
20283
|
livekitLogger.debug('room event', {
|