livekit-client 2.15.3 → 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 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.3";
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) {
@@ -13639,6 +13639,12 @@ class SignalClient {
13639
13639
  if (_this3.signalLatency) {
13640
13640
  yield sleep(_this3.signalLatency);
13641
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
+ }
13642
13648
  if (!_this3.ws || _this3.ws.readyState !== _this3.ws.OPEN) {
13643
13649
  _this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
13644
13650
  return;
@@ -15844,11 +15850,21 @@ class LocalTrackRecorder extends RecorderBase {
15844
15850
  start: controller => {
15845
15851
  streamController = controller;
15846
15852
  dataListener = event => __awaiter(this, void 0, void 0, function* () {
15847
- const arrayBuffer = yield event.data.arrayBuffer();
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
+ }
15848
15864
  if (isClosed()) {
15849
15865
  return;
15850
15866
  }
15851
- controller.enqueue(new Uint8Array(arrayBuffer));
15867
+ controller.enqueue(data);
15852
15868
  });
15853
15869
  this.addEventListener('dataavailable', dataListener);
15854
15870
  },
@@ -16416,8 +16432,13 @@ class LocalTrack extends Track {
16416
16432
  return;
16417
16433
  }
16418
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
+ }
16419
16440
  this.localTrackRecorder = new LocalTrackRecorder(this, {
16420
- mimeType: 'audio/webm;codecs=opus'
16441
+ mimeType
16421
16442
  });
16422
16443
  } else {
16423
16444
  this.log.warn('preconnect buffer already started');
@@ -16442,6 +16463,10 @@ class LocalTrack extends Track {
16442
16463
  var _a;
16443
16464
  return (_a = this.localTrackRecorder) === null || _a === void 0 ? void 0 : _a.byteStream;
16444
16465
  }
16466
+ getPreConnectBufferMimeType() {
16467
+ var _a;
16468
+ return (_a = this.localTrackRecorder) === null || _a === void 0 ? void 0 : _a.mimeType;
16469
+ }
16445
16470
  }
16446
16471
 
16447
16472
  class LocalAudioTrack extends LocalTrack {
@@ -20535,7 +20560,7 @@ class LocalParticipant extends Participant {
20535
20560
  this.reconnectFuture = undefined;
20536
20561
  this.updateTrackSubscriptionPermissions();
20537
20562
  };
20538
- this.handleDisconnected = () => {
20563
+ this.handleClosing = () => {
20539
20564
  var _a, _b, _c, _d, _e, _f;
20540
20565
  if (this.reconnectFuture) {
20541
20566
  this.reconnectFuture.promise.catch(e => this.log.warn(e.message, this.logContext));
@@ -20785,7 +20810,7 @@ class LocalParticipant extends Participant {
20785
20810
  if ((_a = this.signalConnectedFuture) === null || _a === void 0 ? void 0 : _a.isResolved) {
20786
20811
  this.signalConnectedFuture = undefined;
20787
20812
  }
20788
- 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.Disconnected, this.handleDisconnected).on(EngineEvent.SignalRequestResponse, this.handleSignalRequestResponse).on(EngineEvent.DataPacketReceived, this.handleDataPacket);
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);
20789
20814
  }
20790
20815
  /**
20791
20816
  * Sets and updates the metadata of the local participant.
@@ -20969,7 +20994,8 @@ class LocalParticipant extends Participant {
20969
20994
  throw e;
20970
20995
  }
20971
20996
  for (const localTrack of localTracks) {
20972
- if (source === Track.Source.Microphone && isAudioTrack(localTrack) && (publishOptions === null || publishOptions === void 0 ? void 0 : publishOptions.preConnectBuffer)) {
20997
+ const opts = Object.assign(Object.assign({}, this.roomOptions.publishDefaults), options);
20998
+ if (source === Track.Source.Microphone && isAudioTrack(localTrack) && opts.preConnectBuffer) {
20973
20999
  this.log.info('starting preconnect buffer for microphone', Object.assign({}, this.logContext));
20974
21000
  localTrack.startPreConnectBuffer();
20975
21001
  }
@@ -21569,6 +21595,7 @@ class LocalParticipant extends Participant {
21569
21595
  this.emit(ParticipantEvent.LocalTrackPublished, publication);
21570
21596
  if (isLocalAudioTrack(track) && ti.audioFeatures.includes(AudioTrackFeature.TF_PRECONNECT_BUFFER)) {
21571
21597
  const stream = track.getPreConnectBuffer();
21598
+ const mimeType = track.getPreConnectBufferMimeType();
21572
21599
  // TODO: we're registering the listener after negotiation, so there might be a race
21573
21600
  this.on(ParticipantEvent.LocalTrackSubscribed, pub => {
21574
21601
  if (pub.trackSid === ti.sid) {
@@ -21594,7 +21621,7 @@ class LocalParticipant extends Participant {
21594
21621
  this.log.debug('sending preconnect buffer', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
21595
21622
  const writer = yield this.streamBytes({
21596
21623
  name: 'preconnect-buffer',
21597
- mimeType: 'audio/opus',
21624
+ mimeType,
21598
21625
  topic: 'lk.agent.pre-connect-audio-buffer',
21599
21626
  destinationIdentities: [agent.identity],
21600
21627
  attributes: {
@@ -24291,7 +24318,7 @@ class Room extends eventsExports.EventEmitter {
24291
24318
  } else if (kind === 'audiooutput') {
24292
24319
  shouldTriggerImmediateDeviceChange = true;
24293
24320
  if (!supportsSetSinkId() && !_this3.options.webAudioMix || _this3.options.webAudioMix && _this3.audioContext && !('setSinkId' in _this3.audioContext)) {
24294
- throw new Error('cannot switch audio output, setSinkId not supported');
24321
+ throw new Error('cannot switch audio output, the current browser does not support it');
24295
24322
  }
24296
24323
  if (_this3.options.webAudioMix) {
24297
24324
  // setting `default` for web audio output doesn't work, so we need to normalize the id before