@stream-io/video-client 1.35.1 → 1.36.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 (63) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/index.browser.es.js +382 -329
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +404 -333
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +382 -329
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +3 -2
  9. package/dist/src/StreamVideoClient.d.ts +3 -2
  10. package/dist/src/coordinator/connection/client.d.ts +3 -2
  11. package/dist/src/coordinator/connection/connection.d.ts +2 -1
  12. package/dist/src/coordinator/connection/types.d.ts +17 -1
  13. package/dist/src/devices/DeviceManager.d.ts +2 -2
  14. package/dist/src/logger.d.ts +9 -6
  15. package/dist/src/rpc/createClient.d.ts +3 -2
  16. package/dist/src/rtc/BasePeerConnection.d.ts +7 -4
  17. package/dist/src/rtc/Publisher.d.ts +3 -3
  18. package/dist/src/rtc/codecs.d.ts +3 -1
  19. package/dist/src/rtc/helpers/sdp.d.ts +8 -0
  20. package/dist/src/rtc/types.d.ts +4 -5
  21. package/dist/src/store/CallState.d.ts +1 -1
  22. package/dist/src/types.d.ts +6 -0
  23. package/package.json +3 -2
  24. package/src/Call.ts +49 -68
  25. package/src/StreamSfuClient.ts +11 -11
  26. package/src/StreamVideoClient.ts +19 -21
  27. package/src/coordinator/connection/client.ts +21 -30
  28. package/src/coordinator/connection/connection.ts +5 -4
  29. package/src/coordinator/connection/location.ts +4 -4
  30. package/src/coordinator/connection/types.ts +21 -2
  31. package/src/devices/BrowserPermission.ts +5 -5
  32. package/src/devices/CameraManager.ts +3 -4
  33. package/src/devices/DeviceManager.ts +11 -11
  34. package/src/devices/MicrophoneManager.ts +8 -8
  35. package/src/devices/devices.ts +18 -14
  36. package/src/events/call.ts +6 -9
  37. package/src/events/internal.ts +4 -4
  38. package/src/events/mutes.ts +3 -8
  39. package/src/helpers/DynascaleManager.ts +9 -9
  40. package/src/helpers/RNSpeechDetector.ts +5 -5
  41. package/src/helpers/clientUtils.ts +1 -3
  42. package/src/helpers/ensureExhausted.ts +2 -2
  43. package/src/logger.ts +9 -34
  44. package/src/rpc/__tests__/createClient.test.ts +5 -1
  45. package/src/rpc/createClient.ts +4 -3
  46. package/src/rpc/retryable.ts +4 -2
  47. package/src/rtc/BasePeerConnection.ts +26 -24
  48. package/src/rtc/Dispatcher.ts +4 -4
  49. package/src/rtc/IceTrickleBuffer.ts +5 -5
  50. package/src/rtc/Publisher.ts +21 -13
  51. package/src/rtc/Subscriber.ts +22 -17
  52. package/src/rtc/__tests__/Publisher.test.ts +12 -8
  53. package/src/rtc/codecs.ts +13 -2
  54. package/src/rtc/helpers/__tests__/sdp.codecs.test.ts +628 -0
  55. package/src/rtc/helpers/sdp.ts +82 -0
  56. package/src/rtc/signal.ts +7 -7
  57. package/src/rtc/types.ts +4 -4
  58. package/src/stats/CallStateStatsReporter.ts +4 -4
  59. package/src/stats/SfuStatsReporter.ts +6 -6
  60. package/src/store/CallState.ts +3 -3
  61. package/src/store/rxUtils.ts +4 -2
  62. package/src/store/stateStore.ts +6 -6
  63. package/src/types.ts +6 -0
@@ -11,7 +11,6 @@ import {
11
11
  addConnectionEventListeners,
12
12
  generateUUIDv4,
13
13
  isErrorResponse,
14
- isFunction,
15
14
  KnownCodes,
16
15
  removeConnectionEventListeners,
17
16
  retryInterval,
@@ -24,7 +23,6 @@ import {
24
23
  ClientEventListener,
25
24
  ConnectAPIResponse,
26
25
  ErrorFromResponse,
27
- Logger,
28
26
  StreamClientOptions,
29
27
  StreamVideoEvent,
30
28
  TokenOrProvider,
@@ -38,7 +36,7 @@ import {
38
36
  CreateGuestResponse,
39
37
  } from '../../gen/coordinator';
40
38
  import { makeSafePromise, type SafePromise } from '../../helpers/promise';
41
- import { getLogLevel } from '../../logger';
39
+ import { ScopedLogger, videoLoggerSystem } from '../../logger';
42
40
 
43
41
  export class StreamClient {
44
42
  _user?: UserWithId;
@@ -52,7 +50,7 @@ export class StreamClient {
52
50
  listeners: Partial<
53
51
  Record<AllClientEventTypes, ClientEventListener<any>[] | undefined>
54
52
  > = {};
55
- logger: Logger;
53
+ logger: ScopedLogger;
56
54
 
57
55
  private locationHint: Promise<string> | undefined;
58
56
 
@@ -150,9 +148,7 @@ export class StreamClient {
150
148
 
151
149
  this.defaultWSTimeout = this.options.defaultWsTimeout ?? 15000;
152
150
 
153
- this.logger = isFunction(inputOptions.logger)
154
- ? inputOptions.logger
155
- : () => null;
151
+ this.logger = videoLoggerSystem.getLogger('coordinator');
156
152
  }
157
153
 
158
154
  getAuthType = () => {
@@ -206,8 +202,7 @@ export class StreamClient {
206
202
  * If the user id remains the same we don't throw error
207
203
  */
208
204
  if (this.userID === user.id && this.connectUserTask) {
209
- this.logger(
210
- 'warn',
205
+ this.logger.warn(
211
206
  'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',
212
207
  );
213
208
  return this.connectUserTask;
@@ -220,8 +215,7 @@ export class StreamClient {
220
215
  }
221
216
 
222
217
  if ((this.secret || this.node) && !this.options.allowServerSideConnect) {
223
- this.logger(
224
- 'warn',
218
+ this.logger.warn(
225
219
  'Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/',
226
220
  );
227
221
  }
@@ -288,16 +282,14 @@ export class StreamClient {
288
282
 
289
283
  const wsPromise = this.wsPromiseSafe?.();
290
284
  if (this.wsConnection?.isConnecting && wsPromise) {
291
- this.logger(
292
- 'info',
285
+ this.logger.info(
293
286
  'client:openConnection() - connection already in progress',
294
287
  );
295
288
  return await wsPromise;
296
289
  }
297
290
 
298
291
  if (this.wsConnection?.isHealthy && this._hasConnectionID()) {
299
- this.logger(
300
- 'info',
292
+ this.logger.info(
301
293
  'client:openConnection() - openConnection called twice, healthy connection already exists',
302
294
  );
303
295
 
@@ -319,7 +311,7 @@ export class StreamClient {
319
311
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
320
312
  */
321
313
  disconnectUser = async (timeout?: number) => {
322
- this.logger('info', 'client:disconnect() - Disconnecting the client');
314
+ this.logger.info('client:disconnect() - Disconnecting the client');
323
315
 
324
316
  // remove the user specific fields
325
317
  delete this.user;
@@ -390,7 +382,7 @@ export class StreamClient {
390
382
  this.listeners[eventName] = [];
391
383
  }
392
384
 
393
- this.logger('debug', `Adding listener for ${eventName} event`);
385
+ this.logger.debug(`Adding listener for ${eventName} event`);
394
386
  this.listeners[eventName]?.push(callback as ClientEventListener<any>);
395
387
  return () => {
396
388
  this.off(eventName, callback);
@@ -408,7 +400,7 @@ export class StreamClient {
408
400
  this.listeners[eventName] = [];
409
401
  }
410
402
 
411
- this.logger('debug', `Removing listener for ${eventName} event`);
403
+ this.logger.debug(`Removing listener for ${eventName} event`);
412
404
  this.listeners[eventName] = this.listeners[eventName]?.filter(
413
405
  (value) => value !== callback,
414
406
  );
@@ -447,8 +439,8 @@ export class StreamClient {
447
439
  config?: AxiosRequestConfig & { maxBodyLength?: number };
448
440
  },
449
441
  ) => {
450
- if (getLogLevel() !== 'trace') return;
451
- this.logger('trace', `client: ${type} - Request - ${url}`, {
442
+ if (this.logger.getLogLevel() !== 'trace') return;
443
+ this.logger.trace(`client: ${type} - Request - ${url}`, {
452
444
  payload: data,
453
445
  config,
454
446
  });
@@ -459,9 +451,8 @@ export class StreamClient {
459
451
  url: string,
460
452
  response: AxiosResponse<T>,
461
453
  ) => {
462
- if (getLogLevel() !== 'trace') return;
463
- this.logger(
464
- 'trace',
454
+ if (this.logger.getLogLevel() !== 'trace') return;
455
+ this.logger.trace(
465
456
  `client:${type} - Response - url: ${url} > status ${response.status}`,
466
457
  {
467
458
  response,
@@ -529,14 +520,14 @@ export class StreamClient {
529
520
  this.consecutiveFailures += 1;
530
521
  const { response } = e;
531
522
  if (!response || !isErrorResponse(response)) {
532
- this.logger('error', `client:${type} url: ${url}`, e);
523
+ this.logger.error(`client:${type} url: ${url}`, e);
533
524
  throw e as AxiosError<APIErrorResponse>;
534
525
  }
535
526
 
536
527
  const { data: responseData, status } = response;
537
528
  const isTokenExpired = responseData.code === KnownCodes.TOKEN_EXPIRED;
538
529
  if (isTokenExpired && !this.tokenManager.isStatic()) {
539
- this.logger('warn', `client:${type}: url: ${url}`, response);
530
+ this.logger.warn(`client:${type}: url: ${url}`, response);
540
531
  if (this.consecutiveFailures > 1) {
541
532
  await sleep(retryInterval(this.consecutiveFailures));
542
533
  }
@@ -544,7 +535,7 @@ export class StreamClient {
544
535
  await this.tokenManager.loadToken();
545
536
  return await this.doAxiosRequest<T, D>(type, url, data, options);
546
537
  } else {
547
- this.logger('error', `client:${type} url: ${url}`, response);
538
+ this.logger.error(`client:${type} url: ${url}`, response);
548
539
  throw new ErrorFromResponse<APIErrorResponse>({
549
540
  message: `Stream error code ${responseData.code}: ${responseData.message}`,
550
541
  code: responseData.code ?? null,
@@ -593,7 +584,7 @@ export class StreamClient {
593
584
  };
594
585
 
595
586
  dispatchEvent = (event: StreamVideoEvent) => {
596
- this.logger('debug', `Dispatching event: ${event.type}`, event);
587
+ this.logger.debug(`Dispatching event: ${event.type}`, event);
597
588
  if (!this.listeners) return;
598
589
 
599
590
  // call generic listeners
@@ -622,7 +613,7 @@ export class StreamClient {
622
613
  // The StableWSConnection handles all the reconnection logic.
623
614
  this.wsConnection = new StableWSConnection(this);
624
615
 
625
- this.logger('info', 'StreamClient.connect: this.wsConnection.connect()');
616
+ this.logger.info('StreamClient.connect: this.wsConnection.connect()');
626
617
  return await this.wsConnection.connect(this.defaultWSTimeout);
627
618
  };
628
619
 
@@ -704,10 +695,10 @@ export class StreamClient {
704
695
  event: { type: 'online' | 'offline' } | Event,
705
696
  ) => {
706
697
  if (event.type === 'offline') {
707
- this.logger('debug', 'device went offline');
698
+ this.logger.debug('device went offline');
708
699
  this.dispatchEvent({ type: 'network.changed', online: false });
709
700
  } else if (event.type === 'online') {
710
- this.logger('debug', 'device went online');
701
+ this.logger.debug('device went online');
711
702
  this.dispatchEvent({ type: 'network.changed', online: true });
712
703
  }
713
704
  };
@@ -7,7 +7,8 @@ import {
7
7
  retryInterval,
8
8
  sleep,
9
9
  } from './utils';
10
- import type { LogLevel, StreamVideoEvent, UR } from './types';
10
+ import type { StreamVideoEvent, UR } from './types';
11
+ import type { LogLevel } from '@stream-io/logger';
11
12
  import type {
12
13
  ConnectedEvent,
13
14
  ConnectionErrorEvent,
@@ -88,7 +89,7 @@ export class StableWSConnection {
88
89
  }
89
90
 
90
91
  _log = (msg: string, extra: UR = {}, level: LogLevel = 'info') => {
91
- this.client.logger(level, `connection:${msg}`, extra);
92
+ this.client.logger[level](`connection:${msg}`, extra);
92
93
  };
93
94
 
94
95
  setClient = (client: StreamClient) => {
@@ -442,13 +443,13 @@ export class StableWSConnection {
442
443
 
443
444
  const user = this.client.user;
444
445
  if (!user) {
445
- this.client.logger('error', `User not set, can't connect to WS`);
446
+ this.client.logger.error(`User not set, can't connect to WS`);
446
447
  return;
447
448
  }
448
449
 
449
450
  const token = this.client._getToken();
450
451
  if (!token) {
451
- this.client.logger('error', `Token not set, can't connect authenticate`);
452
+ this.client.logger.error(`Token not set, can't connect authenticate`);
452
453
  return;
453
454
  }
454
455
 
@@ -1,11 +1,11 @@
1
- import { getLogger } from '../../logger';
1
+ import { videoLoggerSystem } from '../../logger';
2
2
 
3
3
  export const getLocationHint = async (
4
4
  hintUrl = `https://hint.stream-io-video.com/`,
5
5
  timeout = 2000,
6
6
  maxAttempts = 3,
7
7
  ): Promise<string> => {
8
- const logger = getLogger(['location-hint']);
8
+ const logger = videoLoggerSystem.getLogger('location-hint');
9
9
 
10
10
  let attempt = 0;
11
11
  let locationHint = 'ERR';
@@ -18,10 +18,10 @@ export const getLocationHint = async (
18
18
  signal: abortController.signal,
19
19
  });
20
20
  const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
21
- logger('debug', `Location header: ${awsPop}`);
21
+ logger.debug(`Location header: ${awsPop}`);
22
22
  locationHint = awsPop.substring(0, 3); // AMS1-P2 -> AMS
23
23
  } catch (e) {
24
- logger('warn', `Failed to get location hint from ${hintUrl}`, e);
24
+ logger.warn(`Failed to get location hint from ${hintUrl}`, e);
25
25
  locationHint = 'ERR';
26
26
  } finally {
27
27
  clearTimeout(timeoutId);
@@ -1,6 +1,7 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
2
  import { ConnectedEvent, UserRequest, VideoEvent } from '../../gen/coordinator';
3
3
  import { AllSfuEvents } from '../../rtc';
4
+ import type { ConfigureLoggersOptions, LogLevel } from '@stream-io/logger';
4
5
 
5
6
  export type UR = Record<string, unknown>;
6
7
 
@@ -24,8 +25,6 @@ export type { OwnUserResponse } from '../../gen/coordinator';
24
25
 
25
26
  export type ConnectAPIResponse = Promise<void | ConnectedEvent>;
26
27
 
27
- export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
28
-
29
28
  type ErrorResponseDetails = {
30
29
  code: number;
31
30
  messages: string[];
@@ -156,8 +155,28 @@ export type StreamClientOptions = Partial<AxiosRequestConfig> & {
156
155
  */
157
156
  baseURL?: string;
158
157
  browser?: boolean;
158
+
159
+ /**
160
+ * @deprecated Use `logOptions` instead.
161
+ * Custom logger instance used to handle log messages.
162
+ * Will be removed in a future release.
163
+ */
159
164
  logger?: Logger;
165
+
166
+ /**
167
+ * @deprecated Use `logOptions` instead.
168
+ * Sets the minimum log level for all logs.
169
+ * Will be removed in a future release.
170
+ */
160
171
  logLevel?: LogLevel;
172
+
173
+ /**
174
+ * Configuration options where keys are logger scopes.
175
+ * The `default` scope is reserved is used to set defaults for all loggers.
176
+ *
177
+ */
178
+ logOptions?: ConfigureLoggersOptions;
179
+
161
180
  /**
162
181
  * The URL to use for the location hint.
163
182
  */
@@ -1,8 +1,8 @@
1
1
  import { fromEventPattern, map } from 'rxjs';
2
2
  import { isReactNative } from '../helpers/platforms';
3
- import { getLogger } from '../logger';
4
3
  import { disposeOfMediaStream } from './utils';
5
4
  import { withoutConcurrency } from '../helpers/concurrency';
5
+ import { videoLoggerSystem } from '../logger';
6
6
 
7
7
  interface BrowserPermissionConfig {
8
8
  constraints: DisplayMediaStreamOptions;
@@ -17,7 +17,7 @@ export class BrowserPermission {
17
17
  private state: BrowserPermissionState | undefined;
18
18
  private wasPrompted: boolean = false;
19
19
  private listeners = new Set<(state: BrowserPermissionState) => void>();
20
- private logger = getLogger(['permissions']);
20
+ private logger = videoLoggerSystem.getLogger('permissions');
21
21
 
22
22
  constructor(private readonly permission: BrowserPermissionConfig) {
23
23
  const signal = this.disposeController.signal;
@@ -47,7 +47,7 @@ export class BrowserPermission {
47
47
  });
48
48
  }
49
49
  } catch (err) {
50
- this.logger('debug', 'Failed to query permission status', err);
50
+ this.logger.debug('Failed to query permission status', err);
51
51
  assumeGranted();
52
52
  }
53
53
  })();
@@ -104,7 +104,7 @@ export class BrowserPermission {
104
104
  'name' in e &&
105
105
  (e.name === 'NotAllowedError' || e.name === 'SecurityError')
106
106
  ) {
107
- this.logger('info', 'Browser permission was not granted', {
107
+ this.logger.info('Browser permission was not granted', {
108
108
  permission: this.permission,
109
109
  });
110
110
  this.setState('denied');
@@ -116,7 +116,7 @@ export class BrowserPermission {
116
116
  return false;
117
117
  }
118
118
 
119
- this.logger('error', `Failed to getUserMedia`, {
119
+ this.logger.error(`Failed to getUserMedia`, {
120
120
  error: e,
121
121
  permission: this.permission,
122
122
  });
@@ -34,7 +34,7 @@ export class CameraManager extends DeviceManager<CameraManagerState> {
34
34
  */
35
35
  async selectDirection(direction: Exclude<CameraDirection, undefined>) {
36
36
  if (!this.isDirectionSupportedByDevice()) {
37
- this.logger('warn', 'Setting direction is not supported on this device');
37
+ this.logger.warn('Setting direction is not supported on this device');
38
38
  return;
39
39
  }
40
40
 
@@ -86,7 +86,7 @@ export class CameraManager extends DeviceManager<CameraManagerState> {
86
86
  await this.statusChangeSettled();
87
87
  } catch (error) {
88
88
  // couldn't enable device, target resolution will be applied the next time user attempts to start the device
89
- this.logger('warn', 'could not apply target resolution', error);
89
+ this.logger.warn('could not apply target resolution', error);
90
90
  }
91
91
  }
92
92
  if (this.enabled && this.state.mediaStream) {
@@ -98,8 +98,7 @@ export class CameraManager extends DeviceManager<CameraManagerState> {
98
98
  height !== this.targetResolution.height
99
99
  ) {
100
100
  await this.applySettingsToStream();
101
- this.logger(
102
- 'debug',
101
+ this.logger.debug(
103
102
  `${width}x${height} target resolution applied to media stream`,
104
103
  );
105
104
  }
@@ -6,8 +6,7 @@ import { createSubscription } from '../store/rxUtils';
6
6
  import { DeviceManagerState } from './DeviceManagerState';
7
7
  import { isMobile } from '../helpers/compatibility';
8
8
  import { isReactNative } from '../helpers/platforms';
9
- import { Logger } from '../coordinator/connection/types';
10
- import { getLogger } from '../logger';
9
+ import { ScopedLogger, videoLoggerSystem } from '../logger';
11
10
  import { TrackType } from '../gen/video/sfu/models/models';
12
11
  import { deviceIds$ } from './devices';
13
12
  import {
@@ -29,7 +28,7 @@ export abstract class DeviceManager<
29
28
  * if true, stops the media stream when call is left
30
29
  */
31
30
  stopOnLeave = true;
32
- logger: Logger;
31
+ logger: ScopedLogger;
33
32
 
34
33
  state: S;
35
34
 
@@ -48,7 +47,9 @@ export abstract class DeviceManager<
48
47
  this.call = call;
49
48
  this.state = state;
50
49
  this.trackType = trackType;
51
- this.logger = getLogger([`${TrackType[trackType].toLowerCase()} manager`]);
50
+ this.logger = videoLoggerSystem.getLogger(
51
+ `${TrackType[trackType].toLowerCase()} manager`,
52
+ );
52
53
  this.setup();
53
54
  }
54
55
 
@@ -257,6 +258,7 @@ export abstract class DeviceManager<
257
258
  };
258
259
 
259
260
  protected async applySettingsToStream() {
261
+ console.log('applySettingsToStream ');
260
262
  await withCancellation(this.statusChangeConcurrencyTag, async (signal) => {
261
263
  if (this.enabled) {
262
264
  try {
@@ -300,7 +302,7 @@ export abstract class DeviceManager<
300
302
  protected async muteStream(stopTracks: boolean = true) {
301
303
  const mediaStream = this.state.mediaStream;
302
304
  if (!mediaStream) return;
303
- this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
305
+ this.logger.debug(`${stopTracks ? 'Stopping' : 'Disabling'} stream`);
304
306
  if (this.call.state.callingState === CallingState.JOINED) {
305
307
  await this.stopPublishStream();
306
308
  }
@@ -347,7 +349,7 @@ export abstract class DeviceManager<
347
349
  }
348
350
 
349
351
  protected async unmuteStream() {
350
- this.logger('debug', 'Starting stream');
352
+ this.logger.debug('Starting stream');
351
353
  let stream: MediaStream;
352
354
  let rootStream: Promise<MediaStream> | undefined;
353
355
  if (
@@ -435,8 +437,7 @@ export abstract class DeviceManager<
435
437
  return output;
436
438
  })
437
439
  .then(chainWith(parent), (error) => {
438
- this.logger(
439
- 'warn',
440
+ this.logger.warn(
440
441
  'Filter failed to start and will be ignored',
441
442
  error,
442
443
  );
@@ -463,7 +464,7 @@ export abstract class DeviceManager<
463
464
  const createTrackMuteHandler = (muted: boolean) => () => {
464
465
  if (!isMobile() || this.trackType !== TrackType.VIDEO) return;
465
466
  this.call.notifyTrackMuteState(muted, this.trackType).catch((err) => {
466
- this.logger('warn', 'Error while notifying track mute state', err);
467
+ this.logger.warn('Error while notifying track mute state', err);
467
468
  });
468
469
  };
469
470
  stream.getTracks().forEach((track) => {
@@ -534,8 +535,7 @@ export abstract class DeviceManager<
534
535
  }
535
536
  }
536
537
  } catch (err) {
537
- this.logger(
538
- 'warn',
538
+ this.logger.warn(
539
539
  'Unexpected error while handling disconnected or replaced device',
540
540
  err,
541
541
  );
@@ -66,7 +66,7 @@ export class MicrophoneManager extends AudioDeviceManager<MicrophoneManagerState
66
66
  await this.stopSpeakingWhileMutedDetection();
67
67
  }
68
68
  } catch (err) {
69
- this.logger('warn', 'Could not enable speaking while muted', err);
69
+ this.logger.warn('Could not enable speaking while muted', err);
70
70
  }
71
71
  },
72
72
  ),
@@ -96,14 +96,14 @@ export class MicrophoneManager extends AudioDeviceManager<MicrophoneManagerState
96
96
  }
97
97
  })
98
98
  .catch((err) => {
99
- this.logger('warn', `Failed to enable noise cancellation`, err);
99
+ this.logger.warn(`Failed to enable noise cancellation`, err);
100
100
  return this.call.notifyNoiseCancellationStopped();
101
101
  });
102
102
  } else if (callingState === CallingState.LEFT) {
103
103
  this.noiseCancellationRegistration
104
104
  .then(() => this.noiseCancellation?.disable())
105
105
  .catch((err) => {
106
- this.logger('warn', `Failed to disable noise cancellation`, err);
106
+ this.logger.warn(`Failed to disable noise cancellation`, err);
107
107
  });
108
108
  }
109
109
  }),
@@ -141,11 +141,11 @@ export class MicrophoneManager extends AudioDeviceManager<MicrophoneManagerState
141
141
  this.call.tracer.trace('noiseCancellation.enabled', enabled);
142
142
  if (enabled) {
143
143
  this.call.notifyNoiseCancellationStarting().catch((err) => {
144
- this.logger('warn', `notifyNoiseCancellationStart failed`, err);
144
+ this.logger.warn(`notifyNoiseCancellationStart failed`, err);
145
145
  });
146
146
  } else {
147
147
  this.call.notifyNoiseCancellationStopped().catch((err) => {
148
- this.logger('warn', `notifyNoiseCancellationStop failed`, err);
148
+ this.logger.warn(`notifyNoiseCancellationStop failed`, err);
149
149
  });
150
150
  }
151
151
  },
@@ -179,9 +179,9 @@ export class MicrophoneManager extends AudioDeviceManager<MicrophoneManagerState
179
179
  }
180
180
  }
181
181
  } catch (e) {
182
- this.logger('warn', 'Failed to enable noise cancellation', e);
182
+ this.logger.warn('Failed to enable noise cancellation', e);
183
183
  await this.disableNoiseCancellation().catch((err) => {
184
- this.logger('warn', 'Failed to disable noise cancellation', err);
184
+ this.logger.warn('Failed to disable noise cancellation', err);
185
185
  });
186
186
  throw e;
187
187
  }
@@ -195,7 +195,7 @@ export class MicrophoneManager extends AudioDeviceManager<MicrophoneManagerState
195
195
  .then(() => this.noiseCancellation?.disable())
196
196
  .then(() => this.noiseCancellationChangeUnsubscribe?.())
197
197
  .catch((err) => {
198
- this.logger('warn', 'Failed to unregister noise cancellation', err);
198
+ this.logger.warn('Failed to unregister noise cancellation', err);
199
199
  });
200
200
 
201
201
  this.call.tracer.trace('noiseCancellation.disabled', true);
@@ -9,12 +9,12 @@ import {
9
9
  startWith,
10
10
  tap,
11
11
  } from 'rxjs';
12
- import { getLogger } from '../logger';
13
12
  import { BrowserPermission } from './BrowserPermission';
14
13
  import { lazy } from '../helpers/lazy';
15
14
  import { isFirefox } from '../helpers/browsers';
16
15
  import { dumpStream, Tracer } from '../stats';
17
16
  import { getCurrentValue } from '../store/rxUtils';
17
+ import { videoLoggerSystem } from '../logger';
18
18
 
19
19
  /**
20
20
  * Returns an Observable that emits the list of available devices
@@ -266,15 +266,16 @@ export const getAudioStream = async (
266
266
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
267
267
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
268
268
  const { deviceId, ...relaxedConstraints } = trackConstraints;
269
- getLogger(['devices'])(
270
- 'warn',
271
- 'Failed to get audio stream, will try again with relaxed constraints',
272
- { error, constraints, relaxedConstraints },
273
- );
269
+ videoLoggerSystem
270
+ .getLogger('devices')
271
+ .warn(
272
+ 'Failed to get audio stream, will try again with relaxed constraints',
273
+ { error, constraints, relaxedConstraints },
274
+ );
274
275
  return getAudioStream(relaxedConstraints);
275
276
  }
276
277
 
277
- getLogger(['devices'])('error', 'Failed to get audio stream', {
278
+ videoLoggerSystem.getLogger('devices').error('Failed to get audio stream', {
278
279
  error,
279
280
  constraints,
280
281
  });
@@ -310,15 +311,16 @@ export const getVideoStream = async (
310
311
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
311
312
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
312
313
  const { deviceId, ...relaxedConstraints } = trackConstraints;
313
- getLogger(['devices'])(
314
- 'warn',
315
- 'Failed to get video stream, will try again with relaxed constraints',
316
- { error, constraints, relaxedConstraints },
317
- );
314
+ videoLoggerSystem
315
+ .getLogger('devices')
316
+ .warn(
317
+ 'Failed to get video stream, will try again with relaxed constraints',
318
+ { error, constraints, relaxedConstraints },
319
+ );
318
320
  return getVideoStream(relaxedConstraints);
319
321
  }
320
322
 
321
- getLogger(['devices'])('error', 'Failed to get video stream', {
323
+ videoLoggerSystem.getLogger('devices').error('Failed to get video stream', {
322
324
  error,
323
325
  constraints,
324
326
  });
@@ -373,7 +375,9 @@ export const getScreenShareStream = async (
373
375
  return stream;
374
376
  } catch (e) {
375
377
  tracer?.trace(`${tag}OnFailure`, (e as Error).name);
376
- getLogger(['devices'])('error', 'Failed to get screen share stream', e);
378
+ videoLoggerSystem
379
+ .getLogger('devices')
380
+ .error('Failed to get screen share stream', e);
377
381
  throw e;
378
382
  }
379
383
  };
@@ -38,8 +38,7 @@ export const watchCallRejected = (call: Call) => {
38
38
  const { session: callSession } = eventCall;
39
39
 
40
40
  if (!callSession) {
41
- call.logger(
42
- 'warn',
41
+ call.logger.warn(
43
42
  'No call session provided. Ignoring call.rejected event.',
44
43
  event,
45
44
  );
@@ -49,8 +48,7 @@ export const watchCallRejected = (call: Call) => {
49
48
  const rejectedBy = callSession.rejected_by;
50
49
  const { members, callingState } = call.state;
51
50
  if (callingState !== CallingState.RINGING) {
52
- call.logger(
53
- 'info',
51
+ call.logger.info(
54
52
  'Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.',
55
53
  event,
56
54
  );
@@ -61,7 +59,7 @@ export const watchCallRejected = (call: Call) => {
61
59
  .filter((m) => m.user_id !== call.currentUserId)
62
60
  .every((m) => rejectedBy[m.user_id]);
63
61
  if (everyoneElseRejected) {
64
- call.logger('info', 'everyone rejected, leaving the call');
62
+ call.logger.info('everyone rejected, leaving the call');
65
63
  await call.leave({
66
64
  reject: true,
67
65
  reason: 'cancel',
@@ -70,7 +68,7 @@ export const watchCallRejected = (call: Call) => {
70
68
  }
71
69
  } else {
72
70
  if (rejectedBy[eventCall.created_by.id]) {
73
- call.logger('info', 'call creator rejected, leaving call');
71
+ call.logger.info('call creator rejected, leaving call');
74
72
  await call.leave({ message: 'ring: creator rejected' });
75
73
  }
76
74
  }
@@ -90,7 +88,7 @@ export const watchCallEnded = (call: Call) => {
90
88
  call
91
89
  .leave({ message: 'call.ended event received', reject: false })
92
90
  .catch((err) => {
93
- call.logger('error', 'Failed to leave call after call.ended ', err);
91
+ call.logger.error('Failed to leave call after call.ended ', err);
94
92
  });
95
93
  }
96
94
  };
@@ -117,8 +115,7 @@ export const watchSfuCallEnded = (call: Call) => {
117
115
  const reason = CallEndedReason[e.reason];
118
116
  await call.leave({ message: `callEnded received: ${reason}` });
119
117
  } catch (err) {
120
- call.logger(
121
- 'error',
118
+ call.logger.error(
122
119
  'Failed to leave call after being ended by the SFU',
123
120
  err,
124
121
  );
@@ -2,7 +2,6 @@ import { Dispatcher } from '../rtc';
2
2
  import { Call } from '../Call';
3
3
  import { CallState } from '../store';
4
4
  import { StreamVideoParticipantPatches } from '../types';
5
- import { getLogger } from '../logger';
6
5
  import { pushToIfMissing, removeFromIfPresent } from '../helpers/array';
7
6
  import type {
8
7
  InboundStateNotification,
@@ -13,6 +12,7 @@ import {
13
12
  WebsocketReconnectStrategy,
14
13
  } from '../gen/video/sfu/models/models';
15
14
  import { OwnCapability } from '../gen/coordinator';
15
+ import { videoLoggerSystem } from '../logger';
16
16
 
17
17
  export const watchConnectionQualityChanged = (
18
18
  dispatcher: Dispatcher,
@@ -60,7 +60,7 @@ export const watchLiveEnded = (dispatcher: Dispatcher, call: Call) => {
60
60
  call.state.setBackstage(true);
61
61
  if (!call.permissionsContext.hasPermission(OwnCapability.JOIN_BACKSTAGE)) {
62
62
  call.leave({ message: 'live ended' }).catch((err) => {
63
- call.logger('error', 'Failed to leave call after live ended', err);
63
+ call.logger.error('Failed to leave call after live ended', err);
64
64
  });
65
65
  }
66
66
  });
@@ -72,9 +72,9 @@ export const watchLiveEnded = (dispatcher: Dispatcher, call: Call) => {
72
72
  export const watchSfuErrorReports = (dispatcher: Dispatcher) => {
73
73
  return dispatcher.on('error', (e) => {
74
74
  if (!e.error) return;
75
- const logger = getLogger(['SfuClient']);
75
+ const logger = videoLoggerSystem.getLogger('SfuClient');
76
76
  const { error, reconnectStrategy } = e;
77
- logger('error', 'SFU reported error', {
77
+ logger.error('SFU reported error', {
78
78
  code: ErrorCode[error.code],
79
79
  reconnectStrategy: WebsocketReconnectStrategy[reconnectStrategy],
80
80
  message: error.message,