@stream-io/video-client 1.44.3 → 1.44.4

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,14 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.44.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.44.3...@stream-io/video-client-1.44.4) (2026-03-20)
6
+
7
+ - trace device permission state transitions ([#2168](https://github.com/GetStream/stream-video-js/issues/2168)) ([e4203a3](https://github.com/GetStream/stream-video-js/commit/e4203a34cad1c90d1bc5612fc379dd1f0f0ebe5d))
8
+
9
+ ### Bug Fixes
10
+
11
+ - **react:** remove default broken microphone notification from call controls ([#2158](https://github.com/GetStream/stream-video-js/issues/2158)) ([4a95b9c](https://github.com/GetStream/stream-video-js/commit/4a95b9c29e9d2728ae7eea764f07ec8507aa0f5a))
12
+
5
13
  ## [1.44.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.44.2...@stream-io/video-client-1.44.3) (2026-03-06)
6
14
 
7
15
  ### Bug Fixes
@@ -6283,7 +6283,7 @@ const getSdkVersion = (sdk) => {
6283
6283
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
6284
6284
  };
6285
6285
 
6286
- const version = "1.44.3";
6286
+ const version = "1.44.4";
6287
6287
  const [major, minor, patch] = version.split('.');
6288
6288
  let sdkInfo = {
6289
6289
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -10298,6 +10298,9 @@ class BrowserPermission {
10298
10298
  }
10299
10299
  setState(state) {
10300
10300
  if (this.state !== state) {
10301
+ const { tracer, queryName } = this.permission;
10302
+ const traceKey = `navigator.mediaDevices.${queryName}.permission`;
10303
+ tracer?.trace(traceKey, { previous: this.state, state });
10301
10304
  this.state = state;
10302
10305
  this.listeners.forEach((listener) => listener(state));
10303
10306
  }
@@ -10368,17 +10371,19 @@ const videoDeviceConstraints = {
10368
10371
  * Keeps track of the browser permission to use microphone. This permission also
10369
10372
  * affects an ability to enumerate audio devices.
10370
10373
  */
10371
- const getAudioBrowserPermission = lazy(() => new BrowserPermission({
10374
+ const getAudioBrowserPermission = lazy((tracer) => new BrowserPermission({
10372
10375
  constraints: audioDeviceConstraints,
10373
10376
  queryName: 'microphone',
10377
+ tracer,
10374
10378
  }));
10375
10379
  /**
10376
10380
  * Keeps track of the browser permission to use camera. This permission also
10377
10381
  * affects an ability to enumerate video devices.
10378
10382
  */
10379
- const getVideoBrowserPermission = lazy(() => new BrowserPermission({
10383
+ const getVideoBrowserPermission = lazy((tracer) => new BrowserPermission({
10380
10384
  constraints: videoDeviceConstraints,
10381
10385
  queryName: 'camera',
10386
+ tracer,
10382
10387
  }));
10383
10388
  const getDeviceChangeObserver = lazy((tracer) => {
10384
10389
  // 'addEventListener' is not available in React Native, returning
@@ -10394,7 +10399,7 @@ const getDeviceChangeObserver = lazy((tracer) => {
10394
10399
  * the observable errors.
10395
10400
  */
10396
10401
  const getAudioDevices = lazy((tracer) => {
10397
- return merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(startWith([]), concatMap(() => getDevices(getAudioBrowserPermission(), 'audioinput', tracer)), shareReplay(1));
10402
+ return merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(startWith([]), concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audioinput', tracer)), shareReplay(1));
10398
10403
  });
10399
10404
  /**
10400
10405
  * Prompts the user for a permission to use video devices (if not already granted
@@ -10403,7 +10408,7 @@ const getAudioDevices = lazy((tracer) => {
10403
10408
  * the observable errors.
10404
10409
  */
10405
10410
  const getVideoDevices = lazy((tracer) => {
10406
- return merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission().asObservable()).pipe(startWith([]), concatMap(() => getDevices(getVideoBrowserPermission(), 'videoinput', tracer)), shareReplay(1));
10411
+ return merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission(tracer).asObservable()).pipe(startWith([]), concatMap(() => getDevices(getVideoBrowserPermission(tracer), 'videoinput', tracer)), shareReplay(1));
10407
10412
  });
10408
10413
  /**
10409
10414
  * Prompts the user for a permission to use video devices (if not already granted
@@ -10412,7 +10417,7 @@ const getVideoDevices = lazy((tracer) => {
10412
10417
  * the observable errors.
10413
10418
  */
10414
10419
  const getAudioOutputDevices = lazy((tracer) => {
10415
- return merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(startWith([]), concatMap(() => getDevices(getAudioBrowserPermission(), 'audiooutput', tracer)), shareReplay(1));
10420
+ return merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(startWith([]), concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audiooutput', tracer)), shareReplay(1));
10416
10421
  });
10417
10422
  let getUserMediaExecId = 0;
10418
10423
  const getStream = async (constraints, tracer) => {
@@ -10478,25 +10483,21 @@ const getAudioStream = async (trackConstraints, tracer) => {
10478
10483
  },
10479
10484
  };
10480
10485
  try {
10481
- await getAudioBrowserPermission().prompt({
10486
+ await getAudioBrowserPermission(tracer).prompt({
10482
10487
  throwOnNotAllowed: true,
10483
10488
  forcePrompt: true,
10484
10489
  });
10485
10490
  return await getStream(constraints, tracer);
10486
10491
  }
10487
10492
  catch (error) {
10493
+ const logger = videoLoggerSystem.getLogger('devices');
10488
10494
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
10489
10495
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
10490
10496
  const { deviceId, ...relaxedConstraints } = trackConstraints;
10491
- videoLoggerSystem
10492
- .getLogger('devices')
10493
- .warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
10497
+ logger.warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
10494
10498
  return getAudioStream(relaxedConstraints, tracer);
10495
10499
  }
10496
- videoLoggerSystem.getLogger('devices').error('Failed to get audio stream', {
10497
- error,
10498
- constraints,
10499
- });
10500
+ logger.error('Failed to get audio stream', { error, constraints });
10500
10501
  throw error;
10501
10502
  }
10502
10503
  };
@@ -10516,25 +10517,21 @@ const getVideoStream = async (trackConstraints, tracer) => {
10516
10517
  },
10517
10518
  };
10518
10519
  try {
10519
- await getVideoBrowserPermission().prompt({
10520
+ await getVideoBrowserPermission(tracer).prompt({
10520
10521
  throwOnNotAllowed: true,
10521
10522
  forcePrompt: true,
10522
10523
  });
10523
10524
  return await getStream(constraints, tracer);
10524
10525
  }
10525
10526
  catch (error) {
10527
+ const logger = videoLoggerSystem.getLogger('devices');
10526
10528
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
10527
10529
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
10528
10530
  const { deviceId, ...relaxedConstraints } = trackConstraints;
10529
- videoLoggerSystem
10530
- .getLogger('devices')
10531
- .warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
10532
- return getVideoStream(relaxedConstraints);
10531
+ logger.warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
10532
+ return getVideoStream(relaxedConstraints, tracer);
10533
10533
  }
10534
- videoLoggerSystem.getLogger('devices').error('Failed to get video stream', {
10535
- error,
10536
- constraints,
10537
- });
10534
+ logger.error('Failed to get video stream', { error, constraints });
10538
10535
  throw error;
10539
10536
  }
10540
10537
  };
@@ -11305,8 +11302,8 @@ class DeviceManagerState {
11305
11302
  }
11306
11303
 
11307
11304
  class CameraManagerState extends DeviceManagerState {
11308
- constructor() {
11309
- super('stop-tracks', getVideoBrowserPermission());
11305
+ constructor(tracer) {
11306
+ super('stop-tracks', getVideoBrowserPermission(tracer));
11310
11307
  this.directionSubject = new BehaviorSubject(undefined);
11311
11308
  /**
11312
11309
  * Observable that emits the preferred camera direction
@@ -11360,7 +11357,7 @@ class CameraManager extends DeviceManager {
11360
11357
  * @param devicePersistence the device persistence preferences to use.
11361
11358
  */
11362
11359
  constructor(call, devicePersistence) {
11363
- super(call, new CameraManagerState(), TrackType.VIDEO, devicePersistence);
11360
+ super(call, new CameraManagerState(call.tracer), TrackType.VIDEO, devicePersistence);
11364
11361
  this.targetResolution = {
11365
11362
  width: 1280,
11366
11363
  height: 720,
@@ -11571,8 +11568,8 @@ class AudioDeviceManagerState extends DeviceManagerState {
11571
11568
  }
11572
11569
 
11573
11570
  class MicrophoneManagerState extends AudioDeviceManagerState {
11574
- constructor(disableMode) {
11575
- super(disableMode, getAudioBrowserPermission(), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
11571
+ constructor(disableMode, tracer) {
11572
+ super(disableMode, getAudioBrowserPermission(tracer), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
11576
11573
  this.speakingWhileMutedSubject = new BehaviorSubject(false);
11577
11574
  /**
11578
11575
  * An Observable that emits `true` if the user's microphone is muted, but they're speaking.
@@ -11912,7 +11909,7 @@ class RNSpeechDetector {
11912
11909
 
11913
11910
  class MicrophoneManager extends AudioDeviceManager {
11914
11911
  constructor(call, devicePersistence, disableMode = 'stop-tracks') {
11915
- super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO, devicePersistence);
11912
+ super(call, new MicrophoneManagerState(disableMode, call.tracer), TrackType.AUDIO, devicePersistence);
11916
11913
  this.speakingWhileMutedNotificationEnabled = true;
11917
11914
  this.soundDetectorConcurrencyTag = Symbol('soundDetectorConcurrencyTag');
11918
11915
  this.silenceThresholdMs = 5000;
@@ -12014,7 +12011,6 @@ class MicrophoneManager extends AudioDeviceManager {
12014
12011
  deviceId,
12015
12012
  label,
12016
12013
  };
12017
- console.log(event);
12018
12014
  this.call.tracer.trace('mic.capture_report', event);
12019
12015
  this.call.streamClient.dispatchEvent(event);
12020
12016
  },
@@ -15890,7 +15886,7 @@ class StreamClient {
15890
15886
  this.getUserAgent = () => {
15891
15887
  if (!this.cachedUserAgent) {
15892
15888
  const { clientAppIdentifier = {} } = this.options;
15893
- const { sdkName = 'js', sdkVersion = "1.44.3", ...extras } = clientAppIdentifier;
15889
+ const { sdkName = 'js', sdkVersion = "1.44.4", ...extras } = clientAppIdentifier;
15894
15890
  this.cachedUserAgent = [
15895
15891
  `stream-video-${sdkName}-v${sdkVersion}`,
15896
15892
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),