@rapidaai/react 1.1.50 → 1.1.51

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.
@@ -27311,6 +27311,9 @@ import moment from "moment";
27311
27311
  function isSafari() {
27312
27312
  return getBrowser()?.name === "Safari";
27313
27313
  }
27314
+ function isChrome() {
27315
+ return getBrowser()?.name === "Chrome";
27316
+ }
27314
27317
  function toDate(timestamp) {
27315
27318
  const seconds = timestamp.getSeconds();
27316
27319
  const nanos = timestamp.getNanos();
@@ -29020,6 +29023,24 @@ registerProcessor("raw-audio-processor", RawAudioProcessor);
29020
29023
 
29021
29024
  // src/audio/input.ts
29022
29025
  var LIBSAMPLERATE_JS = "https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js";
29026
+ function getAudioConstraints(sampleRate) {
29027
+ if (isChrome()) {
29028
+ return {
29029
+ sampleRate: { ideal: sampleRate },
29030
+ echoCancellation: true,
29031
+ noiseSuppression: true,
29032
+ autoGainControl: true,
29033
+ // Chrome-specific: helps with consistent audio quality
29034
+ channelCount: { ideal: 1 }
29035
+ };
29036
+ }
29037
+ return {
29038
+ sampleRate: { ideal: sampleRate },
29039
+ echoCancellation: { ideal: true },
29040
+ noiseSuppression: { ideal: true },
29041
+ autoGainControl: { ideal: true }
29042
+ };
29043
+ }
29023
29044
  var Input = class _Input {
29024
29045
  constructor(context, analyser, worklet, inputStream) {
29025
29046
  this.context = context;
@@ -29027,18 +29048,10 @@ var Input = class _Input {
29027
29048
  this.worklet = worklet;
29028
29049
  this.inputStream = inputStream;
29029
29050
  }
29030
- static async create({
29031
- sampleRate,
29032
- format
29033
- }) {
29051
+ static async create({ sampleRate, format }, existingStream) {
29034
29052
  let context = null;
29035
29053
  let inputStream = null;
29036
29054
  try {
29037
- const options = {
29038
- sampleRate: { ideal: sampleRate },
29039
- echoCancellation: { ideal: true },
29040
- noiseSuppression: { ideal: true }
29041
- };
29042
29055
  const supportsSampleRateConstraint = navigator.mediaDevices.getSupportedConstraints().sampleRate;
29043
29056
  context = new window.AudioContext(
29044
29057
  supportsSampleRateConstraint ? { sampleRate } : {}
@@ -29048,9 +29061,14 @@ var Input = class _Input {
29048
29061
  await context.audioWorklet.addModule(LIBSAMPLERATE_JS);
29049
29062
  }
29050
29063
  await loadRawAudioProcessor(context.audioWorklet);
29051
- inputStream = await navigator.mediaDevices.getUserMedia({
29052
- audio: options
29053
- });
29064
+ if (existingStream) {
29065
+ inputStream = existingStream;
29066
+ } else {
29067
+ const options = getAudioConstraints(sampleRate);
29068
+ inputStream = await navigator.mediaDevices.getUserMedia({
29069
+ audio: options
29070
+ });
29071
+ }
29054
29072
  const source = context.createMediaStreamSource(inputStream);
29055
29073
  const worklet = new AudioWorkletNode(context, "raw-audio-processor");
29056
29074
  worklet.port.postMessage({ type: "setFormat", format, sampleRate });
@@ -29303,13 +29321,14 @@ var VoiceAgent = class extends Agent {
29303
29321
  connectDevice = async () => {
29304
29322
  try {
29305
29323
  this.preliminaryInputStream = await this.waitForUserMediaPermission();
29306
- [this.input, this.output] = await Promise.all([
29307
- Input.create(this.agentConfig.inputOptions.recorderOption),
29308
- Output.create(this.agentConfig.outputOptions.playerOption)
29309
- ]);
29324
+ this.output = await Output.create(this.agentConfig.outputOptions.playerOption);
29325
+ this.input = await Input.create(
29326
+ this.agentConfig.inputOptions.recorderOption,
29327
+ this.preliminaryInputStream
29328
+ // Reuse the same MediaStream
29329
+ );
29310
29330
  this.input.worklet.port.onmessage = this.onInputWorkletMessage;
29311
29331
  this.output.worklet.port.onmessage = this.onOutputWorkletMessage;
29312
- this.preliminaryInputStream?.getTracks().forEach((track) => track.stop());
29313
29332
  this.preliminaryInputStream = null;
29314
29333
  } catch (error) {
29315
29334
  await this.disconnectAudio();
@@ -29319,7 +29338,20 @@ var VoiceAgent = class extends Agent {
29319
29338
  // Helper method to handle media permissions:
29320
29339
  waitForUserMediaPermission = async () => {
29321
29340
  try {
29322
- return await navigator.mediaDevices.getUserMedia({ audio: true });
29341
+ const sampleRate = this.agentConfig.inputOptions.recorderOption.sampleRate;
29342
+ const options = isChrome() ? {
29343
+ sampleRate: { ideal: sampleRate },
29344
+ echoCancellation: true,
29345
+ noiseSuppression: true,
29346
+ autoGainControl: true,
29347
+ channelCount: { ideal: 1 }
29348
+ } : {
29349
+ sampleRate: { ideal: sampleRate },
29350
+ echoCancellation: { ideal: true },
29351
+ noiseSuppression: { ideal: true },
29352
+ autoGainControl: { ideal: true }
29353
+ };
29354
+ return await navigator.mediaDevices.getUserMedia({ audio: options });
29323
29355
  } catch (error) {
29324
29356
  console.error(
29325
29357
  "Permission denied or error while requesting microphone access:",
@@ -29591,6 +29623,7 @@ var VoiceAgent = class extends Agent {
29591
29623
  const audioData = content.getContent_asU8();
29592
29624
  this.addAudioChunk(new Uint8Array(audioData).buffer);
29593
29625
  }
29626
+ break;
29594
29627
  case import_common_pb8.AssistantConversationAssistantMessage.MessageCase.TEXT:
29595
29628
  const systemTranscript = systemContent.getText()?.getContent();
29596
29629
  if (systemTranscript) {
@@ -30118,4 +30151,4 @@ export {
30118
30151
  useSelectInputDeviceAgent,
30119
30152
  DeviceSelectorComponent
30120
30153
  };
30121
- //# sourceMappingURL=chunk-2EMDIAFM.mjs.map
30154
+ //# sourceMappingURL=chunk-A2PCWS4P.mjs.map