sera-ai 1.0.20 → 1.0.22

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.d.mts CHANGED
@@ -68,6 +68,7 @@ interface AudioCaptureProps {
68
68
  format?: "raw" | "wav";
69
69
  showDownload?: boolean;
70
70
  className?: string;
71
+ visualizerClassName?: string;
71
72
  style?: React$1.CSSProperties;
72
73
  }
73
74
  declare const AudioCapture: React$1.FC<AudioCaptureProps>;
package/dist/index.d.ts CHANGED
@@ -68,6 +68,7 @@ interface AudioCaptureProps {
68
68
  format?: "raw" | "wav";
69
69
  showDownload?: boolean;
70
70
  className?: string;
71
+ visualizerClassName?: string;
71
72
  style?: React$1.CSSProperties;
72
73
  }
73
74
  declare const AudioCapture: React$1.FC<AudioCaptureProps>;
package/dist/index.js CHANGED
@@ -29,6 +29,11 @@ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
29
29
  var pRetry__default = /*#__PURE__*/_interopDefault(pRetry);
30
30
 
31
31
  // src/AudioRecorder.tsx
32
+
33
+ // src/constants/audio.ts
34
+ var AUDIO_SAMPLE_RATE = 16e3;
35
+
36
+ // src/hooks/useFFmpegConverter.ts
32
37
  var createFFmpegWorker = () => {
33
38
  const workerCode = `
34
39
  let ffmpegModule = null;
@@ -296,7 +301,7 @@ var useFFmpegConverter = () => {
296
301
  return true;
297
302
  }, []);
298
303
  const convertToWav = React3.useCallback(
299
- async (audioData, sampleRate = 44100, fileName = "recording.wav") => {
304
+ async (audioData, sampleRate = AUDIO_SAMPLE_RATE, fileName = "recording.wav") => {
300
305
  setIsConverting(true);
301
306
  setProgress(0);
302
307
  setError(null);
@@ -412,7 +417,8 @@ var useFFmpegConverter = () => {
412
417
  console.error("No audio data chunk found in WAV file");
413
418
  return file;
414
419
  }
415
- console.log(`[AUDIO] Found audio data: start=${audioDataStart}, length=${audioDataLength} bytes`);
420
+ const originalSampleRate = dataView.getUint32(24, true);
421
+ console.log(`[AUDIO] Found audio data: start=${audioDataStart}, length=${audioDataLength} bytes, sampleRate=${originalSampleRate}Hz`);
416
422
  const audioData = new Int16Array(arrayBuffer, audioDataStart, audioDataLength / 2);
417
423
  if (audioData.length === 0) {
418
424
  console.error("No audio data extracted from WAV file");
@@ -498,8 +504,8 @@ var useFFmpegConverter = () => {
498
504
  // Amplitude threshold for silence
499
505
  minSilenceDuration: 0.5,
500
506
  // Minimum silence duration to remove (seconds)
501
- sampleRate: 44100,
502
- // Assume standard sample rate
507
+ sampleRate: originalSampleRate,
508
+ // Preserve original sample rate to avoid speed changes
503
509
  fileName: file.name,
504
510
  fileType: file.type,
505
511
  originalSize: file.size
@@ -2924,7 +2930,14 @@ var useAudioRecorder = ({
2924
2930
  }
2925
2931
  const newSessionId = `session_retry_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
2926
2932
  console.log("\u{1F194} Generated new retry session ID:", newSessionId);
2927
- await uploadChunkToServerRef.current(combinedAudio, true, 0, true, false);
2933
+ await uploadChunkToServerRef.current(
2934
+ combinedAudio,
2935
+ true,
2936
+ 0,
2937
+ true,
2938
+ false,
2939
+ metadata.sampleRate
2940
+ );
2928
2941
  console.log("[SUCCESS] Retry upload completed successfully");
2929
2942
  } catch (error2) {
2930
2943
  console.error("[ERROR] Retry session failed:", error2);
@@ -3063,7 +3076,7 @@ var useAudioRecorder = ({
3063
3076
  setShowRetrySessionPrompt(false);
3064
3077
  }, [clearFailedSessions]);
3065
3078
  const uploadChunkToServer = React3__namespace.default.useCallback(
3066
- async (audioData, isFinalChunk, sequence, retry = false, isPausedChunk = false) => {
3079
+ async (audioData, isFinalChunk, sequence, retry = false, isPausedChunk = false, sampleRateOverride) => {
3067
3080
  const currentIsLoaded = isLoadedRef.current;
3068
3081
  console.log("\u{1F527} uploadChunkToServer called with:", {
3069
3082
  isLoaded: currentIsLoaded,
@@ -3123,7 +3136,7 @@ var useAudioRecorder = ({
3123
3136
  console.log(
3124
3137
  `[AUDIO] Audio stats: maxAmplitude=${maxAmplitude.toFixed(4)}, audioContent=${(audioPercentage * 100).toFixed(2)}%, sequence=${sequence}, isFinal=${isFinalChunk}`
3125
3138
  );
3126
- const sampleRate = audioContextRef.current?.sampleRate || 16e3;
3139
+ const sampleRate = sampleRateOverride ?? (audioContextRef.current?.sampleRate || AUDIO_SAMPLE_RATE);
3127
3140
  const timestamp = Date.now();
3128
3141
  const fileName = `audio-chunk-${timestamp}.wav`;
3129
3142
  let wavFile = await convertToWav(audioData, sampleRate, fileName);
@@ -4802,7 +4815,7 @@ var useAudioDictation = ({
4802
4815
  };
4803
4816
  const encodeWAV = (samples) => {
4804
4817
  console.log(`Encoding WAV with ${samples.length} samples`);
4805
- const sampleRate = audioContextRef.current?.sampleRate || 44100;
4818
+ const sampleRate = audioContextRef.current?.sampleRate || AUDIO_SAMPLE_RATE;
4806
4819
  console.log(`Using sample rate: ${sampleRate}Hz`);
4807
4820
  const buffer = new ArrayBuffer(44 + samples.length * 2);
4808
4821
  const view = new DataView(buffer);
@@ -5398,7 +5411,7 @@ var useAudioCapture = ({
5398
5411
  });
5399
5412
  }, []);
5400
5413
  const float32ToWavFile = (samples) => {
5401
- const sampleRate = audioContextRef.current?.sampleRate || 44100;
5414
+ const sampleRate = audioContextRef.current?.sampleRate || AUDIO_SAMPLE_RATE;
5402
5415
  const buffer = new ArrayBuffer(44 + samples.length * 2);
5403
5416
  const view = new DataView(buffer);
5404
5417
  const writeString = (offset2, str) => {
@@ -5713,6 +5726,7 @@ var AudioCapture = ({
5713
5726
  format = "raw",
5714
5727
  showDownload = false,
5715
5728
  className = "",
5729
+ visualizerClassName = "",
5716
5730
  style
5717
5731
  }) => {
5718
5732
  React3__namespace.useEffect(() => {
@@ -5877,12 +5891,13 @@ var AudioCapture = ({
5877
5891
  statusMessage && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-blue-600 dark:text-blue-400 mt-1", children: statusMessage })
5878
5892
  ] })
5879
5893
  ] }),
5880
- isRecording && !isPaused && mediaStreamRef.current && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full max-w-lg mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
5894
+ isRecording && !isPaused && mediaStreamRef.current && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full ${visualizerClassName || "max-w-lg"} mx-auto`, children: /* @__PURE__ */ jsxRuntime.jsx(
5881
5895
  AudioVisualizerImproved,
5882
5896
  {
5883
5897
  mediaStream: mediaStreamRef.current,
5884
5898
  isRecording: isRecording && !isPaused,
5885
- forceLight: false
5899
+ forceLight: false,
5900
+ className: visualizerClassName
5886
5901
  }
5887
5902
  ) }),
5888
5903
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: isProcessing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 bg-teal-600 hover:bg-teal-700 text-white py-2 px-4 rounded-full", children: [