livekit-client 1.1.3 → 1.1.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.
@@ -10070,7 +10070,7 @@ function computeBitrate(currentStats, prevStats) {
10070
10070
  return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
10071
10071
  }
10072
10072
 
10073
- var version$1 = "1.1.3";
10073
+ var version$1 = "1.1.4";
10074
10074
 
10075
10075
  const version = version$1;
10076
10076
  const protocolVersion = 8;
@@ -11060,6 +11060,7 @@ function detachTrack(track, element) {
11060
11060
 
11061
11061
  class LocalTrack extends Track {
11062
11062
  constructor(mediaTrack, kind, constraints) {
11063
+ let userProvidedTrack = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
11063
11064
  super(mediaTrack, kind);
11064
11065
  this._isUpstreamPaused = false;
11065
11066
 
@@ -11076,6 +11077,7 @@ class LocalTrack extends Track {
11076
11077
  this.constraints = constraints !== null && constraints !== void 0 ? constraints : mediaTrack.getConstraints();
11077
11078
  this.reacquireTrack = false;
11078
11079
  this.wasMuted = false;
11080
+ this.providedByUser = userProvidedTrack;
11079
11081
  }
11080
11082
 
11081
11083
  get id() {
@@ -11105,6 +11107,10 @@ class LocalTrack extends Track {
11105
11107
  get isUpstreamPaused() {
11106
11108
  return this._isUpstreamPaused;
11107
11109
  }
11110
+
11111
+ get isUserProvided() {
11112
+ return this.providedByUser;
11113
+ }
11108
11114
  /**
11109
11115
  * @returns DeviceID of the device that is currently being used for this track
11110
11116
  */
@@ -11136,6 +11142,8 @@ class LocalTrack extends Track {
11136
11142
  }
11137
11143
 
11138
11144
  async replaceTrack(track) {
11145
+ let userProvidedTrack = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
11146
+
11139
11147
  if (!this.sender) {
11140
11148
  throw new TrackInvalidError('unable to replace an unpublished track');
11141
11149
  } // detach
@@ -11164,6 +11172,7 @@ class LocalTrack extends Track {
11164
11172
  attachToElement(track, el);
11165
11173
  });
11166
11174
  this.mediaStream = new MediaStream([track]);
11175
+ this.providedByUser = userProvidedTrack;
11167
11176
  return this;
11168
11177
  }
11169
11178
 
@@ -11235,7 +11244,7 @@ class LocalTrack extends Track {
11235
11244
  if (!isMobile()) return;
11236
11245
  livekitLogger.debug("visibility changed, is in Background: ".concat(this.isInBackground));
11237
11246
 
11238
- if (!this.isInBackground && this.needsReAcquisition) {
11247
+ if (!this.isInBackground && this.needsReAcquisition && !this.isUserProvided) {
11239
11248
  livekitLogger.debug("track needs to be reaquired, restarting ".concat(this.source));
11240
11249
  await this.restart();
11241
11250
  this.reacquireTrack = false; // Restore muted state if had to be restarted
@@ -11386,7 +11395,8 @@ function getNewAudioContext() {
11386
11395
 
11387
11396
  class LocalAudioTrack extends LocalTrack {
11388
11397
  constructor(mediaTrack, constraints) {
11389
- super(mediaTrack, Track.Kind.Audio, constraints);
11398
+ let userProvidedTrack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
11399
+ super(mediaTrack, Track.Kind.Audio, constraints, userProvidedTrack);
11390
11400
  /** @internal */
11391
11401
 
11392
11402
  this.stopOnMute = false;
@@ -11446,7 +11456,7 @@ class LocalAudioTrack extends LocalTrack {
11446
11456
  }
11447
11457
 
11448
11458
  async unmute() {
11449
- if (this.source === Track.Source.Microphone && this.stopOnMute) {
11459
+ if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
11450
11460
  livekitLogger.debug('reacquiring mic track');
11451
11461
  await this.restartTrack();
11452
11462
  }
@@ -11530,7 +11540,8 @@ class LocalAudioTrack extends LocalTrack {
11530
11540
  const refreshSubscribedCodecAfterNewCodec = 5000;
11531
11541
  class LocalVideoTrack extends LocalTrack {
11532
11542
  constructor(mediaTrack, constraints) {
11533
- super(mediaTrack, Track.Kind.Video, constraints);
11543
+ let userProvidedTrack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
11544
+ super(mediaTrack, Track.Kind.Video, constraints, userProvidedTrack);
11534
11545
  this.simulcastCodecs = new Map();
11535
11546
 
11536
11547
  this.monitorSender = async () => {
@@ -11627,7 +11638,7 @@ class LocalVideoTrack extends LocalTrack {
11627
11638
  }
11628
11639
 
11629
11640
  async unmute() {
11630
- if (this.source === Track.Source.Camera) {
11641
+ if (this.source === Track.Source.Camera && !this.isUserProvided) {
11631
11642
  livekitLogger.debug('reacquiring camera track');
11632
11643
  await this.restartTrack();
11633
11644
  }
@@ -12955,10 +12966,10 @@ function trackPermissionToProto(perms) {
12955
12966
  function mediaTrackToLocalTrack(mediaStreamTrack, constraints) {
12956
12967
  switch (mediaStreamTrack.kind) {
12957
12968
  case 'audio':
12958
- return new LocalAudioTrack(mediaStreamTrack, constraints);
12969
+ return new LocalAudioTrack(mediaStreamTrack, constraints, false);
12959
12970
 
12960
12971
  case 'video':
12961
- return new LocalVideoTrack(mediaStreamTrack, constraints);
12972
+ return new LocalVideoTrack(mediaStreamTrack, constraints, false);
12962
12973
 
12963
12974
  default:
12964
12975
  throw new TrackInvalidError("unsupported track type: ".concat(mediaStreamTrack.kind));
@@ -14065,12 +14076,12 @@ class LocalParticipant extends Participant {
14065
14076
  throw new TrackInvalidError('no video track found');
14066
14077
  }
14067
14078
 
14068
- const screenVideo = new LocalVideoTrack(tracks[0]);
14079
+ const screenVideo = new LocalVideoTrack(tracks[0], undefined, false);
14069
14080
  screenVideo.source = Track.Source.ScreenShare;
14070
14081
  const localTracks = [screenVideo];
14071
14082
 
14072
14083
  if (stream.getAudioTracks().length > 0) {
14073
- const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0]);
14084
+ const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false);
14074
14085
  screenAudio.source = Track.Source.ScreenShareAudio;
14075
14086
  localTracks.push(screenAudio);
14076
14087
  }
@@ -14093,11 +14104,11 @@ class LocalParticipant extends Participant {
14093
14104
  if (track instanceof MediaStreamTrack) {
14094
14105
  switch (track.kind) {
14095
14106
  case 'audio':
14096
- track = new LocalAudioTrack(track);
14107
+ track = new LocalAudioTrack(track, undefined, true);
14097
14108
  break;
14098
14109
 
14099
14110
  case 'video':
14100
- track = new LocalVideoTrack(track);
14111
+ track = new LocalVideoTrack(track, undefined, true);
14101
14112
  break;
14102
14113
 
14103
14114
  default:
@@ -19489,7 +19500,7 @@ class Room extends events.exports.EventEmitter {
19489
19500
  this.metadata = joinResponse.room.metadata;
19490
19501
  this.emit(RoomEvent.SignalConnected);
19491
19502
  } catch (err) {
19492
- this.engine.close();
19503
+ this.recreateEngine();
19493
19504
  this.setAndEmitConnectionState(ConnectionState.Disconnected);
19494
19505
  throw err;
19495
19506
  } // don't return until ICE connected
@@ -19500,7 +19511,7 @@ class Room extends events.exports.EventEmitter {
19500
19511
 
19501
19512
  const connectTimeout = setTimeout(() => {
19502
19513
  // timeout
19503
- this.engine.close();
19514
+ this.recreateEngine();
19504
19515
  this.setAndEmitConnectionState(ConnectionState.Disconnected);
19505
19516
  reject(new ConnectionError('could not connect after timeout'));
19506
19517
  }, maxICEConnectTimeout);
@@ -19508,7 +19519,7 @@ class Room extends events.exports.EventEmitter {
19508
19519
  const abortHandler = () => {
19509
19520
  livekitLogger.warn('closing engine');
19510
19521
  clearTimeout(connectTimeout);
19511
- this.engine.close();
19522
+ this.recreateEngine();
19512
19523
  this.setAndEmitConnectionState(ConnectionState.Disconnected);
19513
19524
  reject(new ConnectionError('room connection has been cancelled'));
19514
19525
  };
@@ -19573,14 +19584,14 @@ class Room extends events.exports.EventEmitter {
19573
19584
  };
19574
19585
 
19575
19586
  this.handleRestarting = () => {
19576
- if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
19577
- this.emit(RoomEvent.Reconnecting);
19578
- } // also unwind existing participants & existing subscriptions
19579
-
19580
-
19587
+ // also unwind existing participants & existing subscriptions
19581
19588
  for (const p of this.participants.values()) {
19582
19589
  this.handleParticipantDisconnected(p.sid, p);
19583
19590
  }
19591
+
19592
+ if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
19593
+ this.emit(RoomEvent.Reconnecting);
19594
+ }
19584
19595
  };
19585
19596
 
19586
19597
  this.handleRestarted = async joinResponse => {
@@ -19609,7 +19620,7 @@ class Room extends events.exports.EventEmitter {
19609
19620
  this.localParticipant.unpublishTrack(track, false);
19610
19621
 
19611
19622
  if (!track.isMuted) {
19612
- if (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) {
19623
+ if ((track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) && !track.isUserProvided) {
19613
19624
  // we need to restart the track before publishing, often a full reconnect
19614
19625
  // is necessary because computer had gone to sleep.
19615
19626
  livekitLogger.debug('restarting existing track', {
@@ -19648,7 +19659,7 @@ class Room extends events.exports.EventEmitter {
19648
19659
  this.handleParticipantDisconnected(info.sid, remoteParticipant);
19649
19660
  } else if (isNewParticipant) {
19650
19661
  // fire connected event
19651
- this.emit(RoomEvent.ParticipantConnected, remoteParticipant);
19662
+ this.emitWhenConnected(RoomEvent.ParticipantConnected, remoteParticipant);
19652
19663
  } else {
19653
19664
  // just update, no events
19654
19665
  remoteParticipant.updateInfo(info);
@@ -19690,7 +19701,7 @@ class Room extends events.exports.EventEmitter {
19690
19701
  }
19691
19702
  });
19692
19703
  this.activeSpeakers = activeSpeakers;
19693
- this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
19704
+ this.emitWhenConnected(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
19694
19705
  }; // process list of changed speakers
19695
19706
 
19696
19707
 
@@ -19722,7 +19733,7 @@ class Room extends events.exports.EventEmitter {
19722
19733
  const activeSpeakers = Array.from(lastSpeakers.values());
19723
19734
  activeSpeakers.sort((a, b) => b.audioLevel - a.audioLevel);
19724
19735
  this.activeSpeakers = activeSpeakers;
19725
- this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
19736
+ this.emitWhenConnected(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
19726
19737
  };
19727
19738
 
19728
19739
  this.handleStreamStateUpdate = streamStateUpdate => {
@@ -19741,7 +19752,7 @@ class Room extends events.exports.EventEmitter {
19741
19752
 
19742
19753
  pub.track.streamState = Track.streamStateFromProto(streamState.state);
19743
19754
  participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
19744
- this.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
19755
+ this.emitWhenConnected(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
19745
19756
  });
19746
19757
  };
19747
19758
 
@@ -19760,7 +19771,7 @@ class Room extends events.exports.EventEmitter {
19760
19771
 
19761
19772
  pub._allowed = update.allowed;
19762
19773
  participant.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus);
19763
- this.emit(ParticipantEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus, participant);
19774
+ this.emitWhenConnected(ParticipantEvent.TrackSubscriptionPermissionChanged, pub, pub.subscriptionStatus, participant);
19764
19775
  };
19765
19776
 
19766
19777
  this.handleDataPacket = (userPacket, kind) => {
@@ -19797,7 +19808,7 @@ class Room extends events.exports.EventEmitter {
19797
19808
 
19798
19809
  this.handleRoomUpdate = r => {
19799
19810
  this.metadata = r.metadata;
19800
- this.emit(RoomEvent.RoomMetadataChanged, r.metadata);
19811
+ this.emitWhenConnected(RoomEvent.RoomMetadataChanged, r.metadata);
19801
19812
  };
19802
19813
 
19803
19814
  this.handleConnectionQualityUpdate = update => {
@@ -19855,6 +19866,10 @@ class Room extends events.exports.EventEmitter {
19855
19866
  this.sendSyncState();
19856
19867
  }
19857
19868
  }).on(EngineEvent.Restarting, this.handleRestarting).on(EngineEvent.Restarted, this.handleRestarted);
19869
+
19870
+ if (this.localParticipant) {
19871
+ this.localParticipant.engine = this.engine;
19872
+ }
19858
19873
  }
19859
19874
  /**
19860
19875
  * getLocalDevices abstracts navigator.mediaDevices.enumerateDevices.
@@ -20031,6 +20046,17 @@ class Room extends events.exports.EventEmitter {
20031
20046
  }
20032
20047
  }
20033
20048
 
20049
+ recreateEngine() {
20050
+ this.engine.close();
20051
+ /* @ts-ignore */
20052
+
20053
+ this.engine = undefined; // clear out existing remote participants, since they may have attached
20054
+ // the old engine
20055
+
20056
+ this.participants.clear();
20057
+ this.createEngine();
20058
+ }
20059
+
20034
20060
  onTrackAdded(mediaTrack, stream, receiver) {
20035
20061
  // don't fire onSubscribed when connecting
20036
20062
  // WebRTC fires onTrack as soon as setRemoteDescription is called on the offer
@@ -20040,7 +20066,7 @@ class Room extends events.exports.EventEmitter {
20040
20066
  if (this.state === ConnectionState.Connecting || this.state === ConnectionState.Reconnecting) {
20041
20067
  setTimeout(() => {
20042
20068
  this.onTrackAdded(mediaTrack, stream, receiver);
20043
- }, 10);
20069
+ }, 50);
20044
20070
  return;
20045
20071
  }
20046
20072
 
@@ -20117,7 +20143,7 @@ class Room extends events.exports.EventEmitter {
20117
20143
  participant.tracks.forEach(publication => {
20118
20144
  participant.unpublishTrack(publication.trackSid, true);
20119
20145
  });
20120
- this.emit(RoomEvent.ParticipantDisconnected, participant);
20146
+ this.emitWhenConnected(RoomEvent.ParticipantDisconnected, participant);
20121
20147
  }
20122
20148
 
20123
20149
  acquireAudioContext() {
@@ -20386,12 +20412,12 @@ async function createLocalScreenTracks(options) {
20386
20412
  throw new TrackInvalidError('no video track found');
20387
20413
  }
20388
20414
 
20389
- const screenVideo = new LocalVideoTrack(tracks[0]);
20415
+ const screenVideo = new LocalVideoTrack(tracks[0], undefined, false);
20390
20416
  screenVideo.source = Track.Source.ScreenShare;
20391
20417
  const localTracks = [screenVideo];
20392
20418
 
20393
20419
  if (stream.getAudioTracks().length > 0) {
20394
- const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0]);
20420
+ const screenAudio = new LocalAudioTrack(stream.getAudioTracks()[0], undefined, false);
20395
20421
  screenAudio.source = Track.Source.ScreenShareAudio;
20396
20422
  localTracks.push(screenAudio);
20397
20423
  }