livekit-client 1.12.0 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
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;