livekit-client 1.12.0 → 1.12.1

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.
Files changed (31) hide show
  1. package/README.md +14 -0
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +59 -39
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +44 -17
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/e2ee/worker/FrameCryptor.d.ts +0 -1
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +8 -0
  13. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  14. package/dist/src/room/Room.d.ts.map +1 -1
  15. package/dist/src/room/participant/RemoteParticipant.d.ts +6 -4
  16. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  17. package/dist/src/room/track/create.d.ts.map +1 -1
  18. package/dist/src/utils/browserParser.d.ts +2 -0
  19. package/dist/src/utils/browserParser.d.ts.map +1 -1
  20. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +0 -1
  21. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +8 -0
  22. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +6 -4
  23. package/dist/ts4.2/src/utils/browserParser.d.ts +2 -0
  24. package/package.json +1 -1
  25. package/src/e2ee/worker/FrameCryptor.ts +12 -14
  26. package/src/e2ee/worker/ParticipantKeyHandler.ts +15 -0
  27. package/src/e2ee/worker/e2ee.worker.ts +12 -6
  28. package/src/room/Room.ts +17 -7
  29. package/src/room/participant/RemoteParticipant.ts +19 -15
  30. package/src/room/track/create.ts +9 -0
  31. package/src/utils/browserParser.ts +5 -0
@@ -14165,7 +14165,8 @@ const browsersList = [{
14165
14165
  describe(ua) {
14166
14166
  const browser = {
14167
14167
  name: 'Firefox',
14168
- version: getMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, ua)
14168
+ version: getMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, ua),
14169
+ os: ua.toLowerCase().includes('fxios') ? 'iOS' : undefined
14169
14170
  };
14170
14171
  return browser;
14171
14172
  }
@@ -14174,7 +14175,8 @@ const browsersList = [{
14174
14175
  describe(ua) {
14175
14176
  const browser = {
14176
14177
  name: 'Chrome',
14177
- version: getMatch(/(?:chrome|chromium|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua)
14178
+ version: getMatch(/(?:chrome|chromium|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua),
14179
+ os: ua.toLowerCase().includes('crios') ? 'iOS' : undefined
14178
14180
  };
14179
14181
  return browser;
14180
14182
  }
@@ -14184,7 +14186,8 @@ const browsersList = [{
14184
14186
  describe(ua) {
14185
14187
  const browser = {
14186
14188
  name: 'Safari',
14187
- version: getMatch(commonVersionIdentifier, ua)
14189
+ version: getMatch(commonVersionIdentifier, ua),
14190
+ os: ua.includes('Mobile/') ? 'iOS' : 'macOS'
14188
14191
  };
14189
14192
  return browser;
14190
14193
  }
@@ -14195,7 +14198,7 @@ function getMatch(exp, ua) {
14195
14198
  return match && match.length >= id && match[id] || '';
14196
14199
  }
14197
14200
 
14198
- var version$1 = "1.12.0";
14201
+ var version$1 = "1.12.1";
14199
14202
 
14200
14203
  const version = version$1;
14201
14204
  const protocolVersion = 9;
@@ -21510,6 +21513,7 @@ class RemoteParticipant extends Participant {
21510
21513
  this.tracks = new Map();
21511
21514
  this.audioTracks = new Map();
21512
21515
  this.videoTracks = new Map();
21516
+ this.volumeMap = new Map();
21513
21517
  }
21514
21518
  addTrackPublication(publication) {
21515
21519
  super.addTrackPublication(publication);
@@ -21553,12 +21557,15 @@ class RemoteParticipant extends Participant {
21553
21557
  }
21554
21558
  }
21555
21559
  /**
21556
- * sets the volume on the participant's microphone track
21560
+ * sets the volume on the participant's audio track
21561
+ * by default, this affects the microphone publication
21562
+ * a different source can be passed in as a second argument
21557
21563
  * if no track exists the volume will be applied when the microphone track is added
21558
21564
  */
21559
21565
  setVolume(volume) {
21560
- this.volume = volume;
21561
- const audioPublication = this.getTrack(Track.Source.Microphone);
21566
+ let source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Track.Source.Microphone;
21567
+ this.volumeMap.set(source, volume);
21568
+ const audioPublication = this.getTrack(source);
21562
21569
  if (audioPublication && audioPublication.track) {
21563
21570
  audioPublication.track.setVolume(volume);
21564
21571
  }
@@ -21567,11 +21574,12 @@ class RemoteParticipant extends Participant {
21567
21574
  * gets the volume on the participant's microphone track
21568
21575
  */
21569
21576
  getVolume() {
21570
- const audioPublication = this.getTrack(Track.Source.Microphone);
21577
+ let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Track.Source.Microphone;
21578
+ const audioPublication = this.getTrack(source);
21571
21579
  if (audioPublication && audioPublication.track) {
21572
21580
  return audioPublication.track.getVolume();
21573
21581
  }
21574
- return this.volume;
21582
+ return this.volumeMap.get(source);
21575
21583
  }
21576
21584
  /** @internal */
21577
21585
  addSubscribedMediaTrack(mediaTrack, sid, mediaStream, receiver, adaptiveStreamSettings, triesLeft) {
@@ -21629,9 +21637,9 @@ class RemoteParticipant extends Participant {
21629
21637
  track.setMediaStream(mediaStream);
21630
21638
  track.start();
21631
21639
  publication.setTrack(track);
21632
- // set participant volume on new microphone tracks
21633
- if (this.volume !== undefined && track instanceof RemoteAudioTrack && track.source === Track.Source.Microphone) {
21634
- track.setVolume(this.volume);
21640
+ // set participant volumes on new audio tracks
21641
+ if (this.volumeMap.has(publication.source) && track instanceof RemoteAudioTrack) {
21642
+ track.setVolume(this.volumeMap.get(publication.source));
21635
21643
  }
21636
21644
  return publication;
21637
21645
  }
@@ -23609,9 +23617,10 @@ class Room extends EventEmitter {
23609
23617
  return __awaiter(this, void 0, void 0, function* () {
23610
23618
  yield this.acquireAudioContext();
23611
23619
  const elements = [];
23612
- if (isSafari()) {
23620
+ const browser = getBrowser();
23621
+ if (browser && browser.os === 'iOS') {
23613
23622
  /**
23614
- * iOS Safari blocks audio element playback if
23623
+ * iOS blocks audio element playback if
23615
23624
  * - user is not publishing audio themselves and
23616
23625
  * - no other audio source is playing
23617
23626
  *
@@ -23622,6 +23631,7 @@ class Room extends EventEmitter {
23622
23631
  let dummyAudioEl = document.getElementById(audioId);
23623
23632
  if (!dummyAudioEl) {
23624
23633
  dummyAudioEl = document.createElement('audio');
23634
+ dummyAudioEl.id = audioId;
23625
23635
  dummyAudioEl.autoplay = true;
23626
23636
  dummyAudioEl.hidden = true;
23627
23637
  const track = getEmptyAudioStreamTrack();
@@ -23719,7 +23729,7 @@ class Room extends EventEmitter {
23719
23729
  throw e;
23720
23730
  }
23721
23731
  } else if (kind === 'audiooutput') {
23722
- if (!supportsSetSinkId() && !this.options.expWebAudioMix || this.audioContext && !('setSinkId' in this.audioContext)) {
23732
+ if (!supportsSetSinkId() && !this.options.expWebAudioMix || this.options.expWebAudioMix && this.audioContext && !('setSinkId' in this.audioContext)) {
23723
23733
  throw new Error('cannot switch audio output, setSinkId not supported');
23724
23734
  }
23725
23735
  (_a = (_c = this.options).audioOutput) !== null && _a !== void 0 ? _a : _c.audioOutput = {};
@@ -23867,12 +23877,20 @@ class Room extends EventEmitter {
23867
23877
  if (typeof this.options.expWebAudioMix !== 'boolean' && this.options.expWebAudioMix.audioContext) {
23868
23878
  // override audio context with custom audio context if supplied by user
23869
23879
  this.audioContext = this.options.expWebAudioMix.audioContext;
23870
- yield this.audioContext.resume();
23871
- } else {
23880
+ } else if (!this.audioContext || this.audioContext.state === 'closed') {
23872
23881
  // by using an AudioContext, it reduces lag on audio elements
23873
23882
  // https://stackoverflow.com/questions/9811429/html5-audio-tag-on-safari-has-a-delay/54119854#54119854
23874
23883
  this.audioContext = (_a = getNewAudioContext()) !== null && _a !== void 0 ? _a : undefined;
23875
23884
  }
23885
+ if (this.audioContext && this.audioContext.state === 'suspended') {
23886
+ // for iOS a newly created AudioContext is always in `suspended` state.
23887
+ // we try our best to resume the context here, if that doesn't work, we just continue with regular processing
23888
+ try {
23889
+ yield this.audioContext.resume();
23890
+ } catch (e) {
23891
+ livekitLogger.warn(e);
23892
+ }
23893
+ }
23876
23894
  if (this.options.expWebAudioMix) {
23877
23895
  this.participants.forEach(participant => participant.setAudioContext(this.audioContext));
23878
23896
  }
@@ -24323,6 +24341,15 @@ function createLocalTracks(options) {
24323
24341
  if (typeof conOrBool !== 'boolean') {
24324
24342
  trackConstraints = conOrBool;
24325
24343
  }
24344
+ // update the constraints with the device id the user gave permissions to in the permission prompt
24345
+ // otherwise each track restart (e.g. mute - unmute) will try to initialize the device again -> causing additional permission prompts
24346
+ if (trackConstraints) {
24347
+ trackConstraints.deviceId = mediaStreamTrack.getSettings().deviceId;
24348
+ } else {
24349
+ trackConstraints = {
24350
+ deviceId: mediaStreamTrack.getSettings().deviceId
24351
+ };
24352
+ }
24326
24353
  const track = mediaTrackToLocalTrack(mediaStreamTrack, trackConstraints);
24327
24354
  if (track.kind === Track.Kind.Video) {
24328
24355
  track.source = Track.Source.Camera;