livekit-client 1.2.7 → 1.2.10

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 (36) hide show
  1. package/dist/livekit-client.esm.mjs +1082 -459
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/api/SignalClient.d.ts +11 -1
  6. package/dist/src/api/SignalClient.d.ts.map +1 -1
  7. package/dist/src/proto/google/protobuf/timestamp.d.ts +8 -2
  8. package/dist/src/proto/google/protobuf/timestamp.d.ts.map +1 -1
  9. package/dist/src/proto/livekit_models.d.ts +106 -47
  10. package/dist/src/proto/livekit_models.d.ts.map +1 -1
  11. package/dist/src/proto/livekit_rtc.d.ts +3012 -2132
  12. package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
  13. package/dist/src/room/Room.d.ts.map +1 -1
  14. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  15. package/dist/src/room/participant/Participant.d.ts +1 -1
  16. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  17. package/dist/src/room/participant/RemoteParticipant.d.ts +1 -1
  18. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  19. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  20. package/dist/src/room/track/RemoteAudioTrack.d.ts +1 -1
  21. package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
  22. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  23. package/package.json +3 -3
  24. package/src/api/SignalClient.ts +148 -41
  25. package/src/proto/google/protobuf/timestamp.ts +3 -1
  26. package/src/proto/livekit_models.ts +132 -36
  27. package/src/proto/livekit_rtc.ts +822 -459
  28. package/src/room/RTCEngine.ts +5 -5
  29. package/src/room/Room.ts +22 -6
  30. package/src/room/participant/LocalParticipant.ts +7 -4
  31. package/src/room/participant/Participant.ts +2 -1
  32. package/src/room/participant/RemoteParticipant.ts +3 -3
  33. package/src/room/participant/publishUtils.test.ts +12 -0
  34. package/src/room/participant/publishUtils.ts +21 -19
  35. package/src/room/track/RemoteAudioTrack.ts +15 -5
  36. package/src/room/track/RemoteTrackPublication.ts +1 -0
@@ -180,7 +180,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
180
180
  },
181
181
  reject: () => {
182
182
  clearTimeout(publicationTimeout);
183
- reject('Cancelled publication by calling unpublish');
183
+ reject(new Error('Cancelled publication by calling unpublish'));
184
184
  },
185
185
  };
186
186
  this.client.sendAddTrack(req);
@@ -452,11 +452,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
452
452
  return;
453
453
  }
454
454
  const dp = DataPacket.decode(new Uint8Array(buffer));
455
- if (dp.speaker) {
455
+ if (dp.value?.$case === 'speaker') {
456
456
  // dispatch speaker updates
457
- this.emit(EngineEvent.ActiveSpeakersUpdate, dp.speaker.speakers);
458
- } else if (dp.user) {
459
- this.emit(EngineEvent.DataPacketReceived, dp.user, dp.kind);
457
+ this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.speaker.speakers);
458
+ } else if (dp.value?.$case === 'user') {
459
+ this.emit(EngineEvent.DataPacketReceived, dp.value.user, dp.kind);
460
460
  }
461
461
  };
462
462
 
package/src/room/Room.ts CHANGED
@@ -211,7 +211,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
211
211
 
212
212
  if (this.connectFuture) {
213
213
  return this.connectFuture.promise;
214
- } else if (this.reconnectFuture) {
214
+ }
215
+ if (this.reconnectFuture) {
215
216
  this.connectFuture = this.reconnectFuture;
216
217
  return this.connectFuture.promise;
217
218
  }
@@ -398,27 +399,42 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
398
399
  break;
399
400
  case 'speaker':
400
401
  req = SimulateScenario.fromPartial({
401
- speakerUpdate: 3,
402
+ scenario: {
403
+ $case: 'speakerUpdate',
404
+ speakerUpdate: 3,
405
+ },
402
406
  });
403
407
  break;
404
408
  case 'node-failure':
405
409
  req = SimulateScenario.fromPartial({
406
- nodeFailure: true,
410
+ scenario: {
411
+ $case: 'nodeFailure',
412
+ nodeFailure: true,
413
+ },
407
414
  });
408
415
  break;
409
416
  case 'server-leave':
410
417
  req = SimulateScenario.fromPartial({
411
- serverLeave: true,
418
+ scenario: {
419
+ $case: 'serverLeave',
420
+ serverLeave: true,
421
+ },
412
422
  });
413
423
  break;
414
424
  case 'migration':
415
425
  req = SimulateScenario.fromPartial({
416
- migration: true,
426
+ scenario: {
427
+ $case: 'migration',
428
+ migration: true,
429
+ },
417
430
  });
418
431
  break;
419
432
  case 'switch-candidate':
420
433
  req = SimulateScenario.fromPartial({
421
- switchCandidateProtocol: 1,
434
+ scenario: {
435
+ $case: 'switchCandidateProtocol',
436
+ switchCandidateProtocol: 1,
437
+ },
422
438
  });
423
439
  postAction = () => {
424
440
  this.engine.publisher?.createAndSendOffer({ iceRestart: true });
@@ -800,10 +800,13 @@ export default class LocalParticipant extends Participant {
800
800
 
801
801
  const packet: DataPacket = {
802
802
  kind,
803
- user: {
804
- participantSid: this.sid,
805
- payload: data,
806
- destinationSids: dest,
803
+ value: {
804
+ $case: 'user',
805
+ user: {
806
+ participantSid: this.sid,
807
+ payload: data,
808
+ destinationSids: dest,
809
+ },
807
810
  },
808
811
  };
809
812
 
@@ -69,10 +69,11 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
69
69
  private _connectionQuality: ConnectionQuality = ConnectionQuality.Unknown;
70
70
 
71
71
  /** @internal */
72
- constructor(sid: string, identity: string) {
72
+ constructor(sid: string, identity: string, name?: string) {
73
73
  super();
74
74
  this.sid = sid;
75
75
  this.identity = identity;
76
+ this.name = name;
76
77
  this.audioTracks = new Map();
77
78
  this.videoTracks = new Map();
78
79
  this.tracks = new Map();
@@ -24,12 +24,12 @@ export default class RemoteParticipant extends Participant {
24
24
 
25
25
  /** @internal */
26
26
  static fromParticipantInfo(signalClient: SignalClient, pi: ParticipantInfo): RemoteParticipant {
27
- return new RemoteParticipant(signalClient, pi.sid, pi.identity);
27
+ return new RemoteParticipant(signalClient, pi.sid, pi.identity, pi.name);
28
28
  }
29
29
 
30
30
  /** @internal */
31
- constructor(signalClient: SignalClient, id: string, name?: string) {
32
- super(id, name || '');
31
+ constructor(signalClient: SignalClient, sid: string, identity?: string, name?: string) {
32
+ super(sid, identity || '', name);
33
33
  this.signalClient = signalClient;
34
34
  this.tracks = new Map();
35
35
  this.audioTracks = new Map();
@@ -93,6 +93,18 @@ describe('computeVideoEncodings', () => {
93
93
  expect(encodings![1].maxBitrate).toBe(VideoPresets.h360.encoding.maxBitrate);
94
94
  });
95
95
 
96
+ it('returns one encoding if an empty array is provided for custom screen share layers', () => {
97
+ const encodings = computeVideoEncodings(true, 1920, 1080, {
98
+ simulcast: true,
99
+ screenShareSimulcastLayers: [],
100
+ });
101
+ expect(encodings).toHaveLength(1);
102
+
103
+ // ensure they are what we expect
104
+ expect(encodings![0].rid).toBe('q');
105
+ expect(encodings![0].scaleResolutionDownBy).toBe(1);
106
+ });
107
+
96
108
  it('respects provided min resolution', () => {
97
109
  const encodings = computeVideoEncodings(false, 100, 120, {
98
110
  simulcast: true,
@@ -136,26 +136,28 @@ export function computeVideoEncodings(
136
136
  sortPresets(options?.videoSimulcastLayers) ?? defaultSimulcastLayers(isScreenShare, original);
137
137
  }
138
138
  let midPreset: VideoPreset | undefined;
139
- const lowPreset = presets[0];
140
- if (presets.length > 1) {
141
- [, midPreset] = presets;
142
- }
139
+ if (presets.length > 0) {
140
+ const lowPreset = presets[0];
141
+ if (presets.length > 1) {
142
+ [, midPreset] = presets;
143
+ }
143
144
 
144
- // NOTE:
145
- // 1. Ordering of these encodings is important. Chrome seems
146
- // to use the index into encodings to decide which layer
147
- // to disable when CPU constrained.
148
- // So encodings should be ordered in increasing spatial
149
- // resolution order.
150
- // 2. ion-sfu translates rids into layers. So, all encodings
151
- // should have the base layer `q` and then more added
152
- // based on other conditions.
153
- const size = Math.max(width, height);
154
- if (size >= 960 && midPreset) {
155
- return encodingsFromPresets(width, height, [lowPreset, midPreset, original]);
156
- }
157
- if (size >= 480) {
158
- return encodingsFromPresets(width, height, [lowPreset, original]);
145
+ // NOTE:
146
+ // 1. Ordering of these encodings is important. Chrome seems
147
+ // to use the index into encodings to decide which layer
148
+ // to disable when CPU constrained.
149
+ // So encodings should be ordered in increasing spatial
150
+ // resolution order.
151
+ // 2. ion-sfu translates rids into layers. So, all encodings
152
+ // should have the base layer `q` and then more added
153
+ // based on other conditions.
154
+ const size = Math.max(width, height);
155
+ if (size >= 960 && midPreset) {
156
+ return encodingsFromPresets(width, height, [lowPreset, midPreset, original]);
157
+ }
158
+ if (size >= 480) {
159
+ return encodingsFromPresets(width, height, [lowPreset, original]);
160
+ }
159
161
  }
160
162
  return encodingsFromPresets(width, height, [original]);
161
163
  }
@@ -5,11 +5,10 @@ import { Track } from './Track';
5
5
  export default class RemoteAudioTrack extends RemoteTrack {
6
6
  private prevStats?: AudioReceiverStats;
7
7
 
8
- private elementVolume: number;
8
+ private elementVolume: number | undefined;
9
9
 
10
10
  constructor(mediaTrack: MediaStreamTrack, sid: string, receiver?: RTCRtpReceiver) {
11
11
  super(mediaTrack, sid, Track.Kind.Audio, receiver);
12
- this.elementVolume = 1;
13
12
  }
14
13
 
15
14
  /**
@@ -23,10 +22,19 @@ export default class RemoteAudioTrack extends RemoteTrack {
23
22
  }
24
23
 
25
24
  /**
26
- * gets the volume for all attached audio elements
25
+ * gets the volume of attached audio elements (loudest)
27
26
  */
28
27
  getVolume(): number {
29
- return this.elementVolume;
28
+ if (this.elementVolume) {
29
+ return this.elementVolume;
30
+ }
31
+ let highestVolume = 0;
32
+ this.attachedElements.forEach((element) => {
33
+ if (element.volume > highestVolume) {
34
+ highestVolume = element.volume;
35
+ }
36
+ });
37
+ return highestVolume;
30
38
  }
31
39
 
32
40
  attach(): HTMLMediaElement;
@@ -37,7 +45,9 @@ export default class RemoteAudioTrack extends RemoteTrack {
37
45
  } else {
38
46
  super.attach(element);
39
47
  }
40
- element.volume = this.elementVolume;
48
+ if (this.elementVolume) {
49
+ element.volume = this.elementVolume;
50
+ }
41
51
  return element;
42
52
  }
43
53
 
@@ -134,6 +134,7 @@ export default class RemoteTrackPublication extends TrackPublication {
134
134
  prevTrack.off(TrackEvent.VideoDimensionsChanged, this.handleVideoDimensionsChange);
135
135
  prevTrack.off(TrackEvent.VisibilityChanged, this.handleVisibilityChange);
136
136
  prevTrack.off(TrackEvent.Ended, this.handleEnded);
137
+ prevTrack.detach();
137
138
  }
138
139
  super.setTrack(track);
139
140
  if (track) {