livekit-client 2.15.2 → 2.15.4
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/README.md +2 -2
- package/dist/livekit-client.esm.mjs +67 -15
- 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/api/SignalClient.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +1 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/record.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +2 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/utils.d.ts +2 -0
- package/package.json +1 -1
- package/src/api/SignalClient.ts +6 -0
- package/src/room/PCTransport.ts +2 -2
- package/src/room/Room.ts +1 -1
- package/src/room/participant/LocalParticipant.ts +13 -4
- package/src/room/track/LocalTrack.ts +26 -6
- package/src/room/track/record.ts +15 -2
- package/src/room/utils.ts +11 -2
package/README.md
CHANGED
@@ -402,9 +402,9 @@ Also when targeting legacy browsers, older than the ones specified in our browse
|
|
402
402
|
<br/><table>
|
403
403
|
<thead><tr><th colspan="2">LiveKit Ecosystem</th></tr></thead>
|
404
404
|
<tbody>
|
405
|
-
<tr><td>LiveKit SDKs</td><td><b>Browser</b> · <a href="https://github.com/livekit/client-sdk-swift">iOS/macOS/visionOS</a> · <a href="https://github.com/livekit/client-sdk-android">Android</a> · <a href="https://github.com/livekit/client-sdk-flutter">Flutter</a> · <a href="https://github.com/livekit/client-sdk-react-native">React Native</a> · <a href="https://github.com/livekit/rust-sdks">Rust</a> · <a href="https://github.com/livekit/node-sdks">Node.js</a> · <a href="https://github.com/livekit/python-sdks">Python</a> · <a href="https://github.com/livekit/client-sdk-unity">Unity</a> · <a href="https://github.com/livekit/client-sdk-unity-web">Unity (WebGL)</a></td></tr><tr></tr>
|
405
|
+
<tr><td>LiveKit SDKs</td><td><b>Browser</b> · <a href="https://github.com/livekit/client-sdk-swift">iOS/macOS/visionOS</a> · <a href="https://github.com/livekit/client-sdk-android">Android</a> · <a href="https://github.com/livekit/client-sdk-flutter">Flutter</a> · <a href="https://github.com/livekit/client-sdk-react-native">React Native</a> · <a href="https://github.com/livekit/rust-sdks">Rust</a> · <a href="https://github.com/livekit/node-sdks">Node.js</a> · <a href="https://github.com/livekit/python-sdks">Python</a> · <a href="https://github.com/livekit/client-sdk-unity">Unity</a> · <a href="https://github.com/livekit/client-sdk-unity-web">Unity (WebGL)</a> · <a href="https://github.com/livekit/client-sdk-esp32">ESP32</a></td></tr><tr></tr>
|
406
406
|
<tr><td>Server APIs</td><td><a href="https://github.com/livekit/node-sdks">Node.js</a> · <a href="https://github.com/livekit/server-sdk-go">Golang</a> · <a href="https://github.com/livekit/server-sdk-ruby">Ruby</a> · <a href="https://github.com/livekit/server-sdk-kotlin">Java/Kotlin</a> · <a href="https://github.com/livekit/python-sdks">Python</a> · <a href="https://github.com/livekit/rust-sdks">Rust</a> · <a href="https://github.com/agence104/livekit-server-sdk-php">PHP (community)</a> · <a href="https://github.com/pabloFuente/livekit-server-sdk-dotnet">.NET (community)</a></td></tr><tr></tr>
|
407
|
-
<tr><td>UI Components</td><td><a href="https://github.com/livekit/components-js">React</a> · <a href="https://github.com/livekit/components-android">Android Compose</a> · <a href="https://github.com/livekit/components-swift">SwiftUI</a></td></tr><tr></tr>
|
407
|
+
<tr><td>UI Components</td><td><a href="https://github.com/livekit/components-js">React</a> · <a href="https://github.com/livekit/components-android">Android Compose</a> · <a href="https://github.com/livekit/components-swift">SwiftUI</a> · <a href="https://github.com/livekit/components-flutter">Flutter</a></td></tr><tr></tr>
|
408
408
|
<tr><td>Agents Frameworks</td><td><a href="https://github.com/livekit/agents">Python</a> · <a href="https://github.com/livekit/agents-js">Node.js</a> · <a href="https://github.com/livekit/agent-playground">Playground</a></td></tr><tr></tr>
|
409
409
|
<tr><td>Services</td><td><a href="https://github.com/livekit/livekit">LiveKit server</a> · <a href="https://github.com/livekit/egress">Egress</a> · <a href="https://github.com/livekit/ingress">Ingress</a> · <a href="https://github.com/livekit/sip">SIP</a></td></tr><tr></tr>
|
410
410
|
<tr><td>Resources</td><td><a href="https://docs.livekit.io">Docs</a> · <a href="https://github.com/livekit-examples">Example apps</a> · <a href="https://livekit.io/cloud">Cloud</a> · <a href="https://docs.livekit.io/home/self-hosting/deployment">Self-hosting</a> · <a href="https://github.com/livekit/livekit-cli">CLI</a></td></tr>
|
@@ -11364,7 +11364,7 @@ function getOSVersion(ua) {
|
|
11364
11364
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
11365
11365
|
}
|
11366
11366
|
|
11367
|
-
var version$1 = "2.15.
|
11367
|
+
var version$1 = "2.15.4";
|
11368
11368
|
|
11369
11369
|
const version = version$1;
|
11370
11370
|
const protocolVersion = 16;
|
@@ -11956,7 +11956,7 @@ function isSVCCodec(codec) {
|
|
11956
11956
|
return codec === 'av1' || codec === 'vp9';
|
11957
11957
|
}
|
11958
11958
|
function supportsSetSinkId(elm) {
|
11959
|
-
if (!document) {
|
11959
|
+
if (!document || isSafariBased()) {
|
11960
11960
|
return false;
|
11961
11961
|
}
|
11962
11962
|
if (!elm) {
|
@@ -12167,7 +12167,11 @@ function getEmptyAudioStreamTrack() {
|
|
12167
12167
|
return emptyAudioStreamTrack.clone();
|
12168
12168
|
}
|
12169
12169
|
class Future {
|
12170
|
+
get isResolved() {
|
12171
|
+
return this._isResolved;
|
12172
|
+
}
|
12170
12173
|
constructor(futureBase, onFinally) {
|
12174
|
+
this._isResolved = false;
|
12171
12175
|
this.onFinally = onFinally;
|
12172
12176
|
this.promise = new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
12173
12177
|
this.resolve = resolve;
|
@@ -12177,7 +12181,8 @@ class Future {
|
|
12177
12181
|
}
|
12178
12182
|
})).finally(() => {
|
12179
12183
|
var _a;
|
12180
|
-
|
12184
|
+
this._isResolved = true;
|
12185
|
+
(_a = this.onFinally) === null || _a === void 0 ? void 0 : _a.call(this);
|
12181
12186
|
});
|
12182
12187
|
}
|
12183
12188
|
}
|
@@ -13634,6 +13639,12 @@ class SignalClient {
|
|
13634
13639
|
if (_this3.signalLatency) {
|
13635
13640
|
yield sleep(_this3.signalLatency);
|
13636
13641
|
}
|
13642
|
+
if (_this3.isDisconnected) {
|
13643
|
+
// Skip requests if the signal layer is disconnected
|
13644
|
+
// This can happen if an event is sent in the mist of room.connect() initializing
|
13645
|
+
_this3.log.debug("skipping signal request (type: ".concat(message.case, ") - SignalClient disconnected"));
|
13646
|
+
return;
|
13647
|
+
}
|
13637
13648
|
if (!_this3.ws || _this3.ws.readyState !== _this3.ws.OPEN) {
|
13638
13649
|
_this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
|
13639
13650
|
return;
|
@@ -15027,7 +15038,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
15027
15038
|
if (codecPayload === 0) {
|
15028
15039
|
return true;
|
15029
15040
|
}
|
15030
|
-
if (isSVCCodec(trackbr.codec)) {
|
15041
|
+
if (isSVCCodec(trackbr.codec) && !isSafari()) {
|
15031
15042
|
this.ensureVideoDDExtensionForSVC(media, sdpParsed);
|
15032
15043
|
}
|
15033
15044
|
// TODO: av1 slow starting issue already fixed in chrome 124, clean this after some versions
|
@@ -15839,11 +15850,21 @@ class LocalTrackRecorder extends RecorderBase {
|
|
15839
15850
|
start: controller => {
|
15840
15851
|
streamController = controller;
|
15841
15852
|
dataListener = event => __awaiter(this, void 0, void 0, function* () {
|
15842
|
-
|
15853
|
+
let data;
|
15854
|
+
if (event.data.arrayBuffer) {
|
15855
|
+
const arrayBuffer = yield event.data.arrayBuffer();
|
15856
|
+
data = new Uint8Array(arrayBuffer);
|
15857
|
+
// @ts-expect-error react-native passes over Uint8Arrays directly
|
15858
|
+
} else if (event.data.byteArray) {
|
15859
|
+
// @ts-expect-error
|
15860
|
+
data = event.data.byteArray;
|
15861
|
+
} else {
|
15862
|
+
throw new Error('no data available!');
|
15863
|
+
}
|
15843
15864
|
if (isClosed()) {
|
15844
15865
|
return;
|
15845
15866
|
}
|
15846
|
-
controller.enqueue(
|
15867
|
+
controller.enqueue(data);
|
15847
15868
|
});
|
15848
15869
|
this.addEventListener('dataavailable', dataListener);
|
15849
15870
|
},
|
@@ -16333,9 +16354,25 @@ class LocalTrack extends Track {
|
|
16333
16354
|
}
|
16334
16355
|
attachToElement(_this3._mediaStreamTrack, processorElement);
|
16335
16356
|
processorElement.muted = true;
|
16336
|
-
processorElement.play().catch(error =>
|
16337
|
-
error
|
16338
|
-
|
16357
|
+
processorElement.play().catch(error => {
|
16358
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
16359
|
+
// This happens on Safari when the processor is restarted, try again after a delay
|
16360
|
+
_this3.log.warn('failed to play processor element, retrying', Object.assign(Object.assign({}, _this3.logContext), {
|
16361
|
+
error
|
16362
|
+
}));
|
16363
|
+
setTimeout(() => {
|
16364
|
+
processorElement.play().catch(err => {
|
16365
|
+
_this3.log.error('failed to play processor element', Object.assign(Object.assign({}, _this3.logContext), {
|
16366
|
+
err
|
16367
|
+
}));
|
16368
|
+
});
|
16369
|
+
}, 100);
|
16370
|
+
} else {
|
16371
|
+
_this3.log.error('failed to play processor element', Object.assign(Object.assign({}, _this3.logContext), {
|
16372
|
+
error
|
16373
|
+
}));
|
16374
|
+
}
|
16375
|
+
});
|
16339
16376
|
_this3.processor = processor;
|
16340
16377
|
_this3.processorElement = processorElement;
|
16341
16378
|
if (_this3.processor.processedTrack) {
|
@@ -16395,8 +16432,13 @@ class LocalTrack extends Track {
|
|
16395
16432
|
return;
|
16396
16433
|
}
|
16397
16434
|
if (!this.localTrackRecorder) {
|
16435
|
+
let mimeType = 'audio/webm;codecs=opus';
|
16436
|
+
if (!MediaRecorder.isTypeSupported(mimeType)) {
|
16437
|
+
// iOS currently only supports video/mp4 as a mime type - even for audio.
|
16438
|
+
mimeType = 'video/mp4';
|
16439
|
+
}
|
16398
16440
|
this.localTrackRecorder = new LocalTrackRecorder(this, {
|
16399
|
-
mimeType
|
16441
|
+
mimeType
|
16400
16442
|
});
|
16401
16443
|
} else {
|
16402
16444
|
this.log.warn('preconnect buffer already started');
|
@@ -16421,6 +16463,10 @@ class LocalTrack extends Track {
|
|
16421
16463
|
var _a;
|
16422
16464
|
return (_a = this.localTrackRecorder) === null || _a === void 0 ? void 0 : _a.byteStream;
|
16423
16465
|
}
|
16466
|
+
getPreConnectBufferMimeType() {
|
16467
|
+
var _a;
|
16468
|
+
return (_a = this.localTrackRecorder) === null || _a === void 0 ? void 0 : _a.mimeType;
|
16469
|
+
}
|
16424
16470
|
}
|
16425
16471
|
|
16426
16472
|
class LocalAudioTrack extends LocalTrack {
|
@@ -20514,7 +20560,7 @@ class LocalParticipant extends Participant {
|
|
20514
20560
|
this.reconnectFuture = undefined;
|
20515
20561
|
this.updateTrackSubscriptionPermissions();
|
20516
20562
|
};
|
20517
|
-
this.
|
20563
|
+
this.handleClosing = () => {
|
20518
20564
|
var _a, _b, _c, _d, _e, _f;
|
20519
20565
|
if (this.reconnectFuture) {
|
20520
20566
|
this.reconnectFuture.promise.catch(e => this.log.warn(e.message, this.logContext));
|
@@ -20748,6 +20794,7 @@ class LocalParticipant extends Participant {
|
|
20748
20794
|
* @internal
|
20749
20795
|
*/
|
20750
20796
|
setupEngine(engine) {
|
20797
|
+
var _a;
|
20751
20798
|
this.engine = engine;
|
20752
20799
|
this.engine.on(EngineEvent.RemoteMute, (trackSid, muted) => {
|
20753
20800
|
const pub = this.trackPublications.get(trackSid);
|
@@ -20760,7 +20807,10 @@ class LocalParticipant extends Participant {
|
|
20760
20807
|
pub.unmute();
|
20761
20808
|
}
|
20762
20809
|
});
|
20763
|
-
|
20810
|
+
if ((_a = this.signalConnectedFuture) === null || _a === void 0 ? void 0 : _a.isResolved) {
|
20811
|
+
this.signalConnectedFuture = undefined;
|
20812
|
+
}
|
20813
|
+
this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalConnected, this.handleSignalConnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.LocalTrackUnpublished, this.handleLocalTrackUnpublished).on(EngineEvent.SubscribedQualityUpdate, this.handleSubscribedQualityUpdate).on(EngineEvent.Closing, this.handleClosing).on(EngineEvent.SignalRequestResponse, this.handleSignalRequestResponse).on(EngineEvent.DataPacketReceived, this.handleDataPacket);
|
20764
20814
|
}
|
20765
20815
|
/**
|
20766
20816
|
* Sets and updates the metadata of the local participant.
|
@@ -20944,7 +20994,8 @@ class LocalParticipant extends Participant {
|
|
20944
20994
|
throw e;
|
20945
20995
|
}
|
20946
20996
|
for (const localTrack of localTracks) {
|
20947
|
-
|
20997
|
+
const opts = Object.assign(Object.assign({}, this.roomOptions.publishDefaults), options);
|
20998
|
+
if (source === Track.Source.Microphone && isAudioTrack(localTrack) && opts.preConnectBuffer) {
|
20948
20999
|
this.log.info('starting preconnect buffer for microphone', Object.assign({}, this.logContext));
|
20949
21000
|
localTrack.startPreConnectBuffer();
|
20950
21001
|
}
|
@@ -21544,6 +21595,7 @@ class LocalParticipant extends Participant {
|
|
21544
21595
|
this.emit(ParticipantEvent.LocalTrackPublished, publication);
|
21545
21596
|
if (isLocalAudioTrack(track) && ti.audioFeatures.includes(AudioTrackFeature.TF_PRECONNECT_BUFFER)) {
|
21546
21597
|
const stream = track.getPreConnectBuffer();
|
21598
|
+
const mimeType = track.getPreConnectBufferMimeType();
|
21547
21599
|
// TODO: we're registering the listener after negotiation, so there might be a race
|
21548
21600
|
this.on(ParticipantEvent.LocalTrackSubscribed, pub => {
|
21549
21601
|
if (pub.trackSid === ti.sid) {
|
@@ -21569,7 +21621,7 @@ class LocalParticipant extends Participant {
|
|
21569
21621
|
this.log.debug('sending preconnect buffer', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
|
21570
21622
|
const writer = yield this.streamBytes({
|
21571
21623
|
name: 'preconnect-buffer',
|
21572
|
-
mimeType
|
21624
|
+
mimeType,
|
21573
21625
|
topic: 'lk.agent.pre-connect-audio-buffer',
|
21574
21626
|
destinationIdentities: [agent.identity],
|
21575
21627
|
attributes: {
|
@@ -24266,7 +24318,7 @@ class Room extends eventsExports.EventEmitter {
|
|
24266
24318
|
} else if (kind === 'audiooutput') {
|
24267
24319
|
shouldTriggerImmediateDeviceChange = true;
|
24268
24320
|
if (!supportsSetSinkId() && !_this3.options.webAudioMix || _this3.options.webAudioMix && _this3.audioContext && !('setSinkId' in _this3.audioContext)) {
|
24269
|
-
throw new Error('cannot switch audio output,
|
24321
|
+
throw new Error('cannot switch audio output, the current browser does not support it');
|
24270
24322
|
}
|
24271
24323
|
if (_this3.options.webAudioMix) {
|
24272
24324
|
// setting `default` for web audio output doesn't work, so we need to normalize the id before
|