@stream-io/video-client 1.41.3 → 1.42.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.
package/dist/index.es.js CHANGED
@@ -4790,7 +4790,7 @@ const hasVideo = (p) => p.publishedTracks.includes(TrackType.VIDEO);
4790
4790
  *
4791
4791
  * @param p the participant to check.
4792
4792
  */
4793
- const hasAudio = (p) => p.publishedTracks.includes(TrackType.AUDIO);
4793
+ const hasAudio$1 = (p) => p.publishedTracks.includes(TrackType.AUDIO);
4794
4794
  /**
4795
4795
  * Check if a participant is screen sharing.
4796
4796
  *
@@ -4891,8 +4891,8 @@ const publishingVideo = (a, b) => {
4891
4891
  * @param b the second participant.
4892
4892
  */
4893
4893
  const publishingAudio = (a, b) => {
4894
- const hasA = hasAudio(a);
4895
- const hasB = hasAudio(b);
4894
+ const hasA = hasAudio$1(a);
4895
+ const hasB = hasAudio$1(b);
4896
4896
  if (hasA && !hasB)
4897
4897
  return -1;
4898
4898
  if (!hasA && hasB)
@@ -6189,7 +6189,7 @@ const getSdkVersion = (sdk) => {
6189
6189
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
6190
6190
  };
6191
6191
 
6192
- const version = "1.41.3";
6192
+ const version = "1.42.1";
6193
6193
  const [major, minor, patch] = version.split('.');
6194
6194
  let sdkInfo = {
6195
6195
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -10380,7 +10380,7 @@ const getAudioStream = async (trackConstraints, tracer) => {
10380
10380
  videoLoggerSystem
10381
10381
  .getLogger('devices')
10382
10382
  .warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
10383
- return getAudioStream(relaxedConstraints);
10383
+ return getAudioStream(relaxedConstraints, tracer);
10384
10384
  }
10385
10385
  videoLoggerSystem.getLogger('devices').error('Failed to get audio stream', {
10386
10386
  error,
@@ -11377,9 +11377,6 @@ class MicrophoneManagerState extends AudioDeviceManagerState {
11377
11377
  }
11378
11378
  }
11379
11379
 
11380
- const DETECTION_FREQUENCY_IN_MS = 500;
11381
- const AUDIO_LEVEL_THRESHOLD = 150;
11382
- const FFT_SIZE = 128;
11383
11380
  /**
11384
11381
  * Creates a new sound detector.
11385
11382
  *
@@ -11389,7 +11386,7 @@ const FFT_SIZE = 128;
11389
11386
  * @returns a clean-up function which once invoked stops the sound detector.
11390
11387
  */
11391
11388
  const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options = {}) => {
11392
- const { detectionFrequencyInMs = DETECTION_FREQUENCY_IN_MS, audioLevelThreshold = AUDIO_LEVEL_THRESHOLD, fftSize = FFT_SIZE, destroyStreamOnStop = true, } = options;
11389
+ const { detectionFrequencyInMs = 500, audioLevelThreshold = 150, fftSize = 128, destroyStreamOnStop = true, } = options;
11393
11390
  const audioContext = new AudioContext();
11394
11391
  const analyser = audioContext.createAnalyser();
11395
11392
  analyser.fftSize = fftSize;
@@ -11430,6 +11427,101 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
11430
11427
  };
11431
11428
  };
11432
11429
 
11430
+ /**
11431
+ * Analyzes frequency data to determine if audio is being captured.
11432
+ */
11433
+ const hasAudio = (analyser, threshold) => {
11434
+ const data = new Uint8Array(analyser.frequencyBinCount);
11435
+ analyser.getByteFrequencyData(data);
11436
+ return data.some((value) => value > threshold);
11437
+ };
11438
+ /** Helper for "no event" transitions */
11439
+ const noEmit = (nextState) => ({
11440
+ shouldEmit: false,
11441
+ nextState,
11442
+ });
11443
+ /** Helper for event-emitting transitions */
11444
+ const emit = (capturesAudio, nextState) => ({ shouldEmit: true, nextState, capturesAudio });
11445
+ /**
11446
+ * State transition function - computes next state and whether to emit an event.
11447
+ */
11448
+ const transitionState = (state, audioDetected, options) => {
11449
+ if (audioDetected) {
11450
+ return state.kind === 'IDLE' || state.kind === 'EMITTING'
11451
+ ? emit(true, state)
11452
+ : noEmit(state);
11453
+ }
11454
+ const { noAudioThresholdMs, emitIntervalMs } = options;
11455
+ const now = Date.now();
11456
+ switch (state.kind) {
11457
+ case 'IDLE':
11458
+ return noEmit({ kind: 'DETECTING', noAudioStartTime: now });
11459
+ case 'DETECTING': {
11460
+ const { noAudioStartTime } = state;
11461
+ const elapsed = now - noAudioStartTime;
11462
+ return elapsed >= noAudioThresholdMs
11463
+ ? emit(false, { kind: 'EMITTING', noAudioStartTime, lastEmitTime: now })
11464
+ : noEmit(state);
11465
+ }
11466
+ case 'EMITTING': {
11467
+ const timeSinceLastEmit = now - state.lastEmitTime;
11468
+ return timeSinceLastEmit >= emitIntervalMs
11469
+ ? emit(false, { ...state, lastEmitTime: now })
11470
+ : noEmit(state);
11471
+ }
11472
+ }
11473
+ };
11474
+ /**
11475
+ * Creates and configures an audio analyzer for the given stream.
11476
+ */
11477
+ const createAudioAnalyzer = (audioStream, fftSize) => {
11478
+ const audioContext = new AudioContext();
11479
+ const analyser = audioContext.createAnalyser();
11480
+ analyser.fftSize = fftSize;
11481
+ const microphone = audioContext.createMediaStreamSource(audioStream);
11482
+ microphone.connect(analyser);
11483
+ return { audioContext, analyser };
11484
+ };
11485
+ /**
11486
+ * Creates a new no-audio detector that monitors continuous absence of audio on an audio stream.
11487
+ *
11488
+ * @param audioStream the audio stream to observe.
11489
+ * @param options custom options for the no-audio detector.
11490
+ * @returns a cleanup function which once invoked stops the no-audio detector.
11491
+ */
11492
+ const createNoAudioDetector = (audioStream, options) => {
11493
+ const { detectionFrequencyInMs = 350, audioLevelThreshold = 0, fftSize = 256, onCaptureStatusChange, } = options;
11494
+ let state = { kind: 'IDLE' };
11495
+ const { audioContext, analyser } = createAudioAnalyzer(audioStream, fftSize);
11496
+ const detectionIntervalId = setInterval(() => {
11497
+ const [audioTrack] = audioStream.getAudioTracks();
11498
+ if (!audioTrack?.enabled || audioTrack.readyState === 'ended') {
11499
+ state = { kind: 'IDLE' };
11500
+ return;
11501
+ }
11502
+ const audioDetected = hasAudio(analyser, audioLevelThreshold);
11503
+ const transition = transitionState(state, audioDetected, options);
11504
+ state = transition.nextState;
11505
+ if (!transition.shouldEmit)
11506
+ return;
11507
+ const { capturesAudio } = transition;
11508
+ onCaptureStatusChange(capturesAudio);
11509
+ if (capturesAudio) {
11510
+ stop().catch((err) => {
11511
+ const logger = videoLoggerSystem.getLogger('NoAudioDetector');
11512
+ logger.error('Error stopping no-audio detector', err);
11513
+ });
11514
+ }
11515
+ }, detectionFrequencyInMs);
11516
+ async function stop() {
11517
+ clearInterval(detectionIntervalId);
11518
+ if (audioContext.state !== 'closed') {
11519
+ await audioContext.close();
11520
+ }
11521
+ }
11522
+ return stop;
11523
+ };
11524
+
11433
11525
  class RNSpeechDetector {
11434
11526
  constructor(externalAudioStream) {
11435
11527
  this.pc1 = new RTCPeerConnection({});
@@ -11441,16 +11533,10 @@ class RNSpeechDetector {
11441
11533
  */
11442
11534
  async start(onSoundDetectedStateChanged) {
11443
11535
  try {
11444
- let audioStream;
11445
- if (this.externalAudioStream != null) {
11446
- audioStream = this.externalAudioStream;
11447
- }
11448
- else {
11449
- audioStream = await navigator.mediaDevices.getUserMedia({
11450
- audio: true,
11451
- });
11452
- this.audioStream = audioStream;
11453
- }
11536
+ const audioStream = this.externalAudioStream != null
11537
+ ? this.externalAudioStream
11538
+ : await navigator.mediaDevices.getUserMedia({ audio: true });
11539
+ this.audioStream = audioStream;
11454
11540
  this.pc1.addEventListener('icecandidate', async (e) => {
11455
11541
  await this.pc2.addIceCandidate(e.candidate);
11456
11542
  });
@@ -11474,9 +11560,9 @@ class RNSpeechDetector {
11474
11560
  const answer = await this.pc2.createAnswer();
11475
11561
  await this.pc1.setRemoteDescription(answer);
11476
11562
  await this.pc2.setLocalDescription(answer);
11477
- const unsub = this.onSpeakingDetectedStateChange(onSoundDetectedStateChanged);
11563
+ const unsubscribe = this.onSpeakingDetectedStateChange(onSoundDetectedStateChanged);
11478
11564
  return () => {
11479
- unsub();
11565
+ unsubscribe();
11480
11566
  this.stop();
11481
11567
  };
11482
11568
  }
@@ -11516,7 +11602,7 @@ class RNSpeechDetector {
11516
11602
  const silenceTimeout = 5000; // Reset baseline after 5 seconds of silence
11517
11603
  const checkAudioLevel = async () => {
11518
11604
  try {
11519
- const stats = (await this.pc1.getStats());
11605
+ const stats = await this.pc1.getStats();
11520
11606
  const report = flatten(stats);
11521
11607
  // Audio levels are present inside stats of type `media-source` and of kind `audio`
11522
11608
  const audioMediaSourceStats = report.find((stat) => stat.type === 'media-source' &&
@@ -11570,8 +11656,7 @@ class RNSpeechDetector {
11570
11656
  logger.error('error checking audio level from stats', error);
11571
11657
  }
11572
11658
  };
11573
- // Call checkAudioLevel periodically (every 100ms)
11574
- const intervalId = setInterval(checkAudioLevel, 100);
11659
+ const intervalId = setInterval(checkAudioLevel, 250);
11575
11660
  return () => {
11576
11661
  clearInterval(intervalId);
11577
11662
  clearTimeout(speechTimer);
@@ -11597,15 +11682,19 @@ class MicrophoneManager extends AudioDeviceManager {
11597
11682
  super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO);
11598
11683
  this.speakingWhileMutedNotificationEnabled = true;
11599
11684
  this.soundDetectorConcurrencyTag = Symbol('soundDetectorConcurrencyTag');
11685
+ this.silenceThresholdMs = 5000;
11600
11686
  }
11601
11687
  setup() {
11688
+ if (this.areSubscriptionsSetUp)
11689
+ return;
11602
11690
  super.setup();
11603
11691
  this.subscriptions.push(createSafeAsyncSubscription(combineLatest([
11604
11692
  this.call.state.callingState$,
11605
11693
  this.call.state.ownCapabilities$,
11606
11694
  this.state.selectedDevice$,
11607
11695
  this.state.status$,
11608
- ]), async ([callingState, ownCapabilities, deviceId, status]) => {
11696
+ this.state.browserPermissionState$,
11697
+ ]), async ([callingState, ownCapabilities, deviceId, status, permissionState,]) => {
11609
11698
  try {
11610
11699
  if (callingState === CallingState.LEFT) {
11611
11700
  await this.stopSpeakingWhileMutedDetection();
@@ -11615,7 +11704,8 @@ class MicrophoneManager extends AudioDeviceManager {
11615
11704
  if (!this.speakingWhileMutedNotificationEnabled)
11616
11705
  return;
11617
11706
  if (ownCapabilities.includes(OwnCapability.SEND_AUDIO)) {
11618
- if (status === 'disabled') {
11707
+ const hasPermission = await this.hasPermission(permissionState);
11708
+ if (hasPermission && status !== 'enabled') {
11619
11709
  await this.startSpeakingWhileMutedDetection(deviceId);
11620
11710
  }
11621
11711
  else {
@@ -11664,6 +11754,40 @@ class MicrophoneManager extends AudioDeviceManager {
11664
11754
  });
11665
11755
  }
11666
11756
  }));
11757
+ if (!isReactNative()) {
11758
+ const unsubscribe = createSafeAsyncSubscription(combineLatest([this.state.status$, this.state.mediaStream$]), async ([status, mediaStream]) => {
11759
+ if (this.noAudioDetectorCleanup) {
11760
+ const cleanup = this.noAudioDetectorCleanup;
11761
+ this.noAudioDetectorCleanup = undefined;
11762
+ await cleanup().catch((err) => {
11763
+ this.logger.warn('Failed to stop no-audio detector', err);
11764
+ });
11765
+ }
11766
+ if (status !== 'enabled' || !mediaStream)
11767
+ return;
11768
+ if (this.silenceThresholdMs <= 0)
11769
+ return;
11770
+ const deviceId = this.state.selectedDevice;
11771
+ const devices = getCurrentValue(this.listDevices());
11772
+ const label = devices.find((d) => d.deviceId === deviceId)?.label;
11773
+ this.noAudioDetectorCleanup = createNoAudioDetector(mediaStream, {
11774
+ noAudioThresholdMs: this.silenceThresholdMs,
11775
+ emitIntervalMs: this.silenceThresholdMs,
11776
+ onCaptureStatusChange: (capturesAudio) => {
11777
+ const event = {
11778
+ type: 'mic.capture_report',
11779
+ call_cid: this.call.cid,
11780
+ capturesAudio,
11781
+ deviceId,
11782
+ label,
11783
+ };
11784
+ this.call.tracer.trace('mic.capture_report', event);
11785
+ this.call.streamClient.dispatchEvent(event);
11786
+ },
11787
+ });
11788
+ });
11789
+ this.subscriptions.push(unsubscribe);
11790
+ }
11667
11791
  }
11668
11792
  /**
11669
11793
  * Enables noise cancellation for the microphone.
@@ -11761,6 +11885,45 @@ class MicrophoneManager extends AudioDeviceManager {
11761
11885
  this.speakingWhileMutedNotificationEnabled = false;
11762
11886
  await this.stopSpeakingWhileMutedDetection();
11763
11887
  }
11888
+ /**
11889
+ * Sets the silence threshold in milliseconds for no-audio detection.
11890
+ * When the microphone is enabled but produces no audio for this duration,
11891
+ * a 'mic.capture_report' event will be emitted.
11892
+ *
11893
+ * @param thresholdMs the threshold in milliseconds (default: 5000).
11894
+ * Set to 0 or a negative value to disable no-audio detection.
11895
+ */
11896
+ setSilenceThreshold(thresholdMs) {
11897
+ this.silenceThresholdMs = thresholdMs;
11898
+ }
11899
+ /**
11900
+ * Performs audio capture test on a specific microphone.
11901
+ *
11902
+ * This method is only available in browser environments (not React Native).
11903
+ *
11904
+ * @param deviceId The device ID to test.
11905
+ * @param options Optional test configuration.
11906
+ * @returns Promise that resolves with the test result (true or false).
11907
+ */
11908
+ async performTest(deviceId, options) {
11909
+ if (isReactNative())
11910
+ throw new Error('Not available in React Native');
11911
+ const stream = await this.getStream({ deviceId: { exact: deviceId } });
11912
+ const { testDurationMs = 3000 } = options || {};
11913
+ const { promise, resolve } = promiseWithResolvers();
11914
+ const cleanup = createNoAudioDetector(stream, {
11915
+ noAudioThresholdMs: testDurationMs,
11916
+ emitIntervalMs: testDurationMs,
11917
+ onCaptureStatusChange: async (capturesAudio) => {
11918
+ resolve(capturesAudio);
11919
+ await cleanup().catch((err) => {
11920
+ this.logger.warn('Failed to stop detector during test', err);
11921
+ });
11922
+ disposeOfMediaStream(stream);
11923
+ },
11924
+ });
11925
+ return promise;
11926
+ }
11764
11927
  /**
11765
11928
  * Applies the audio settings to the microphone.
11766
11929
  * @param settings the audio settings to apply.
@@ -11809,13 +11972,12 @@ class MicrophoneManager extends AudioDeviceManager {
11809
11972
  }
11810
11973
  async startSpeakingWhileMutedDetection(deviceId) {
11811
11974
  await withoutConcurrency(this.soundDetectorConcurrencyTag, async () => {
11812
- await this.stopSpeakingWhileMutedDetection();
11813
11975
  if (isReactNative()) {
11814
11976
  this.rnSpeechDetector = new RNSpeechDetector();
11815
11977
  const unsubscribe = await this.rnSpeechDetector.start((event) => {
11816
11978
  this.state.setSpeakingWhileMuted(event.isSoundDetected);
11817
11979
  });
11818
- this.soundDetectorCleanup = () => {
11980
+ this.soundDetectorCleanup = async () => {
11819
11981
  unsubscribe();
11820
11982
  this.rnSpeechDetector = undefined;
11821
11983
  };
@@ -11823,6 +11985,7 @@ class MicrophoneManager extends AudioDeviceManager {
11823
11985
  else {
11824
11986
  // Need to start a new stream that's not connected to publisher
11825
11987
  const stream = await this.getStream({
11988
+ ...this.state.defaultConstraints,
11826
11989
  deviceId: { exact: deviceId },
11827
11990
  });
11828
11991
  this.soundDetectorCleanup = createSoundDetector(stream, (event) => {
@@ -11841,6 +12004,20 @@ class MicrophoneManager extends AudioDeviceManager {
11841
12004
  await soundDetectorCleanup();
11842
12005
  });
11843
12006
  }
12007
+ async hasPermission(permissionState) {
12008
+ if (!isReactNative())
12009
+ return permissionState === 'granted';
12010
+ const nativePermissions = globalThis.streamRNVideoSDK?.permissions;
12011
+ if (!nativePermissions)
12012
+ return true; // assume granted
12013
+ try {
12014
+ return await nativePermissions.check('microphone');
12015
+ }
12016
+ catch (err) {
12017
+ this.logger.warn('Failed to check permission', err);
12018
+ return false;
12019
+ }
12020
+ }
11844
12021
  }
11845
12022
 
11846
12023
  class ScreenShareState extends AudioDeviceManagerState {
@@ -11902,6 +12079,8 @@ class ScreenShareManager extends AudioDeviceManager {
11902
12079
  super(call, new ScreenShareState(), TrackType.SCREEN_SHARE);
11903
12080
  }
11904
12081
  setup() {
12082
+ if (this.areSubscriptionsSetUp)
12083
+ return;
11905
12084
  super.setup();
11906
12085
  this.subscriptions.push(createSubscription(this.call.state.settings$, (settings) => {
11907
12086
  const maybeTargetResolution = settings?.screensharing.target_resolution;
@@ -12248,6 +12427,9 @@ class Call {
12248
12427
  this.leaveCallHooks.add(registerEventHandlers(this, this.dispatcher));
12249
12428
  this.registerEffects();
12250
12429
  this.registerReconnectHandlers();
12430
+ // Set up the device managers again. Although this is already done
12431
+ // in the DeviceManager's constructor, they'll need to be re-set up
12432
+ // in the cases where a call instance is recycled (join -> leave -> join).
12251
12433
  this.camera.setup();
12252
12434
  this.microphone.setup();
12253
12435
  this.screenShare.setup();
@@ -15345,7 +15527,7 @@ class StreamClient {
15345
15527
  this.getUserAgent = () => {
15346
15528
  if (!this.cachedUserAgent) {
15347
15529
  const { clientAppIdentifier = {} } = this.options;
15348
- const { sdkName = 'js', sdkVersion = "1.41.3", ...extras } = clientAppIdentifier;
15530
+ const { sdkName = 'js', sdkVersion = "1.42.1", ...extras } = clientAppIdentifier;
15349
15531
  this.cachedUserAgent = [
15350
15532
  `stream-video-${sdkName}-v${sdkVersion}`,
15351
15533
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
@@ -15981,5 +16163,5 @@ const humanize = (n) => {
15981
16163
  return String(n);
15982
16164
  };
15983
16165
 
15984
- export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallRecordingFailedEventRecordingTypeEnum, CallRecordingReadyEventRecordingTypeEnum, CallRecordingStartedEventRecordingTypeEnum, CallRecordingStoppedEventRecordingTypeEnum, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DeviceManager, DeviceManagerState, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, IndividualRecordingSettingsRequestModeEnum, IndividualRecordingSettingsResponseModeEnum, IngressAudioEncodingOptionsRequestChannelsEnum, IngressSourceRequestFpsEnum, IngressVideoLayerRequestCodecEnum, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RawRecordingSettingsRequestModeEnum, RawRecordingSettingsResponseModeEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, SfuJoinError, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoWriteableStateStore, TranscriptionSettingsRequestClosedCaptionModeEnum, TranscriptionSettingsRequestLanguageEnum, TranscriptionSettingsRequestModeEnum, TranscriptionSettingsResponseClosedCaptionModeEnum, TranscriptionSettingsResponseLanguageEnum, TranscriptionSettingsResponseModeEnum, VideoSettingsRequestCameraFacingEnum, VideoSettingsResponseCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, deviceIds$, disposeOfMediaStream, dominantSpeaker, getAudioBrowserPermission, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceState, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, humanize, isPinned, livestreamOrAudioRoomSortPreset, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking, videoLoggerSystem, withParticipantSource };
16166
+ export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallRecordingFailedEventRecordingTypeEnum, CallRecordingReadyEventRecordingTypeEnum, CallRecordingStartedEventRecordingTypeEnum, CallRecordingStoppedEventRecordingTypeEnum, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DeviceManager, DeviceManagerState, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, IndividualRecordingSettingsRequestModeEnum, IndividualRecordingSettingsResponseModeEnum, IngressAudioEncodingOptionsRequestChannelsEnum, IngressSourceRequestFpsEnum, IngressVideoLayerRequestCodecEnum, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RawRecordingSettingsRequestModeEnum, RawRecordingSettingsResponseModeEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, SfuJoinError, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoWriteableStateStore, TranscriptionSettingsRequestClosedCaptionModeEnum, TranscriptionSettingsRequestLanguageEnum, TranscriptionSettingsRequestModeEnum, TranscriptionSettingsResponseClosedCaptionModeEnum, TranscriptionSettingsResponseLanguageEnum, TranscriptionSettingsResponseModeEnum, VideoSettingsRequestCameraFacingEnum, VideoSettingsResponseCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, deviceIds$, disposeOfMediaStream, dominantSpeaker, getAudioBrowserPermission, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceState, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio$1 as hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, humanize, isPinned, livestreamOrAudioRoomSortPreset, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking, videoLoggerSystem, withParticipantSource };
15985
16167
  //# sourceMappingURL=index.es.js.map