@siteed/expo-audio-stream 0.6.0 → 0.7.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/build/useAudioRecording.d.ts +2 -0
- package/build/useAudioRecording.d.ts.map +1 -1
- package/build/useAudioRecording.js +18 -13
- package/build/useAudioRecording.js.map +1 -1
- package/ios/AudioStreamManager.swift +15 -10
- package/ios/ExpoAudioStreamModule.swift +12 -6
- package/package.json +1 -1
- package/src/useAudioRecording.ts +22 -15
|
@@ -2,6 +2,7 @@ import { AudioStreamResult, RecordingConfig, StartAudioStreamResult } from "./Ex
|
|
|
2
2
|
export interface AudioDataEvent {
|
|
3
3
|
data: string | Blob;
|
|
4
4
|
position: number;
|
|
5
|
+
fileUri: string;
|
|
5
6
|
eventDataSize: number;
|
|
6
7
|
totalSize: number;
|
|
7
8
|
}
|
|
@@ -9,6 +10,7 @@ export interface UseAudioRecorderState {
|
|
|
9
10
|
startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;
|
|
10
11
|
stopRecording: () => Promise<AudioStreamResult | null>;
|
|
11
12
|
pauseRecording: () => void;
|
|
13
|
+
resumeRecording: () => void;
|
|
12
14
|
isRecording: boolean;
|
|
13
15
|
isPaused: boolean;
|
|
14
16
|
duration: number;
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,OAAO,EAAE,MAAM,CAAC;IAChB,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,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,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,CA+MxB"}
|
|
@@ -73,6 +73,7 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
|
|
|
73
73
|
onAudioStream?.({
|
|
74
74
|
data: encoded,
|
|
75
75
|
position,
|
|
76
|
+
fileUri,
|
|
76
77
|
eventDataSize: deltaSize,
|
|
77
78
|
totalSize,
|
|
78
79
|
});
|
|
@@ -101,6 +102,7 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
|
|
|
101
102
|
onAudioStream?.({
|
|
102
103
|
data: buffer,
|
|
103
104
|
position,
|
|
105
|
+
fileUri,
|
|
104
106
|
eventDataSize: deltaSize,
|
|
105
107
|
totalSize,
|
|
106
108
|
});
|
|
@@ -126,29 +128,31 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
|
|
|
126
128
|
setIsPaused(false);
|
|
127
129
|
setSize(0);
|
|
128
130
|
setDuration(0);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
console.log(`[useAudioRecorder] start recoding`, recordingOptions);
|
|
132
|
-
}
|
|
133
|
-
const fileUrl = await ExpoAudioStreamModule.startRecording(recordingOptions);
|
|
134
|
-
return fileUrl;
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
console.error("[useAudioRecorder] Error starting recording:", error);
|
|
138
|
-
setIsRecording(false);
|
|
131
|
+
if (debug) {
|
|
132
|
+
console.log(`[useAudioRecorder] start recoding`, recordingOptions);
|
|
139
133
|
}
|
|
134
|
+
const result = await ExpoAudioStreamModule.startRecording(recordingOptions);
|
|
135
|
+
return result;
|
|
140
136
|
}, [debug]);
|
|
141
137
|
const stopRecording = useCallback(async () => {
|
|
142
|
-
console.log(`STOOOOOP NOW`);
|
|
143
138
|
const result = await ExpoAudioStreamModule.stopRecording();
|
|
144
|
-
console.log(`STOOOOOP NOW 2`);
|
|
145
139
|
setIsRecording(false);
|
|
146
140
|
setIsPaused(false);
|
|
147
141
|
return result;
|
|
148
142
|
}, []);
|
|
149
143
|
const pauseRecording = useCallback(async () => {
|
|
150
144
|
try {
|
|
151
|
-
await ExpoAudioStreamModule.
|
|
145
|
+
await ExpoAudioStreamModule.pauseRecording();
|
|
146
|
+
setIsPaused(true);
|
|
147
|
+
setIsRecording(false);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error("[useAudioRecorder] Error pausing recording:", error);
|
|
151
|
+
}
|
|
152
|
+
}, [debug]);
|
|
153
|
+
const resumeRecording = useCallback(async () => {
|
|
154
|
+
try {
|
|
155
|
+
await ExpoAudioStreamModule.resumeRecording();
|
|
152
156
|
setIsPaused(true);
|
|
153
157
|
setIsRecording(false);
|
|
154
158
|
}
|
|
@@ -160,6 +164,7 @@ export function useAudioRecorder({ onAudioStream, debug = false, }) {
|
|
|
160
164
|
startRecording,
|
|
161
165
|
stopRecording,
|
|
162
166
|
pauseRecording,
|
|
167
|
+
resumeRecording,
|
|
163
168
|
isPaused,
|
|
164
169
|
isRecording,
|
|
165
170
|
duration,
|
|
@@ -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 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"]}
|
|
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 fileUri: string;\n eventDataSize: number;\n totalSize: number;\n}\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;\n stopRecording: () => Promise<AudioStreamResult | null>;\n pauseRecording: () => void;\n resumeRecording: () => 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 fileUri,\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 fileUri,\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 if (debug) {\n console.log(`[useAudioRecorder] start recoding`, recordingOptions);\n }\n\n const result: StartAudioStreamResult =\n await ExpoAudioStreamModule.startRecording(recordingOptions);\n return result;\n },\n [debug],\n );\n\n const stopRecording = useCallback(async () => {\n const result: AudioStreamResult =\n await ExpoAudioStreamModule.stopRecording();\n setIsRecording(false);\n setIsPaused(false);\n return result;\n }, []);\n\n const pauseRecording = useCallback(async () => {\n try {\n await ExpoAudioStreamModule.pauseRecording();\n setIsPaused(true);\n setIsRecording(false);\n } catch (error) {\n console.error(\"[useAudioRecorder] Error pausing recording:\", error);\n }\n }, [debug]);\n\n const resumeRecording = useCallback(async () => {\n try {\n await ExpoAudioStreamModule.resumeRecording();\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 resumeRecording,\n isPaused,\n isRecording,\n duration,\n size,\n };\n}\n"]}
|
|
@@ -76,9 +76,9 @@ class AudioStreamManager: NSObject {
|
|
|
76
76
|
internal var recordingSettings: RecordingSettings?
|
|
77
77
|
internal var recordingUUID: UUID?
|
|
78
78
|
internal var mimeType: String = "audio/wav"
|
|
79
|
-
private var lastBuffer: AVAudioPCMBuffer?
|
|
80
79
|
private var lastBufferTime: AVAudioTime?
|
|
81
|
-
|
|
80
|
+
private var accumulatedData = Data()
|
|
81
|
+
|
|
82
82
|
weak var delegate: AudioStreamManagerDelegate? // Define the delegate here
|
|
83
83
|
|
|
84
84
|
override init() {
|
|
@@ -208,6 +208,8 @@ class AudioStreamManager: NSObject {
|
|
|
208
208
|
|
|
209
209
|
emissionInterval = max(100.0, Double(intervalMilliseconds)) / 1000.0
|
|
210
210
|
lastEmissionTime = Date()
|
|
211
|
+
accumulatedData.removeAll()
|
|
212
|
+
totalDataSize = 0
|
|
211
213
|
|
|
212
214
|
let session = AVAudioSession.sharedInstance()
|
|
213
215
|
do {
|
|
@@ -240,9 +242,6 @@ class AudioStreamManager: NSObject {
|
|
|
240
242
|
|
|
241
243
|
// Processing the current buffer
|
|
242
244
|
self.processAudioBuffer(buffer, fileURL: self.recordingFileURL!)
|
|
243
|
-
|
|
244
|
-
// Store the buffer and time as the last buffer and time
|
|
245
|
-
self.lastBuffer = buffer
|
|
246
245
|
self.lastBufferTime = time
|
|
247
246
|
}
|
|
248
247
|
|
|
@@ -302,9 +301,12 @@ class AudioStreamManager: NSObject {
|
|
|
302
301
|
return nil
|
|
303
302
|
}
|
|
304
303
|
|
|
305
|
-
//
|
|
306
|
-
if
|
|
307
|
-
|
|
304
|
+
// Emit any remaining accumulated data
|
|
305
|
+
if !accumulatedData.isEmpty {
|
|
306
|
+
let currentTime = Date()
|
|
307
|
+
let recordingTime = currentTime.timeIntervalSince(startTime)
|
|
308
|
+
delegate?.audioStreamManager(self, didReceiveAudioData: accumulatedData, recordingTime: recordingTime, totalDataSize: totalDataSize)
|
|
309
|
+
accumulatedData.removeAll()
|
|
308
310
|
}
|
|
309
311
|
|
|
310
312
|
let endTime = Date()
|
|
@@ -329,7 +331,6 @@ class AudioStreamManager: NSObject {
|
|
|
329
331
|
sampleRate: settings.sampleRate
|
|
330
332
|
)
|
|
331
333
|
recordingFileURL = nil // Reset for next recording
|
|
332
|
-
lastBuffer = nil // Reset last buffer
|
|
333
334
|
lastBufferTime = nil // Reset last buffer time
|
|
334
335
|
|
|
335
336
|
return result
|
|
@@ -383,6 +384,9 @@ class AudioStreamManager: NSObject {
|
|
|
383
384
|
data.insert(contentsOf: header, at: 0)
|
|
384
385
|
}
|
|
385
386
|
|
|
387
|
+
// Accumulate new data
|
|
388
|
+
accumulatedData.append(data)
|
|
389
|
+
|
|
386
390
|
// print("Writing data size: \(data.count) bytes") // Debug: Check the size of data being written
|
|
387
391
|
fileHandle.seekToEndOfFile()
|
|
388
392
|
fileHandle.write(data)
|
|
@@ -396,9 +400,10 @@ class AudioStreamManager: NSObject {
|
|
|
396
400
|
if let startTime = startTime {
|
|
397
401
|
let recordingTime = currentTime.timeIntervalSince(startTime)
|
|
398
402
|
// print("Emitting data: Recording time \(recordingTime) seconds, Data size \(totalDataSize) bytes")
|
|
399
|
-
self.delegate?.audioStreamManager(self, didReceiveAudioData:
|
|
403
|
+
self.delegate?.audioStreamManager(self, didReceiveAudioData: accumulatedData, recordingTime: recordingTime, totalDataSize: totalDataSize)
|
|
400
404
|
self.lastEmissionTime = currentTime // Update last emission time
|
|
401
405
|
self.lastEmittedSize = totalDataSize
|
|
406
|
+
accumulatedData.removeAll() // Reset accumulated data after emission
|
|
402
407
|
}
|
|
403
408
|
}
|
|
404
409
|
}
|
|
@@ -31,9 +31,18 @@ public class ExpoAudioStreamModule: Module, AudioStreamManagerDelegate {
|
|
|
31
31
|
let interval = options["interval"] as? Int ?? 1000
|
|
32
32
|
|
|
33
33
|
let settings = RecordingSettings(sampleRate: sampleRate, numberOfChannels: numberOfChannels, bitDepth: bitDepth)
|
|
34
|
-
let result = self.streamManager.startRecording(settings: settings, intervalMilliseconds: interval)
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
if let result = self.streamManager.startRecording(settings: settings, intervalMilliseconds: interval) {
|
|
35
|
+
let resultDict: [String: Any] = [
|
|
36
|
+
"fileUri": result.fileUri,
|
|
37
|
+
"channels": result.channels,
|
|
38
|
+
"bitDepth": result.bitDepth,
|
|
39
|
+
"sampleRate": result.sampleRate,
|
|
40
|
+
"mimeType": result.mimeType,
|
|
41
|
+
]
|
|
42
|
+
promise.resolve(resultDict)
|
|
43
|
+
} else {
|
|
44
|
+
promise.reject("ERROR", "Failed to start recording.")
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
48
|
|
|
@@ -97,9 +106,6 @@ public class ExpoAudioStreamModule: Module, AudioStreamManagerDelegate {
|
|
|
97
106
|
"streamUuid": manager.recordingUUID?.uuidString ?? UUID().uuidString
|
|
98
107
|
]
|
|
99
108
|
|
|
100
|
-
// Update the last emitted size for the next calculation
|
|
101
|
-
manager.lastEmittedSize += Int64(deltaSize)
|
|
102
|
-
|
|
103
109
|
// Emit the event to JavaScript
|
|
104
110
|
sendEvent(audioDataEvent, eventBody)
|
|
105
111
|
}
|
package/package.json
CHANGED
package/src/useAudioRecording.ts
CHANGED
|
@@ -13,6 +13,7 @@ import ExpoAudioStreamModule from "./ExpoAudioStreamModule";
|
|
|
13
13
|
export interface AudioDataEvent {
|
|
14
14
|
data: string | Blob;
|
|
15
15
|
position: number;
|
|
16
|
+
fileUri: string;
|
|
16
17
|
eventDataSize: number;
|
|
17
18
|
totalSize: number;
|
|
18
19
|
}
|
|
@@ -20,6 +21,7 @@ export interface UseAudioRecorderState {
|
|
|
20
21
|
startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;
|
|
21
22
|
stopRecording: () => Promise<AudioStreamResult | null>;
|
|
22
23
|
pauseRecording: () => void;
|
|
24
|
+
resumeRecording: () => void;
|
|
23
25
|
isRecording: boolean;
|
|
24
26
|
isPaused: boolean;
|
|
25
27
|
duration: number; // Duration of the recording
|
|
@@ -125,6 +127,7 @@ export function useAudioRecorder({
|
|
|
125
127
|
onAudioStream?.({
|
|
126
128
|
data: encoded,
|
|
127
129
|
position,
|
|
130
|
+
fileUri,
|
|
128
131
|
eventDataSize: deltaSize,
|
|
129
132
|
totalSize,
|
|
130
133
|
});
|
|
@@ -155,6 +158,7 @@ export function useAudioRecorder({
|
|
|
155
158
|
onAudioStream?.({
|
|
156
159
|
data: buffer,
|
|
157
160
|
position,
|
|
161
|
+
fileUri,
|
|
158
162
|
eventDataSize: deltaSize,
|
|
159
163
|
totalSize,
|
|
160
164
|
});
|
|
@@ -188,28 +192,20 @@ export function useAudioRecorder({
|
|
|
188
192
|
setIsPaused(false);
|
|
189
193
|
setSize(0);
|
|
190
194
|
setDuration(0);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
console.log(`[useAudioRecorder] start recoding`, recordingOptions);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const fileUrl =
|
|
197
|
-
await ExpoAudioStreamModule.startRecording(recordingOptions);
|
|
198
|
-
|
|
199
|
-
return fileUrl;
|
|
200
|
-
} catch (error) {
|
|
201
|
-
console.error("[useAudioRecorder] Error starting recording:", error);
|
|
202
|
-
setIsRecording(false);
|
|
195
|
+
if (debug) {
|
|
196
|
+
console.log(`[useAudioRecorder] start recoding`, recordingOptions);
|
|
203
197
|
}
|
|
198
|
+
|
|
199
|
+
const result: StartAudioStreamResult =
|
|
200
|
+
await ExpoAudioStreamModule.startRecording(recordingOptions);
|
|
201
|
+
return result;
|
|
204
202
|
},
|
|
205
203
|
[debug],
|
|
206
204
|
);
|
|
207
205
|
|
|
208
206
|
const stopRecording = useCallback(async () => {
|
|
209
|
-
console.log(`STOOOOOP NOW`);
|
|
210
207
|
const result: AudioStreamResult =
|
|
211
208
|
await ExpoAudioStreamModule.stopRecording();
|
|
212
|
-
console.log(`STOOOOOP NOW 2`);
|
|
213
209
|
setIsRecording(false);
|
|
214
210
|
setIsPaused(false);
|
|
215
211
|
return result;
|
|
@@ -217,7 +213,17 @@ export function useAudioRecorder({
|
|
|
217
213
|
|
|
218
214
|
const pauseRecording = useCallback(async () => {
|
|
219
215
|
try {
|
|
220
|
-
await ExpoAudioStreamModule.
|
|
216
|
+
await ExpoAudioStreamModule.pauseRecording();
|
|
217
|
+
setIsPaused(true);
|
|
218
|
+
setIsRecording(false);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error("[useAudioRecorder] Error pausing recording:", error);
|
|
221
|
+
}
|
|
222
|
+
}, [debug]);
|
|
223
|
+
|
|
224
|
+
const resumeRecording = useCallback(async () => {
|
|
225
|
+
try {
|
|
226
|
+
await ExpoAudioStreamModule.resumeRecording();
|
|
221
227
|
setIsPaused(true);
|
|
222
228
|
setIsRecording(false);
|
|
223
229
|
} catch (error) {
|
|
@@ -229,6 +235,7 @@ export function useAudioRecorder({
|
|
|
229
235
|
startRecording,
|
|
230
236
|
stopRecording,
|
|
231
237
|
pauseRecording,
|
|
238
|
+
resumeRecording,
|
|
232
239
|
isPaused,
|
|
233
240
|
isRecording,
|
|
234
241
|
duration,
|