livekit-client 1.4.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package/dist/livekit-client.esm.mjs +2478 -5368
  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 +3 -2
  6. package/dist/src/api/SignalClient.d.ts.map +1 -1
  7. package/dist/src/connectionHelper/ConnectionCheck.d.ts +25 -0
  8. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -0
  9. package/dist/src/connectionHelper/checks/Checker.d.ts +59 -0
  10. package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -0
  11. package/dist/src/connectionHelper/checks/publishAudio.d.ts +6 -0
  12. package/dist/src/connectionHelper/checks/publishAudio.d.ts.map +1 -0
  13. package/dist/src/connectionHelper/checks/publishVideo.d.ts +6 -0
  14. package/dist/src/connectionHelper/checks/publishVideo.d.ts.map +1 -0
  15. package/dist/src/connectionHelper/checks/reconnect.d.ts +6 -0
  16. package/dist/src/connectionHelper/checks/reconnect.d.ts.map +1 -0
  17. package/dist/src/connectionHelper/checks/turn.d.ts +6 -0
  18. package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -0
  19. package/dist/src/connectionHelper/checks/webrtc.d.ts +6 -0
  20. package/dist/src/connectionHelper/checks/webrtc.d.ts.map +1 -0
  21. package/dist/src/connectionHelper/checks/websocket.d.ts +6 -0
  22. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -0
  23. package/dist/src/index.d.ts +6 -3
  24. package/dist/src/index.d.ts.map +1 -1
  25. package/dist/src/logger.d.ts +3 -3
  26. package/dist/src/logger.d.ts.map +1 -1
  27. package/dist/src/options.d.ts +4 -1
  28. package/dist/src/options.d.ts.map +1 -1
  29. package/dist/src/proto/google/protobuf/timestamp.d.ts +4 -4
  30. package/dist/src/proto/google/protobuf/timestamp.d.ts.map +1 -1
  31. package/dist/src/proto/livekit_models.d.ts +4 -4
  32. package/dist/src/proto/livekit_models.d.ts.map +1 -1
  33. package/dist/src/proto/livekit_rtc.d.ts +12 -4
  34. package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
  35. package/dist/src/room/DeviceManager.d.ts.map +1 -1
  36. package/dist/src/room/RTCEngine.d.ts +4 -3
  37. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  38. package/dist/src/room/Room.d.ts +27 -4
  39. package/dist/src/room/Room.d.ts.map +1 -1
  40. package/dist/src/room/events.d.ts +9 -1
  41. package/dist/src/room/events.d.ts.map +1 -1
  42. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  43. package/dist/src/room/participant/Participant.d.ts +1 -1
  44. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  45. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  46. package/dist/src/room/track/RemoteTrackPublication.d.ts +2 -0
  47. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  48. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  49. package/dist/src/room/track/Track.d.ts +2 -1
  50. package/dist/src/room/track/Track.d.ts.map +1 -1
  51. package/dist/src/room/track/TrackPublication.d.ts +1 -1
  52. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  53. package/dist/src/room/track/options.d.ts +3 -3
  54. package/dist/src/room/track/options.d.ts.map +1 -1
  55. package/dist/src/room/track/types.d.ts +3 -3
  56. package/dist/src/room/track/types.d.ts.map +1 -1
  57. package/dist/src/room/types.d.ts +13 -0
  58. package/dist/src/room/types.d.ts.map +1 -0
  59. package/dist/src/room/utils.d.ts +44 -0
  60. package/dist/src/room/utils.d.ts.map +1 -1
  61. package/dist/ts4.2/src/api/SignalClient.d.ts +86 -0
  62. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +25 -0
  63. package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +59 -0
  64. package/dist/ts4.2/src/connectionHelper/checks/publishAudio.d.ts +6 -0
  65. package/dist/ts4.2/src/connectionHelper/checks/publishVideo.d.ts +6 -0
  66. package/dist/ts4.2/src/connectionHelper/checks/reconnect.d.ts +6 -0
  67. package/dist/ts4.2/src/connectionHelper/checks/turn.d.ts +6 -0
  68. package/dist/ts4.2/src/connectionHelper/checks/webrtc.d.ts +6 -0
  69. package/dist/ts4.2/src/connectionHelper/checks/websocket.d.ts +6 -0
  70. package/dist/ts4.2/src/index.d.ts +31 -0
  71. package/dist/ts4.2/src/logger.d.ts +26 -0
  72. package/dist/ts4.2/src/options.d.ts +94 -0
  73. package/dist/ts4.2/src/proto/google/protobuf/timestamp.d.ts +141 -0
  74. package/dist/ts4.2/src/proto/livekit_models.d.ts +1421 -0
  75. package/dist/ts4.2/src/proto/livekit_rtc.d.ts +7122 -0
  76. package/dist/ts4.2/src/room/DefaultReconnectPolicy.d.ts +8 -0
  77. package/dist/ts4.2/src/room/DeviceManager.d.ts +9 -0
  78. package/dist/ts4.2/src/room/PCTransport.d.ts +33 -0
  79. package/dist/ts4.2/src/room/RTCEngine.d.ts +97 -0
  80. package/dist/ts4.2/src/room/ReconnectPolicy.d.ts +23 -0
  81. package/dist/ts4.2/src/room/Room.d.ts +220 -0
  82. package/dist/ts4.2/src/room/defaults.d.ts +8 -0
  83. package/dist/ts4.2/src/room/errors.d.ts +39 -0
  84. package/dist/ts4.2/src/room/events.d.ts +426 -0
  85. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +141 -0
  86. package/dist/ts4.2/src/room/participant/Participant.d.ts +92 -0
  87. package/dist/ts4.2/src/room/participant/ParticipantTrackPermission.d.ts +26 -0
  88. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +52 -0
  89. package/dist/ts4.2/src/room/participant/publishUtils.d.ts +19 -0
  90. package/dist/ts4.2/src/room/stats.d.ts +67 -0
  91. package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +25 -0
  92. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +42 -0
  93. package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +38 -0
  94. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +53 -0
  95. package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +53 -0
  96. package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +15 -0
  97. package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +61 -0
  98. package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +52 -0
  99. package/dist/ts4.2/src/room/track/Track.d.ts +122 -0
  100. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +68 -0
  101. package/dist/ts4.2/src/room/track/create.d.ts +24 -0
  102. package/dist/ts4.2/src/room/track/options.d.ts +241 -0
  103. package/dist/ts4.2/src/room/track/types.d.ts +23 -0
  104. package/dist/ts4.2/src/room/track/utils.d.ts +14 -0
  105. package/dist/ts4.2/src/room/types.d.ts +13 -0
  106. package/dist/ts4.2/src/room/utils.d.ts +79 -0
  107. package/dist/ts4.2/src/test/MockMediaStreamTrack.d.ts +26 -0
  108. package/dist/ts4.2/src/test/mocks.d.ts +11 -0
  109. package/dist/ts4.2/src/version.d.ts +3 -0
  110. package/package.json +32 -22
  111. package/src/api/SignalClient.ts +41 -17
  112. package/src/connectionHelper/ConnectionCheck.ts +90 -0
  113. package/src/connectionHelper/checks/Checker.ts +164 -0
  114. package/src/connectionHelper/checks/publishAudio.ts +33 -0
  115. package/src/connectionHelper/checks/publishVideo.ts +33 -0
  116. package/src/connectionHelper/checks/reconnect.ts +45 -0
  117. package/src/connectionHelper/checks/turn.ts +53 -0
  118. package/src/connectionHelper/checks/webrtc.ts +18 -0
  119. package/src/connectionHelper/checks/websocket.ts +22 -0
  120. package/src/index.ts +8 -1
  121. package/src/options.ts +5 -1
  122. package/src/proto/livekit_rtc.ts +12 -1
  123. package/src/room/DeviceManager.ts +0 -17
  124. package/src/room/RTCEngine.ts +35 -26
  125. package/src/room/Room.ts +231 -63
  126. package/src/room/events.ts +9 -0
  127. package/src/room/participant/LocalParticipant.ts +18 -11
  128. package/src/room/participant/publishUtils.ts +1 -1
  129. package/src/room/track/LocalAudioTrack.ts +1 -1
  130. package/src/room/track/LocalTrack.ts +4 -0
  131. package/src/room/track/LocalVideoTrack.ts +1 -1
  132. package/src/room/track/RemoteTrackPublication.ts +20 -0
  133. package/src/room/track/RemoteVideoTrack.ts +4 -0
  134. package/src/room/track/Track.ts +1 -0
  135. package/src/room/types.ts +12 -0
  136. package/src/room/utils.ts +150 -12
@@ -113,7 +113,7 @@ export default class LocalVideoTrack extends LocalTrack {
113
113
  }
114
114
 
115
115
  async getSenderStats(): Promise<VideoSenderStats[]> {
116
- if (!this.sender) {
116
+ if (!this.sender?.getStats) {
117
117
  return [];
118
118
  }
119
119
 
@@ -22,6 +22,8 @@ export default class RemoteTrackPublication extends TrackPublication {
22
22
 
23
23
  protected videoDimensions?: Track.Dimensions;
24
24
 
25
+ protected fps?: number;
26
+
25
27
  constructor(kind: Track.Kind, id: string, name: string, autoSubscribe: boolean | undefined) {
26
28
  super(kind, id, name);
27
29
  this.subscribed = autoSubscribe;
@@ -143,6 +145,23 @@ export default class RemoteTrackPublication extends TrackPublication {
143
145
  this.emitTrackUpdate();
144
146
  }
145
147
 
148
+ setVideoFPS(fps: number) {
149
+ if (!this.isManualOperationAllowed()) {
150
+ return;
151
+ }
152
+
153
+ if (!(this.track instanceof RemoteVideoTrack)) {
154
+ return;
155
+ }
156
+
157
+ if (this.fps === fps) {
158
+ return;
159
+ }
160
+
161
+ this.fps = fps;
162
+ this.emitTrackUpdate();
163
+ }
164
+
146
165
  get videoQuality(): VideoQuality | undefined {
147
166
  return this.currentVideoQuality;
148
167
  }
@@ -256,6 +275,7 @@ export default class RemoteTrackPublication extends TrackPublication {
256
275
  const settings: UpdateTrackSettings = UpdateTrackSettings.fromPartial({
257
276
  trackSids: [this.trackSid],
258
277
  disabled: this.disabled,
278
+ fps: this.fps,
259
279
  });
260
280
  if (this.videoDimensions) {
261
281
  settings.width = this.videoDimensions.width;
@@ -118,6 +118,10 @@ export default class RemoteVideoTrack extends RemoteTrack {
118
118
  * @internal
119
119
  */
120
120
  stopObservingElementInfo(elementInfo: ElementInfo) {
121
+ if (!this.isAdaptiveStream) {
122
+ log.warn('stopObservingElementInfo ignored');
123
+ return;
124
+ }
121
125
  const stopElementInfos = this.elementInfos.filter((info) => info === elementInfo);
122
126
  for (const info of stopElementInfos) {
123
127
  info.stopObserving();
@@ -398,6 +398,7 @@ export type TrackEventCallbacks = {
398
398
  message: () => void;
399
399
  muted: (track?: any) => void;
400
400
  unmuted: (track?: any) => void;
401
+ restarted: (track?: any) => void;
401
402
  ended: (track?: any) => void;
402
403
  updateSettings: () => void;
403
404
  updateSubscription: () => void;
@@ -0,0 +1,12 @@
1
+ export type SimulationOptions = {
2
+ publish?: {
3
+ audio?: boolean;
4
+ video?: boolean;
5
+ };
6
+ participants?: {
7
+ count?: number;
8
+ aspectRatios?: Array<number>;
9
+ audio?: boolean;
10
+ video?: boolean;
11
+ };
12
+ };
package/src/room/utils.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import UAParser from 'ua-parser-js';
2
2
  import { ClientInfo, ClientInfo_SDK } from '../proto/livekit_models';
3
3
  import { protocolVersion, version } from '../version';
4
+ import type LocalAudioTrack from './track/LocalAudioTrack';
5
+ import type RemoteAudioTrack from './track/RemoteAudioTrack';
6
+ import { getNewAudioContext } from './track/utils';
4
7
 
5
8
  const separator = '|';
6
9
 
@@ -178,22 +181,41 @@ let emptyVideoStreamTrack: MediaStreamTrack | undefined;
178
181
 
179
182
  export function getEmptyVideoStreamTrack() {
180
183
  if (!emptyVideoStreamTrack) {
181
- const canvas = document.createElement('canvas');
182
- // the canvas size is set to 16, because electron apps seem to fail with smaller values
183
- canvas.width = 16;
184
- canvas.height = 16;
185
- canvas.getContext('2d')?.fillRect(0, 0, canvas.width, canvas.height);
186
- // @ts-ignore
187
- const emptyStream = canvas.captureStream();
188
- [emptyVideoStreamTrack] = emptyStream.getTracks();
189
- if (!emptyVideoStreamTrack) {
190
- throw Error('Could not get empty media stream video track');
191
- }
192
- emptyVideoStreamTrack.enabled = false;
184
+ emptyVideoStreamTrack = createDummyVideoStreamTrack();
193
185
  }
194
186
  return emptyVideoStreamTrack;
195
187
  }
196
188
 
189
+ export function createDummyVideoStreamTrack(
190
+ width: number = 16,
191
+ height: number = 16,
192
+ enabled: boolean = false,
193
+ paintContent: boolean = false,
194
+ ) {
195
+ const canvas = document.createElement('canvas');
196
+ // the canvas size is set to 16 by default, because electron apps seem to fail with smaller values
197
+ canvas.width = width;
198
+ canvas.height = height;
199
+ const ctx = canvas.getContext('2d');
200
+ ctx?.fillRect(0, 0, canvas.width, canvas.height);
201
+ if (paintContent && ctx) {
202
+ ctx.beginPath();
203
+ ctx.arc(width / 2, height / 2, 50, 0, Math.PI * 2, true);
204
+ ctx.closePath();
205
+ ctx.fillStyle = 'grey';
206
+ ctx.fill();
207
+ }
208
+ // @ts-ignore
209
+ const dummyStream = canvas.captureStream();
210
+ const [dummyTrack] = dummyStream.getTracks();
211
+ if (!dummyTrack) {
212
+ throw Error('Could not get empty media stream video track');
213
+ }
214
+ dummyTrack.enabled = enabled;
215
+
216
+ return dummyTrack;
217
+ }
218
+
197
219
  let emptyAudioStreamTrack: MediaStreamTrack | undefined;
198
220
 
199
221
  export function getEmptyAudioStreamTrack() {
@@ -236,3 +258,119 @@ export class Future<T> {
236
258
  }).finally(() => this.onFinally?.());
237
259
  }
238
260
  }
261
+
262
+ export type AudioAnalyserOptions = {
263
+ /**
264
+ * If set to true, the analyser will use a cloned version of the underlying mediastreamtrack, which won't be impacted by muting the track.
265
+ * Useful for local tracks when implementing things like "seems like you're muted, but trying to speak".
266
+ * Defaults to false
267
+ */
268
+ cloneTrack?: boolean;
269
+ /**
270
+ * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize
271
+ */
272
+ fftSize?: number;
273
+ /**
274
+ * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/smoothingTimeConstant
275
+ */
276
+ smoothingTimeConstant?: number;
277
+ /**
278
+ * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/minDecibels
279
+ */
280
+ minDecibels?: number;
281
+ /**
282
+ * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels
283
+ */
284
+ maxDecibels?: number;
285
+ };
286
+
287
+ /**
288
+ * Creates and returns an analyser web audio node that is attached to the provided track.
289
+ * Additionally returns a convenience method `calculateVolume` to perform instant volume readings on that track.
290
+ * Call the returned `cleanup` function to close the audioContext that has been created for the instance of this helper
291
+ */
292
+ export function createAudioAnalyser(
293
+ track: LocalAudioTrack | RemoteAudioTrack,
294
+ options?: AudioAnalyserOptions,
295
+ ) {
296
+ const opts = {
297
+ cloneTrack: false,
298
+ fftSize: 2048,
299
+ smoothingTimeConstant: 0.8,
300
+ minDecibels: -100,
301
+ maxDecibels: -80,
302
+ ...options,
303
+ };
304
+ const audioContext = getNewAudioContext();
305
+
306
+ if (!audioContext) {
307
+ throw new Error('Audio Context not supported on this browser');
308
+ }
309
+ const streamTrack = opts.cloneTrack ? track.mediaStreamTrack.clone() : track.mediaStreamTrack;
310
+ const mediaStreamSource = audioContext.createMediaStreamSource(new MediaStream([streamTrack]));
311
+ const analyser = audioContext.createAnalyser();
312
+ analyser.minDecibels = opts.minDecibels;
313
+ analyser.maxDecibels = opts.maxDecibels;
314
+ analyser.fftSize = opts.fftSize;
315
+ analyser.smoothingTimeConstant = opts.smoothingTimeConstant;
316
+
317
+ mediaStreamSource.connect(analyser);
318
+ const dataArray = new Uint8Array(analyser.frequencyBinCount);
319
+
320
+ /**
321
+ * Calculates the current volume of the track in the range from 0 to 1
322
+ */
323
+ const calculateVolume = () => {
324
+ analyser.getByteFrequencyData(dataArray);
325
+ let sum = 0;
326
+ for (const amplitude of dataArray) {
327
+ sum += Math.pow(amplitude / 255, 2);
328
+ }
329
+ const volume = Math.sqrt(sum / dataArray.length);
330
+ return volume;
331
+ };
332
+
333
+ const cleanup = () => {
334
+ audioContext.close();
335
+ if (opts.cloneTrack) {
336
+ streamTrack.stop();
337
+ }
338
+ };
339
+
340
+ return { calculateVolume, analyser, cleanup };
341
+ }
342
+
343
+ export class Mutex {
344
+ private _locking: Promise<void>;
345
+
346
+ private _locks: number;
347
+
348
+ constructor() {
349
+ this._locking = Promise.resolve();
350
+ this._locks = 0;
351
+ }
352
+
353
+ isLocked() {
354
+ return this._locks > 0;
355
+ }
356
+
357
+ lock() {
358
+ this._locks += 1;
359
+
360
+ let unlockNext: () => void;
361
+
362
+ const willLock = new Promise<void>(
363
+ (resolve) =>
364
+ (unlockNext = () => {
365
+ this._locks -= 1;
366
+ resolve();
367
+ }),
368
+ );
369
+
370
+ const willUnlock = this._locking.then(() => unlockNext);
371
+
372
+ this._locking = this._locking.then(() => willLock);
373
+
374
+ return willUnlock;
375
+ }
376
+ }