@siteed/expo-audio-stream 0.4.5 → 0.4.6

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.
@@ -269,6 +269,9 @@ class ExpoAudioStreamModule() : Module() {
269
269
 
270
270
  private fun recordingProcess() {
271
271
  FileOutputStream(audioFile, true).use { fos ->
272
+ // Buffer to accumulate data
273
+ val accumulatedAudioData = ByteArrayOutputStream()
274
+
272
275
  // Write audio data directly to the file
273
276
  val audioData = ByteArray(bufferSizeInBytes)
274
277
  while (isRecording.get()) {
@@ -281,11 +284,13 @@ class ExpoAudioStreamModule() : Module() {
281
284
  if (bytesRead > 0) {
282
285
  fos.write(audioData, 0, bytesRead)
283
286
  totalDataSize += bytesRead
287
+ accumulatedAudioData.write(audioData, 0, bytesRead)
284
288
 
285
289
  // Emit audio data at defined intervals
286
290
  if (SystemClock.elapsedRealtime() - lastEmitTime >= interval) {
287
- emitAudioData(audioData, bytesRead)
291
+ emitAudioData(accumulatedAudioData.toByteArray(), accumulatedAudioData.size())
288
292
  lastEmitTime = SystemClock.elapsedRealtime() // Reset the timer
293
+ accumulatedAudioData.reset() // Clear the accumulator
289
294
  }
290
295
  }
291
296
  }
@@ -339,7 +344,7 @@ class ExpoAudioStreamModule() : Module() {
339
344
  "fileUri" to audioFile?.toURI().toString(),
340
345
  "lastEmittedSize" to from,
341
346
  "encoded" to encodedBuffer,
342
- "deltaSize" to deltaSize,
347
+ "deltaSize" to length,
343
348
  "position" to positionInMs,
344
349
  "mimeType" to mimeType,
345
350
  "totalSize" to fileSize,
@@ -353,7 +358,7 @@ class ExpoAudioStreamModule() : Module() {
353
358
  }
354
359
 
355
360
  private fun encodeAudioData(rawData: ByteArray): String {
356
- return Base64.encodeToString(rawData, Base64.DEFAULT)
361
+ return Base64.encodeToString(rawData, Base64.NO_WRAP)
357
362
  }
358
363
 
359
364
  private fun saveAudioToFile(rawData: ByteArray): Boolean {
@@ -1,6 +1,6 @@
1
1
  import { AudioStreamResult, RecordingOptions } from "./ExpoAudioStream.types";
2
2
  export interface AudioDataEvent {
3
- buffer: Blob;
3
+ arrayBuffer: ArrayBuffer;
4
4
  position: number;
5
5
  }
6
6
  export interface UseAudioRecorderState {
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioRecording.d.ts","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,iBAAiB,EAEjB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChE,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACvD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,aAAa,EACb,KAAa,GACd,EAAE;IACD,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,qBAAqB,CA8KxB"}
1
+ {"version":3,"file":"useAudioRecording.d.ts","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,iBAAiB,EAEjB,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChE,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACvD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,aAAa,EACb,KAAa,GACd,EAAE;IACD,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,qBAAqB,CAmMxB"}
@@ -1,6 +1,6 @@
1
- import { decode as atob } from "base-64";
2
1
  import { Platform } from "expo-modules-core";
3
2
  import { useCallback, useEffect, useState } from "react";
3
+ import { atob } from "react-native-quick-base64";
4
4
  import { addAudioEventListener } from ".";
5
5
  import ExpoAudioStreamModule from "./ExpoAudioStreamModule";
6
6
  export function useAudioRecorder({ onAudioStream, debug = false, }) {
@@ -21,6 +21,7 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
21
21
  if (debug) {
22
22
  console.log(`[useAudioRecorder] Status:`, status);
23
23
  }
24
+ // Extract matching file from filesystem
24
25
  setDuration(status.duration);
25
26
  setSize(status.size);
26
27
  }
@@ -36,9 +37,10 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
36
37
  if (debug) {
37
38
  console.log(`[useAudioRecorder] Registering audio event listener`, onAudioStream);
38
39
  onAudioStream?.({
39
- buffer: new Blob(),
40
+ arrayBuffer: new ArrayBuffer(0),
40
41
  position: 0,
41
42
  }).catch(console.error);
43
+ console.log(`[useAudioRecorder] Registered audio event listener`);
42
44
  }
43
45
  const subscribe = addAudioEventListener(async ({ fileUri, deltaSize, totalSize, lastEmittedSize, position, streamUuid, encoded, mimeType, buffer, }) => {
44
46
  try {
@@ -58,18 +60,26 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
58
60
  if (Platform.OS !== "web") {
59
61
  // Read the audio file as a base64 string for comparison
60
62
  try {
61
- // convert encoded string to binary data
63
+ if (!encoded) {
64
+ console.error("[useAudioRecorder] Encoded audio data is missing");
65
+ throw new Error("Encoded audio data is missing");
66
+ }
67
+ console.log(`encoded.length: ${encoded.length}`);
62
68
  const binaryData = atob(encoded);
63
- const content = new Uint8Array(binaryData.length);
69
+ const bytes = new Uint8Array(binaryData.length);
64
70
  for (let i = 0; i < binaryData.length; i++) {
65
- content[i] = binaryData.charCodeAt(i);
71
+ bytes[i] = binaryData.charCodeAt(i) & 0xff; // Mask to 8 bits
72
+ }
73
+ const arrayBuffer = bytes.buffer;
74
+ if (debug) {
75
+ console.log(`[useAudioRecorder] Read audio file deltaSize: ${deltaSize} vs encoded.length: ${encoded.length}`);
66
76
  }
67
- const audioBlob = new Blob([content], { type: mimeType });
77
+ onAudioStream?.({ arrayBuffer, position });
68
78
  // Below code is optional, used to compare encoded data to audio on file system
69
79
  // Fetch the audio data from the fileUri
70
80
  // const options = {
71
81
  // encoding: FileSystem.EncodingType.Base64,
72
- // position: from,
82
+ // position: lastEmittedSize,
73
83
  // length: deltaSize,
74
84
  // };
75
85
  // const base64Content = await FileSystem.readAsStringAsync(fileUri, options);
@@ -80,7 +90,6 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
80
90
  // }
81
91
  // const audioBlob = new Blob([content], { type: 'application/octet-stream' }); // Create a Blob from the byte array
82
92
  // console.debug(`Read audio file (len: ${content.length}) vs ${deltaSize}`)
83
- onAudioStream?.({ buffer: audioBlob, position });
84
93
  }
85
94
  catch (error) {
86
95
  console.error("[useAudioRecorder] Error reading audio file:", error);
@@ -88,7 +97,8 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
88
97
  }
89
98
  else if (buffer) {
90
99
  // Coming from web
91
- onAudioStream?.({ buffer, position });
100
+ const arrayBuffer = await buffer.arrayBuffer();
101
+ onAudioStream?.({ arrayBuffer, position });
92
102
  }
93
103
  }
94
104
  }
@@ -96,13 +106,16 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
96
106
  console.error("[useAudioRecorder] Error processing audio event:", error);
97
107
  }
98
108
  });
109
+ if (debug) {
110
+ console.log(`[useAudioRecorder] Subscribed to audio event listener`, subscribe);
111
+ }
99
112
  return () => {
100
113
  if (debug) {
101
114
  console.log(`[useAudioRecorder] Removing audio event listener`);
102
115
  }
103
116
  subscribe.remove();
104
117
  };
105
- }, [isRecording, onAudioStream, debug]);
118
+ }, []);
106
119
  const startRecording = useCallback(async (recordingOptions) => {
107
120
  setIsRecording(true);
108
121
  setIsPaused(false);
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioRecording.js","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"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","sourcesContent":["import { decode as atob } from \"base-64\";\nimport { Platform } from \"expo-modules-core\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { addAudioEventListener } from \".\";\nimport {\n AudioStreamResult,\n AudioStreamStatus,\n RecordingOptions,\n} from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\n\nexport interface AudioDataEvent {\n buffer: Blob;\n position: number;\n}\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingOptions) => Promise<string | null>;\n stopRecording: () => Promise<AudioStreamResult | null>;\n pauseRecording: () => void;\n isRecording: boolean;\n isPaused: boolean;\n duration: number; // Duration of the recording\n size: number; // Size in bytes of the recorded audio\n}\n\nexport function useAudioRecorder({\n onAudioStream,\n debug = false,\n}: {\n onAudioStream?: (_: AudioDataEvent) => Promise<void>;\n debug?: boolean;\n}): UseAudioRecorderState {\n const [isRecording, setIsRecording] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const [duration, setDuration] = useState(0);\n const [size, setSize] = useState(0);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] isRecording: ${isRecording}, isPaused: ${isPaused}`,\n );\n }\n if (isRecording || isPaused) {\n const interval = setInterval(() => {\n try {\n if (debug) console.log(`[useAudioRecorder] Getting status`);\n const status: AudioStreamStatus = ExpoAudioStreamModule.status();\n if (debug) {\n console.log(`[useAudioRecorder] Status:`, status);\n }\n setDuration(status.duration);\n setSize(status.size);\n } catch (error) {\n console.error(`[useAudioRecorder] Error getting status:`, error);\n }\n }, 1000);\n return () => clearInterval(interval);\n }\n\n return () => null;\n }, [isRecording, isPaused, debug]);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] Registering audio event listener`,\n onAudioStream,\n );\n onAudioStream?.({\n buffer: new Blob(),\n position: 0,\n }).catch(console.error);\n }\n const subscribe = addAudioEventListener(\n async ({\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n }) => {\n try {\n if (debug) {\n console.log(`[useAudioRecorder] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n });\n }\n if (deltaSize > 0) {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== \"web\") {\n // Read the audio file as a base64 string for comparison\n try {\n // convert encoded string to binary data\n const binaryData = atob(encoded);\n const content = new Uint8Array(binaryData.length);\n for (let i = 0; i < binaryData.length; i++) {\n content[i] = binaryData.charCodeAt(i);\n }\n const audioBlob = new Blob([content], { type: mimeType });\n\n // Below code is optional, used to compare encoded data to audio on file system\n // Fetch the audio data from the fileUri\n // const options = {\n // encoding: FileSystem.EncodingType.Base64,\n // position: from,\n // length: deltaSize,\n // };\n // const base64Content = await FileSystem.readAsStringAsync(fileUri, options);\n // const binaryData = atob(base64Content);\n // const content = new Uint8Array(binaryData.length);\n // for (let i = 0; i < binaryData.length; i++) {\n // content[i] = binaryData.charCodeAt(i);\n // }\n // const audioBlob = new Blob([content], { type: 'application/octet-stream' }); // Create a Blob from the byte array\n // console.debug(`Read audio file (len: ${content.length}) vs ${deltaSize}`)\n\n onAudioStream?.({ buffer: audioBlob, position });\n } catch (error) {\n console.error(\n \"[useAudioRecorder] Error reading audio file:\",\n error,\n );\n }\n } else if (buffer) {\n // Coming from web\n onAudioStream?.({ buffer, position });\n }\n }\n } catch (error) {\n console.error(\n \"[useAudioRecorder] Error processing audio event:\",\n error,\n );\n }\n },\n );\n return () => {\n if (debug) {\n console.log(`[useAudioRecorder] Removing audio event listener`);\n }\n subscribe.remove();\n };\n }, [isRecording, onAudioStream, debug]);\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingOptions) => {\n setIsRecording(true);\n setIsPaused(false);\n setSize(0);\n setDuration(0);\n try {\n if (debug) {\n console.log(`[useAudioRecorder] start recoding`, recordingOptions);\n }\n\n const fileUrl =\n await ExpoAudioStreamModule.startRecording(recordingOptions);\n\n return fileUrl;\n } catch (error) {\n console.error(\"[useAudioRecorder] Error starting recording:\", error);\n setIsRecording(false);\n }\n },\n [debug],\n );\n\n const stopRecording = useCallback(async () => {\n setIsRecording(false);\n setIsPaused(false);\n const result: AudioStreamResult =\n await ExpoAudioStreamModule.stopRecording();\n return result;\n }, []);\n\n const pauseRecording = useCallback(async () => {\n try {\n await ExpoAudioStreamModule.stopRecording();\n setIsPaused(true);\n setIsRecording(false);\n } catch (error) {\n console.error(\"[useAudioRecorder] Error pausing recording:\", error);\n }\n }, [debug]);\n\n return {\n startRecording,\n stopRecording,\n pauseRecording,\n isPaused,\n isRecording,\n duration,\n size,\n };\n}\n"]}
1
+ {"version":3,"file":"useAudioRecording.js","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from \"expo-modules-core\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { atob } from \"react-native-quick-base64\";\n\nimport { addAudioEventListener } from \".\";\nimport {\n AudioStreamResult,\n AudioStreamStatus,\n RecordingOptions,\n} from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\n\nexport interface AudioDataEvent {\n arrayBuffer: ArrayBuffer;\n position: number;\n}\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingOptions) => Promise<string | null>;\n stopRecording: () => Promise<AudioStreamResult | null>;\n pauseRecording: () => void;\n isRecording: boolean;\n isPaused: boolean;\n duration: number; // Duration of the recording\n size: number; // Size in bytes of the recorded audio\n}\n\nexport function useAudioRecorder({\n onAudioStream,\n debug = false,\n}: {\n onAudioStream?: (_: AudioDataEvent) => Promise<void>;\n debug?: boolean;\n}): UseAudioRecorderState {\n const [isRecording, setIsRecording] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const [duration, setDuration] = useState(0);\n const [size, setSize] = useState(0);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] isRecording: ${isRecording}, isPaused: ${isPaused}`,\n );\n }\n if (isRecording || isPaused) {\n const interval = setInterval(() => {\n try {\n if (debug) console.log(`[useAudioRecorder] Getting status`);\n const status: AudioStreamStatus = ExpoAudioStreamModule.status();\n if (debug) {\n console.log(`[useAudioRecorder] Status:`, status);\n }\n // Extract matching file from filesystem\n setDuration(status.duration);\n setSize(status.size);\n } catch (error) {\n console.error(`[useAudioRecorder] Error getting status:`, error);\n }\n }, 1000);\n return () => clearInterval(interval);\n }\n\n return () => null;\n }, [isRecording, isPaused, debug]);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] Registering audio event listener`,\n onAudioStream,\n );\n onAudioStream?.({\n arrayBuffer: new ArrayBuffer(0),\n position: 0,\n }).catch(console.error);\n console.log(`[useAudioRecorder] Registered audio event listener`);\n }\n const subscribe = addAudioEventListener(\n async ({\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n }) => {\n try {\n if (debug) {\n console.log(`[useAudioRecorder] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n });\n }\n if (deltaSize > 0) {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== \"web\") {\n // Read the audio file as a base64 string for comparison\n try {\n if (!encoded) {\n console.error(\n \"[useAudioRecorder] Encoded audio data is missing\",\n );\n throw new Error(\"Encoded audio data is missing\");\n }\n console.log(`encoded.length: ${encoded.length}`);\n const binaryData = atob(encoded);\n const bytes = new Uint8Array(binaryData.length);\n for (let i = 0; i < binaryData.length; i++) {\n bytes[i] = binaryData.charCodeAt(i) & 0xff; // Mask to 8 bits\n }\n const arrayBuffer = bytes.buffer;\n\n if (debug) {\n console.log(\n `[useAudioRecorder] Read audio file deltaSize: ${deltaSize} vs encoded.length: ${encoded.length}`,\n );\n }\n\n onAudioStream?.({ arrayBuffer, position });\n\n // Below code is optional, used to compare encoded data to audio on file system\n // Fetch the audio data from the fileUri\n // const options = {\n // encoding: FileSystem.EncodingType.Base64,\n // position: lastEmittedSize,\n // length: deltaSize,\n // };\n // const base64Content = await FileSystem.readAsStringAsync(fileUri, options);\n // const binaryData = atob(base64Content);\n // const content = new Uint8Array(binaryData.length);\n // for (let i = 0; i < binaryData.length; i++) {\n // content[i] = binaryData.charCodeAt(i);\n // }\n // const audioBlob = new Blob([content], { type: 'application/octet-stream' }); // Create a Blob from the byte array\n // console.debug(`Read audio file (len: ${content.length}) vs ${deltaSize}`)\n } catch (error) {\n console.error(\n \"[useAudioRecorder] Error reading audio file:\",\n error,\n );\n }\n } else if (buffer) {\n // Coming from web\n const arrayBuffer = await buffer.arrayBuffer();\n onAudioStream?.({ arrayBuffer, position });\n }\n }\n } catch (error) {\n console.error(\n \"[useAudioRecorder] Error processing audio event:\",\n error,\n );\n }\n },\n );\n if (debug) {\n console.log(\n `[useAudioRecorder] Subscribed to audio event listener`,\n subscribe,\n );\n }\n return () => {\n if (debug) {\n console.log(`[useAudioRecorder] Removing audio event listener`);\n }\n subscribe.remove();\n };\n }, []);\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingOptions) => {\n setIsRecording(true);\n setIsPaused(false);\n setSize(0);\n setDuration(0);\n try {\n if (debug) {\n console.log(`[useAudioRecorder] start recoding`, recordingOptions);\n }\n\n const fileUrl =\n await ExpoAudioStreamModule.startRecording(recordingOptions);\n\n return fileUrl;\n } catch (error) {\n console.error(\"[useAudioRecorder] Error starting recording:\", error);\n setIsRecording(false);\n }\n },\n [debug],\n );\n\n const stopRecording = useCallback(async () => {\n setIsRecording(false);\n setIsPaused(false);\n const result: AudioStreamResult =\n await ExpoAudioStreamModule.stopRecording();\n return result;\n }, []);\n\n const pauseRecording = useCallback(async () => {\n try {\n await ExpoAudioStreamModule.stopRecording();\n setIsPaused(true);\n setIsRecording(false);\n } catch (error) {\n console.error(\"[useAudioRecorder] Error pausing recording:\", error);\n }\n }, [debug]);\n\n return {\n startRecording,\n stopRecording,\n pauseRecording,\n isPaused,\n isRecording,\n duration,\n size,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siteed/expo-audio-stream",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "stream audio crossplatform",
5
5
  "license": "MIT",
6
6
  "main": "build/index.js",
@@ -33,7 +33,7 @@
33
33
  "open:android": "open -a \"Android Studio\" example/android"
34
34
  },
35
35
  "dependencies": {
36
- "base-64": "^1.0.0"
36
+ "react-native-quick-base64": "^2.1.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@expo/config-plugins": "^7.9.1",
@@ -1,6 +1,6 @@
1
- import { decode as atob } from "base-64";
2
1
  import { Platform } from "expo-modules-core";
3
2
  import { useCallback, useEffect, useState } from "react";
3
+ import { atob } from "react-native-quick-base64";
4
4
 
5
5
  import { addAudioEventListener } from ".";
6
6
  import {
@@ -11,7 +11,7 @@ import {
11
11
  import ExpoAudioStreamModule from "./ExpoAudioStreamModule";
12
12
 
13
13
  export interface AudioDataEvent {
14
- buffer: Blob;
14
+ arrayBuffer: ArrayBuffer;
15
15
  position: number;
16
16
  }
17
17
  export interface UseAudioRecorderState {
@@ -50,6 +50,7 @@ export function useAudioRecorder({
50
50
  if (debug) {
51
51
  console.log(`[useAudioRecorder] Status:`, status);
52
52
  }
53
+ // Extract matching file from filesystem
53
54
  setDuration(status.duration);
54
55
  setSize(status.size);
55
56
  } catch (error) {
@@ -69,9 +70,10 @@ export function useAudioRecorder({
69
70
  onAudioStream,
70
71
  );
71
72
  onAudioStream?.({
72
- buffer: new Blob(),
73
+ arrayBuffer: new ArrayBuffer(0),
73
74
  position: 0,
74
75
  }).catch(console.error);
76
+ console.log(`[useAudioRecorder] Registered audio event listener`);
75
77
  }
76
78
  const subscribe = addAudioEventListener(
77
79
  async ({
@@ -102,19 +104,33 @@ export function useAudioRecorder({
102
104
  if (Platform.OS !== "web") {
103
105
  // Read the audio file as a base64 string for comparison
104
106
  try {
105
- // convert encoded string to binary data
107
+ if (!encoded) {
108
+ console.error(
109
+ "[useAudioRecorder] Encoded audio data is missing",
110
+ );
111
+ throw new Error("Encoded audio data is missing");
112
+ }
113
+ console.log(`encoded.length: ${encoded.length}`);
106
114
  const binaryData = atob(encoded);
107
- const content = new Uint8Array(binaryData.length);
115
+ const bytes = new Uint8Array(binaryData.length);
108
116
  for (let i = 0; i < binaryData.length; i++) {
109
- content[i] = binaryData.charCodeAt(i);
117
+ bytes[i] = binaryData.charCodeAt(i) & 0xff; // Mask to 8 bits
118
+ }
119
+ const arrayBuffer = bytes.buffer;
120
+
121
+ if (debug) {
122
+ console.log(
123
+ `[useAudioRecorder] Read audio file deltaSize: ${deltaSize} vs encoded.length: ${encoded.length}`,
124
+ );
110
125
  }
111
- const audioBlob = new Blob([content], { type: mimeType });
126
+
127
+ onAudioStream?.({ arrayBuffer, position });
112
128
 
113
129
  // Below code is optional, used to compare encoded data to audio on file system
114
130
  // Fetch the audio data from the fileUri
115
131
  // const options = {
116
132
  // encoding: FileSystem.EncodingType.Base64,
117
- // position: from,
133
+ // position: lastEmittedSize,
118
134
  // length: deltaSize,
119
135
  // };
120
136
  // const base64Content = await FileSystem.readAsStringAsync(fileUri, options);
@@ -125,8 +141,6 @@ export function useAudioRecorder({
125
141
  // }
126
142
  // const audioBlob = new Blob([content], { type: 'application/octet-stream' }); // Create a Blob from the byte array
127
143
  // console.debug(`Read audio file (len: ${content.length}) vs ${deltaSize}`)
128
-
129
- onAudioStream?.({ buffer: audioBlob, position });
130
144
  } catch (error) {
131
145
  console.error(
132
146
  "[useAudioRecorder] Error reading audio file:",
@@ -135,7 +149,8 @@ export function useAudioRecorder({
135
149
  }
136
150
  } else if (buffer) {
137
151
  // Coming from web
138
- onAudioStream?.({ buffer, position });
152
+ const arrayBuffer = await buffer.arrayBuffer();
153
+ onAudioStream?.({ arrayBuffer, position });
139
154
  }
140
155
  }
141
156
  } catch (error) {
@@ -146,13 +161,19 @@ export function useAudioRecorder({
146
161
  }
147
162
  },
148
163
  );
164
+ if (debug) {
165
+ console.log(
166
+ `[useAudioRecorder] Subscribed to audio event listener`,
167
+ subscribe,
168
+ );
169
+ }
149
170
  return () => {
150
171
  if (debug) {
151
172
  console.log(`[useAudioRecorder] Removing audio event listener`);
152
173
  }
153
174
  subscribe.remove();
154
175
  };
155
- }, [isRecording, onAudioStream, debug]);
176
+ }, []);
156
177
 
157
178
  const startRecording = useCallback(
158
179
  async (recordingOptions: RecordingOptions) => {