@stream-io/video-client 1.22.2 → 1.23.0

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.23.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.22.2...@stream-io/video-client-1.23.0) (2025-05-20)
6
+
7
+ ### Features
8
+
9
+ - **react-native:** Noise Cancellation ([#1793](https://github.com/GetStream/stream-video-js/issues/1793)) ([d7843e1](https://github.com/GetStream/stream-video-js/commit/d7843e1a23e6f6a35d1c159438d09bdfd17450a5))
10
+ - **web:** improved noise cancellation ([#1794](https://github.com/GetStream/stream-video-js/issues/1794)) ([d59f19b](https://github.com/GetStream/stream-video-js/commit/d59f19b1ba1ff83fe5f024d783b868f4e98d3380))
11
+
12
+ ### Bug Fixes
13
+
14
+ - do not mutate filters array during pipeline setup ([#1798](https://github.com/GetStream/stream-video-js/issues/1798)) ([e9832e5](https://github.com/GetStream/stream-video-js/commit/e9832e5ef41b3f6cddfe2d0cb2cf840e9b28bb86))
15
+
5
16
  ## [1.22.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.22.1...@stream-io/video-client-1.22.2) (2025-05-15)
6
17
 
7
18
  - adjust ErrorFromResponse class ([#1791](https://github.com/GetStream/stream-video-js/issues/1791)) ([c0abcba](https://github.com/GetStream/stream-video-js/commit/c0abcbacfddeb87d8378c4418f80e6770981cdc8)), closes [GetStream/chat#1540](https://github.com/GetStream/chat/issues/1540)
@@ -5680,7 +5680,7 @@ const aggregate = (stats) => {
5680
5680
  return report;
5681
5681
  };
5682
5682
 
5683
- const version = "1.22.2";
5683
+ const version = "1.23.0";
5684
5684
  const [major, minor, patch] = version.split('.');
5685
5685
  let sdkInfo = {
5686
5686
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -9461,13 +9461,16 @@ class InputMediaDeviceManager {
9461
9461
  start: filter,
9462
9462
  stop: undefined,
9463
9463
  };
9464
+ this.call.tracer.trace(`registerFilter.${TrackType[this.trackType]}`, null);
9464
9465
  const registered = withoutConcurrency(this.filterRegistrationConcurrencyTag, async () => {
9466
+ await settled(this.statusChangeConcurrencyTag);
9465
9467
  this.filters.push(entry);
9466
9468
  await this.applySettingsToStream();
9467
9469
  });
9468
9470
  return {
9469
9471
  registered,
9470
9472
  unregister: () => withoutConcurrency(this.filterRegistrationConcurrencyTag, async () => {
9473
+ await settled(this.statusChangeConcurrencyTag);
9471
9474
  entry.stop?.();
9472
9475
  this.filters = this.filters.filter((f) => f !== entry);
9473
9476
  await this.applySettingsToStream();
@@ -10338,7 +10341,17 @@ class MicrophoneManager extends InputMediaDeviceManager {
10338
10341
  NoiseCancellationSettingsModeEnum.AUTO_ON;
10339
10342
  if (autoOn && callingState === CallingState.JOINED) {
10340
10343
  this.noiseCancellationRegistration
10341
- .then(() => this.noiseCancellation?.enable())
10344
+ .then(() => {
10345
+ if (this.noiseCancellation?.canAutoEnable) {
10346
+ return this.noiseCancellation.canAutoEnable();
10347
+ }
10348
+ return true;
10349
+ })
10350
+ .then((canAutoEnable) => {
10351
+ if (canAutoEnable) {
10352
+ this.noiseCancellation?.enable();
10353
+ }
10354
+ })
10342
10355
  .catch((err) => {
10343
10356
  this.logger('warn', `Failed to enable noise cancellation`, err);
10344
10357
  return this.call.notifyNoiseCancellationStopped();
@@ -10356,13 +10369,9 @@ class MicrophoneManager extends InputMediaDeviceManager {
10356
10369
  /**
10357
10370
  * Enables noise cancellation for the microphone.
10358
10371
  *
10359
- * Note: not supported in React Native.
10360
10372
  * @param noiseCancellation - a noise cancellation instance to use.
10361
10373
  */
10362
10374
  async enableNoiseCancellation(noiseCancellation) {
10363
- if (isReactNative()) {
10364
- throw new Error('Noise cancellation is not supported in React Native');
10365
- }
10366
10375
  const { ownCapabilities, settings } = this.call.state;
10367
10376
  const hasNoiseCancellationCapability = ownCapabilities.includes(OwnCapability.ENABLE_NOISE_CANCELLATION);
10368
10377
  if (!hasNoiseCancellationCapability) {
@@ -10378,6 +10387,7 @@ class MicrophoneManager extends InputMediaDeviceManager {
10378
10387
  this.noiseCancellation = noiseCancellation;
10379
10388
  // listen for change events and notify the SFU
10380
10389
  this.noiseCancellationChangeUnsubscribe = this.noiseCancellation.on('change', (enabled) => {
10390
+ this.call.tracer.trace('noiseCancellation.enabled', enabled);
10381
10391
  if (enabled) {
10382
10392
  this.call.notifyNoiseCancellationStarting().catch((err) => {
10383
10393
  this.logger('warn', `notifyNoiseCancellationStart failed`, err);
@@ -10389,16 +10399,37 @@ class MicrophoneManager extends InputMediaDeviceManager {
10389
10399
  });
10390
10400
  }
10391
10401
  });
10392
- const registrationResult = this.registerFilter(noiseCancellation.toFilter());
10393
- this.noiseCancellationRegistration = registrationResult.registered;
10394
- this.unregisterNoiseCancellation = registrationResult.unregister;
10395
- await this.noiseCancellationRegistration;
10402
+ if (isReactNative()) {
10403
+ // no filter registration in React Native, its done in the native code on app init
10404
+ this.noiseCancellationRegistration = Promise.resolve();
10405
+ }
10406
+ else {
10407
+ // Krisp recommends disabling the browser's built-in noise cancellation
10408
+ // and echo cancellation when using Krisp, so we do that here.
10409
+ // https://sdk-docs.krisp.ai/docs/getting-started-js
10410
+ this.setDefaultConstraints({
10411
+ ...this.state.defaultConstraints,
10412
+ echoCancellation: false,
10413
+ noiseSuppression: false,
10414
+ autoGainControl: false,
10415
+ });
10416
+ const registrationResult = this.registerFilter(noiseCancellation.toFilter());
10417
+ this.noiseCancellationRegistration = registrationResult.registered;
10418
+ this.unregisterNoiseCancellation = registrationResult.unregister;
10419
+ await this.noiseCancellationRegistration;
10420
+ }
10396
10421
  // handles an edge case where a noise cancellation is enabled after
10397
10422
  // the participant as joined the call -> we immediately enable NC
10398
10423
  if (noiseCancellationSettings.mode ===
10399
10424
  NoiseCancellationSettingsModeEnum.AUTO_ON &&
10400
10425
  this.call.state.callingState === CallingState.JOINED) {
10401
- noiseCancellation.enable();
10426
+ let canAutoEnable = true;
10427
+ if (noiseCancellation.canAutoEnable) {
10428
+ canAutoEnable = await noiseCancellation.canAutoEnable();
10429
+ }
10430
+ if (canAutoEnable) {
10431
+ noiseCancellation.enable();
10432
+ }
10402
10433
  }
10403
10434
  }
10404
10435
  catch (e) {
@@ -10410,13 +10441,8 @@ class MicrophoneManager extends InputMediaDeviceManager {
10410
10441
  }
10411
10442
  /**
10412
10443
  * Disables noise cancellation for the microphone.
10413
- *
10414
- * Note: not supported in React Native.
10415
10444
  */
10416
10445
  async disableNoiseCancellation() {
10417
- if (isReactNative()) {
10418
- throw new Error('Noise cancellation is not supported in React Native');
10419
- }
10420
10446
  await (this.unregisterNoiseCancellation?.() ?? Promise.resolve())
10421
10447
  .then(() => this.noiseCancellation?.disable())
10422
10448
  .then(() => this.noiseCancellationChangeUnsubscribe?.())
@@ -13770,7 +13796,7 @@ class StreamClient {
13770
13796
  this.getUserAgent = () => {
13771
13797
  if (!this.cachedUserAgent) {
13772
13798
  const { clientAppIdentifier = {} } = this.options;
13773
- const { sdkName = 'js', sdkVersion = "1.22.2", ...extras } = clientAppIdentifier;
13799
+ const { sdkName = 'js', sdkVersion = "1.23.0", ...extras } = clientAppIdentifier;
13774
13800
  this.cachedUserAgent = [
13775
13801
  `stream-video-${sdkName}-v${sdkVersion}`,
13776
13802
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),