@siteed/expo-audio-stream 0.5.2 → 0.6.0
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/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +9 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +62 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +4 -0
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +445 -0
- package/android/src/main/java/net/siteed/audiostream/Constants.kt +12 -0
- package/android/src/main/java/net/siteed/audiostream/EventSender.kt +7 -0
- package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +39 -430
- package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +16 -0
- package/build/ExpoAudioStream.types.d.ts +5 -1
- package/build/ExpoAudioStream.types.d.ts.map +1 -1
- package/build/ExpoAudioStream.types.js.map +1 -1
- package/build/ExpoAudioStreamModule.web.d.ts +2 -2
- package/build/ExpoAudioStreamModule.web.d.ts.map +1 -1
- package/build/ExpoAudioStreamModule.web.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/useAudioRecording.d.ts +2 -2
- package/build/useAudioRecording.d.ts.map +1 -1
- package/build/useAudioRecording.js.map +1 -1
- package/ios/AudioStreamManager.swift +11 -11
- package/package.json +1 -1
- package/src/ExpoAudioStream.types.ts +6 -5
- package/src/ExpoAudioStreamModule.web.ts +2 -2
- package/src/index.ts +4 -0
- package/src/useAudioRecording.ts +3 -3
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,GAEnB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,gBAAgB,GAGjB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,OAAO,GAAG,IAAI,YAAY,CAC9B,qBAAqB,IAAI,kBAAkB,CAAC,eAAe,CAC5D,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,OAAO,qBAAqB,CAAC,cAAc,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,qBAAqB,CAAC,eAAe,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,QAAqD;IAErD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,WAAW,CAAoB,WAAW,EAAE,QAAQ,CAAC,CAAC;AACvE,CAAC;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["import {\n EventEmitter,\n NativeModulesProxy,\n type Subscription,\n} from \"expo-modules-core\";\n\n// Import the native module. On web, it will be resolved to ExpoAudioStream.web.ts\n// and on native platforms to ExpoAudioStream.ts\nimport { AudioEventPayload } from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\nimport {\n useAudioRecorder,\n UseAudioRecorderState,\n AudioDataEvent,\n} from \"./useAudioRecording\";\n\nconst emitter = new EventEmitter(\n ExpoAudioStreamModule ?? NativeModulesProxy.ExpoAudioStream,\n);\n\nexport function listAudioFiles(): Promise<string[]> {\n return ExpoAudioStreamModule.listAudioFiles();\n}\n\nexport function clearAudioFiles(): Promise<void> {\n return ExpoAudioStreamModule.clearAudioFiles();\n}\n\nexport function addAudioEventListener(\n listener: (event: AudioEventPayload) => Promise<void>,\n): Subscription {\n console.log(`addAudioEventListener`, listener);\n return emitter.addListener<AudioEventPayload>(\"AudioData\", listener);\n}\n\nexport type { AudioEventPayload, UseAudioRecorderState, AudioDataEvent };\nexport { useAudioRecorder };\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,GAEnB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,gBAAgB,GAGjB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,OAAO,GAAG,IAAI,YAAY,CAC9B,qBAAqB,IAAI,kBAAkB,CAAC,eAAe,CAC5D,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,OAAO,qBAAqB,CAAC,cAAc,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,qBAAqB,CAAC,eAAe,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,qBAAqB,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,QAAqD;IAErD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,WAAW,CAAoB,WAAW,EAAE,QAAQ,CAAC,CAAC;AACvE,CAAC;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["import {\n EventEmitter,\n NativeModulesProxy,\n type Subscription,\n} from \"expo-modules-core\";\n\n// Import the native module. On web, it will be resolved to ExpoAudioStream.web.ts\n// and on native platforms to ExpoAudioStream.ts\nimport { AudioEventPayload } from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\nimport {\n useAudioRecorder,\n UseAudioRecorderState,\n AudioDataEvent,\n} from \"./useAudioRecording\";\n\nconst emitter = new EventEmitter(\n ExpoAudioStreamModule ?? NativeModulesProxy.ExpoAudioStream,\n);\n\nexport function listAudioFiles(): Promise<string[]> {\n return ExpoAudioStreamModule.listAudioFiles();\n}\n\nexport function clearAudioFiles(): Promise<void> {\n return ExpoAudioStreamModule.clearAudioFiles();\n}\n\nexport function test(): void {\n return ExpoAudioStreamModule.test();\n}\n\nexport function addAudioEventListener(\n listener: (event: AudioEventPayload) => Promise<void>,\n): Subscription {\n console.log(`addAudioEventListener`, listener);\n return emitter.addListener<AudioEventPayload>(\"AudioData\", listener);\n}\n\nexport type { AudioEventPayload, UseAudioRecorderState, AudioDataEvent };\nexport { useAudioRecorder };\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AudioStreamResult,
|
|
1
|
+
import { AudioStreamResult, RecordingConfig, StartAudioStreamResult } from "./ExpoAudioStream.types";
|
|
2
2
|
export interface AudioDataEvent {
|
|
3
3
|
data: string | Blob;
|
|
4
4
|
position: number;
|
|
@@ -6,7 +6,7 @@ export interface AudioDataEvent {
|
|
|
6
6
|
totalSize: number;
|
|
7
7
|
}
|
|
8
8
|
export interface UseAudioRecorderState {
|
|
9
|
-
startRecording: (_:
|
|
9
|
+
startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;
|
|
10
10
|
stopRecording: () => Promise<AudioStreamResult | null>;
|
|
11
11
|
pauseRecording: () => void;
|
|
12
12
|
isRecording: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAudioRecording.d.ts","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EAEjB,
|
|
1
|
+
{"version":3,"file":"useAudioRecording.d.ts","sourceRoot":"","sources":["../src/useAudioRecording.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EAEjB,eAAe,EACf,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACxE,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,CA0MxB"}
|
|
@@ -1 +1 @@
|
|
|
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\";\n\nimport { addAudioEventListener } from \".\";\nimport {\n AudioStreamResult,\n AudioStreamStatus,\n RecordingOptions,\n StartAudioStreamResult,\n} from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\n\nexport interface AudioDataEvent {\n data: string | Blob;\n position: number;\n eventDataSize: number;\n totalSize: number;\n}\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingOptions) => Promise<StartAudioStreamResult>;\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 const checkStatus = useCallback(async () => {\n try {\n if (!isRecording) {\n return;\n }\n\n const status: AudioStreamStatus = ExpoAudioStreamModule.status();\n if (debug) {\n console.log(`[useAudioRecorder] Status:`, status);\n }\n\n if (!status.isRecording) {\n // Don't update if recording stopped.\n return;\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 }, [isRecording]);\n\n useEffect(() => {\n const interval = setInterval(checkStatus, 1000);\n return () => clearInterval(interval);\n }, [checkStatus]);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] Registering audio event listener`,\n onAudioStream,\n );\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 position,\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 // 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 position=${position} deltaSize: ${deltaSize} vs encoded.length: ${encoded.length}`,\n // );\n // }\n\n onAudioStream?.({\n data: encoded,\n position,\n eventDataSize: deltaSize,\n totalSize,\n });\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 onAudioStream?.({\n data: buffer,\n position,\n eventDataSize: deltaSize,\n totalSize,\n });\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 console.log(`STOOOOOP NOW`);\n const result: AudioStreamResult =\n await ExpoAudioStreamModule.stopRecording();\n console.log(`STOOOOOP NOW 2`);\n setIsRecording(false);\n setIsPaused(false);\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\";\n\nimport { addAudioEventListener } from \".\";\nimport {\n AudioStreamResult,\n AudioStreamStatus,\n RecordingConfig,\n StartAudioStreamResult,\n} from \"./ExpoAudioStream.types\";\nimport ExpoAudioStreamModule from \"./ExpoAudioStreamModule\";\n\nexport interface AudioDataEvent {\n data: string | Blob;\n position: number;\n eventDataSize: number;\n totalSize: number;\n}\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;\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 const checkStatus = useCallback(async () => {\n try {\n if (!isRecording) {\n return;\n }\n\n const status: AudioStreamStatus = ExpoAudioStreamModule.status();\n if (debug) {\n console.log(`[useAudioRecorder] Status:`, status);\n }\n\n if (!status.isRecording) {\n // Don't update if recording stopped.\n return;\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 }, [isRecording]);\n\n useEffect(() => {\n const interval = setInterval(checkStatus, 1000);\n return () => clearInterval(interval);\n }, [checkStatus]);\n\n useEffect(() => {\n if (debug) {\n console.log(\n `[useAudioRecorder] Registering audio event listener`,\n onAudioStream,\n );\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 position,\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 // 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 position=${position} deltaSize: ${deltaSize} vs encoded.length: ${encoded.length}`,\n // );\n // }\n\n onAudioStream?.({\n data: encoded,\n position,\n eventDataSize: deltaSize,\n totalSize,\n });\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 onAudioStream?.({\n data: buffer,\n position,\n eventDataSize: deltaSize,\n totalSize,\n });\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: RecordingConfig) => {\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 console.log(`STOOOOOP NOW`);\n const result: AudioStreamResult =\n await ExpoAudioStreamModule.stopRecording();\n console.log(`STOOOOOP NOW 2`);\n setIsRecording(false);\n setIsPaused(false);\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"]}
|
|
@@ -113,16 +113,9 @@ class AudioStreamManager: NSObject {
|
|
|
113
113
|
let fileName = "\(recordingUUID!.uuidString).wav"
|
|
114
114
|
let fileURL = documentsDirectory.appendingPathComponent(fileName)
|
|
115
115
|
|
|
116
|
-
if fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let wavHeader = createWavHeader(dataSize: 0) // Initially set data size to 0
|
|
120
|
-
fileHandle.write(wavHeader)
|
|
121
|
-
fileHandle.closeFile()
|
|
122
|
-
} catch {
|
|
123
|
-
Logger.debug("Failed to write WAV header: \(error.localizedDescription)")
|
|
124
|
-
return nil
|
|
125
|
-
}
|
|
116
|
+
if !fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil) {
|
|
117
|
+
Logger.debug("Failed to create file at: \(fileURL.path)")
|
|
118
|
+
return nil
|
|
126
119
|
}
|
|
127
120
|
return fileURL
|
|
128
121
|
}
|
|
@@ -381,7 +374,14 @@ class AudioStreamManager: NSObject {
|
|
|
381
374
|
print("Buffer data is nil.")
|
|
382
375
|
return
|
|
383
376
|
}
|
|
384
|
-
|
|
377
|
+
var data = Data(bytes: bufferData, count: Int(audioData.mDataByteSize))
|
|
378
|
+
|
|
379
|
+
// Check if this is the first buffer to process and totalDataSize is 0
|
|
380
|
+
if totalDataSize == 0 {
|
|
381
|
+
// Since it's the first buffer, prepend the WAV header
|
|
382
|
+
let header = createWavHeader(dataSize: 0) // Set initial dataSize to 0, update later
|
|
383
|
+
data.insert(contentsOf: header, at: 0)
|
|
384
|
+
}
|
|
385
385
|
|
|
386
386
|
// print("Writing data size: \(data.count) bytes") // Debug: Check the size of data being written
|
|
387
387
|
fileHandle.seekToEndOfFile()
|
package/package.json
CHANGED
|
@@ -37,10 +37,11 @@ export interface AudioStreamStatus {
|
|
|
37
37
|
mimeType: string;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
export type EncodingType = "pcm_16bit" | "pcm_8bit";
|
|
41
|
+
|
|
42
|
+
export interface RecordingConfig {
|
|
43
|
+
sampleRate?: 16000 | 44100 | 48000;
|
|
44
|
+
channels?: 1 | 2; // 1 or 2 MONO or STEREO
|
|
45
|
+
encoding?: EncodingType;
|
|
45
46
|
interval?: number;
|
|
46
47
|
}
|
|
@@ -4,7 +4,7 @@ import { EventEmitter } from "expo-modules-core";
|
|
|
4
4
|
import {
|
|
5
5
|
AudioEventPayload,
|
|
6
6
|
AudioStreamResult,
|
|
7
|
-
|
|
7
|
+
RecordingConfig,
|
|
8
8
|
StartAudioStreamResult,
|
|
9
9
|
} from "./ExpoAudioStream.types";
|
|
10
10
|
|
|
@@ -59,7 +59,7 @@ class ExpoAudioStreamWeb extends EventEmitter {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Start recording with options
|
|
62
|
-
async startRecording(options:
|
|
62
|
+
async startRecording(options: RecordingConfig = {}) {
|
|
63
63
|
if (this.isRecording) {
|
|
64
64
|
throw new Error("Recording is already in progress");
|
|
65
65
|
}
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,10 @@ export function clearAudioFiles(): Promise<void> {
|
|
|
26
26
|
return ExpoAudioStreamModule.clearAudioFiles();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export function test(): void {
|
|
30
|
+
return ExpoAudioStreamModule.test();
|
|
31
|
+
}
|
|
32
|
+
|
|
29
33
|
export function addAudioEventListener(
|
|
30
34
|
listener: (event: AudioEventPayload) => Promise<void>,
|
|
31
35
|
): Subscription {
|
package/src/useAudioRecording.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { addAudioEventListener } from ".";
|
|
|
5
5
|
import {
|
|
6
6
|
AudioStreamResult,
|
|
7
7
|
AudioStreamStatus,
|
|
8
|
-
|
|
8
|
+
RecordingConfig,
|
|
9
9
|
StartAudioStreamResult,
|
|
10
10
|
} from "./ExpoAudioStream.types";
|
|
11
11
|
import ExpoAudioStreamModule from "./ExpoAudioStreamModule";
|
|
@@ -17,7 +17,7 @@ export interface AudioDataEvent {
|
|
|
17
17
|
totalSize: number;
|
|
18
18
|
}
|
|
19
19
|
export interface UseAudioRecorderState {
|
|
20
|
-
startRecording: (_:
|
|
20
|
+
startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;
|
|
21
21
|
stopRecording: () => Promise<AudioStreamResult | null>;
|
|
22
22
|
pauseRecording: () => void;
|
|
23
23
|
isRecording: boolean;
|
|
@@ -183,7 +183,7 @@ export function useAudioRecorder({
|
|
|
183
183
|
}, []);
|
|
184
184
|
|
|
185
185
|
const startRecording = useCallback(
|
|
186
|
-
async (recordingOptions:
|
|
186
|
+
async (recordingOptions: RecordingConfig) => {
|
|
187
187
|
setIsRecording(true);
|
|
188
188
|
setIsPaused(false);
|
|
189
189
|
setSize(0);
|