@siteed/expo-audio-stream 1.0.1 → 1.0.3
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/.size-limit.json +6 -0
- package/README.md +6 -6
- package/android/build.gradle +5 -0
- package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +120 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +34 -4
- package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +635 -0
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +194 -79
- package/android/src/main/java/net/siteed/audiostream/Constants.kt +1 -0
- package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +48 -2
- package/android/src/main/java/net/siteed/audiostream/FFT.kt +44 -0
- package/android/src/main/java/net/siteed/audiostream/Features.kt +56 -0
- package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +12 -0
- package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +56 -0
- package/app.plugin.js +1 -1
- package/build/AudioAnalysis/AudioAnalysis.types.d.ts +76 -0
- package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -0
- package/build/AudioAnalysis/AudioAnalysis.types.js +3 -0
- package/build/AudioAnalysis/AudioAnalysis.types.js.map +1 -0
- package/build/AudioAnalysis/extractAudioAnalysis.d.ts +4 -0
- package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js +101 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
- package/build/AudioAnalysis/extractWaveform.d.ts +8 -0
- package/build/AudioAnalysis/extractWaveform.d.ts.map +1 -0
- package/build/AudioAnalysis/extractWaveform.js +14 -0
- package/build/AudioAnalysis/extractWaveform.js.map +1 -0
- package/build/AudioRecorder.provider.d.ts +14 -1
- package/build/AudioRecorder.provider.d.ts.map +1 -1
- package/build/AudioRecorder.provider.js +18 -5
- package/build/AudioRecorder.provider.js.map +1 -1
- package/build/ExpoAudioStream.native.d.ts +3 -0
- package/build/ExpoAudioStream.native.d.ts.map +1 -0
- package/build/ExpoAudioStream.native.js +6 -0
- package/build/ExpoAudioStream.native.js.map +1 -0
- package/build/ExpoAudioStream.types.d.ts +35 -20
- package/build/ExpoAudioStream.types.d.ts.map +1 -1
- package/build/ExpoAudioStream.types.js.map +1 -1
- package/build/ExpoAudioStream.web.d.ts +42 -0
- package/build/ExpoAudioStream.web.d.ts.map +1 -0
- package/build/ExpoAudioStream.web.js +185 -0
- package/build/ExpoAudioStream.web.js.map +1 -0
- package/build/ExpoAudioStreamModule.d.ts +2 -2
- package/build/ExpoAudioStreamModule.d.ts.map +1 -1
- package/build/ExpoAudioStreamModule.js +16 -3
- package/build/ExpoAudioStreamModule.js.map +1 -1
- package/build/WebRecorder.web.d.ts +51 -0
- package/build/WebRecorder.web.d.ts.map +1 -0
- package/build/WebRecorder.web.js +288 -0
- package/build/WebRecorder.web.js.map +1 -0
- package/build/constants.d.ts +11 -0
- package/build/constants.d.ts.map +1 -0
- package/build/constants.js +14 -0
- package/build/constants.js.map +1 -0
- package/build/events.d.ts +6 -0
- package/build/events.d.ts.map +1 -0
- package/build/events.js +15 -0
- package/build/events.js.map +1 -0
- package/build/index.d.ts +8 -7
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -14
- package/build/index.js.map +1 -1
- package/build/logger.d.ts +9 -0
- package/build/logger.d.ts.map +1 -0
- package/build/logger.js +17 -0
- package/build/logger.js.map +1 -0
- package/build/useAudioRecorder.d.ts +37 -0
- package/build/useAudioRecorder.d.ts.map +1 -0
- package/build/useAudioRecorder.js +271 -0
- package/build/useAudioRecorder.js.map +1 -0
- package/build/utils/convertPCMToFloat32.d.ts +11 -0
- package/build/utils/convertPCMToFloat32.d.ts.map +1 -0
- package/build/utils/convertPCMToFloat32.js +41 -0
- package/build/utils/convertPCMToFloat32.js.map +1 -0
- package/build/utils/encodingToBitDepth.d.ts +5 -0
- package/build/utils/encodingToBitDepth.d.ts.map +1 -0
- package/build/utils/encodingToBitDepth.js +13 -0
- package/build/utils/encodingToBitDepth.js.map +1 -0
- package/build/utils/getWavFileInfo.d.ts +25 -0
- package/build/utils/getWavFileInfo.d.ts.map +1 -0
- package/build/utils/getWavFileInfo.js +89 -0
- package/build/utils/getWavFileInfo.js.map +1 -0
- package/build/utils/writeWavHeader.d.ts +9 -0
- package/build/utils/writeWavHeader.d.ts.map +1 -0
- package/build/utils/writeWavHeader.js +41 -0
- package/build/utils/writeWavHeader.js.map +1 -0
- package/build/workers/InlineFeaturesExtractor.web.d.ts +2 -0
- package/build/workers/InlineFeaturesExtractor.web.d.ts.map +1 -0
- package/build/workers/InlineFeaturesExtractor.web.js +303 -0
- package/build/workers/InlineFeaturesExtractor.web.js.map +1 -0
- package/build/workers/inlineAudioWebWorker.web.d.ts +2 -0
- package/build/workers/inlineAudioWebWorker.web.d.ts.map +1 -0
- package/build/workers/inlineAudioWebWorker.web.js +243 -0
- package/build/workers/inlineAudioWebWorker.web.js.map +1 -0
- package/expo-module.config.json +13 -4
- package/ios/AudioAnalysisData.swift +39 -0
- package/ios/AudioProcessingHelpers.swift +59 -0
- package/ios/AudioProcessor.swift +317 -0
- package/ios/AudioStreamError.swift +7 -0
- package/ios/AudioStreamManager.swift +243 -54
- package/ios/AudioStreamManagerDelegate.swift +4 -0
- package/ios/DataPoint.swift +41 -0
- package/ios/ExpoAudioStreamModule.swift +198 -6
- package/ios/Features.swift +44 -0
- package/ios/RecordingResult.swift +19 -0
- package/ios/RecordingSettings.swift +13 -0
- package/ios/WaveformExtractor.swift +105 -0
- package/package.json +13 -12
- package/plugin/tsconfig.json +13 -8
- package/publish.sh +8 -0
- package/src/AudioAnalysis/AudioAnalysis.types.ts +85 -0
- package/src/AudioAnalysis/extractAudioAnalysis.ts +136 -0
- package/src/AudioAnalysis/extractWaveform.ts +25 -0
- package/src/AudioRecorder.provider.tsx +36 -8
- package/src/ExpoAudioStream.native.ts +6 -0
- package/src/ExpoAudioStream.types.ts +50 -25
- package/src/ExpoAudioStream.web.ts +229 -0
- package/src/ExpoAudioStreamModule.ts +22 -3
- package/src/WebRecorder.web.ts +416 -0
- package/src/constants.ts +18 -0
- package/src/events.ts +25 -0
- package/src/index.ts +14 -29
- package/src/logger.ts +26 -0
- package/src/useAudioRecorder.tsx +415 -0
- package/src/utils/convertPCMToFloat32.ts +48 -0
- package/src/utils/encodingToBitDepth.ts +18 -0
- package/src/utils/getWavFileInfo.ts +125 -0
- package/src/utils/writeWavHeader.ts +56 -0
- package/src/workers/InlineFeaturesExtractor.web.tsx +302 -0
- package/src/workers/inlineAudioWebWorker.web.tsx +242 -0
- package/build/ExpoAudioStreamModule.web.d.ts +0 -37
- package/build/ExpoAudioStreamModule.web.d.ts.map +0 -1
- package/build/ExpoAudioStreamModule.web.js +0 -156
- package/build/ExpoAudioStreamModule.web.js.map +0 -1
- package/build/useAudioRecording.d.ts +0 -23
- package/build/useAudioRecording.d.ts.map +0 -1
- package/build/useAudioRecording.js +0 -189
- package/build/useAudioRecording.js.map +0 -1
- package/docs/demo.gif +0 -0
- package/release-it.js +0 -18
- package/src/ExpoAudioStreamModule.web.ts +0 -181
- package/src/useAudioRecording.ts +0 -268
- package/yarn-error.log +0 -7793
package/src/useAudioRecording.ts
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { Platform } from "expo-modules-core";
|
|
2
|
-
import { useCallback, useEffect, useReducer, useRef } from "react";
|
|
3
|
-
|
|
4
|
-
import { addAudioEventListener } from ".";
|
|
5
|
-
import {
|
|
6
|
-
AudioEventPayload,
|
|
7
|
-
AudioStreamResult,
|
|
8
|
-
AudioStreamStatus,
|
|
9
|
-
RecordingConfig,
|
|
10
|
-
StartAudioStreamResult,
|
|
11
|
-
} from "./ExpoAudioStream.types";
|
|
12
|
-
import ExpoAudioStreamModule from "./ExpoAudioStreamModule";
|
|
13
|
-
|
|
14
|
-
export interface AudioDataEvent {
|
|
15
|
-
data: string | Blob;
|
|
16
|
-
position: number;
|
|
17
|
-
fileUri: string;
|
|
18
|
-
eventDataSize: number;
|
|
19
|
-
totalSize: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface UseAudioRecorderProps {
|
|
23
|
-
debug?: boolean;
|
|
24
|
-
}
|
|
25
|
-
export interface UseAudioRecorderState {
|
|
26
|
-
startRecording: (_: RecordingConfig) => Promise<StartAudioStreamResult>;
|
|
27
|
-
stopRecording: () => Promise<AudioStreamResult | null>;
|
|
28
|
-
pauseRecording: () => void;
|
|
29
|
-
resumeRecording: () => void;
|
|
30
|
-
isRecording: boolean;
|
|
31
|
-
isPaused: boolean;
|
|
32
|
-
duration: number; // Duration of the recording
|
|
33
|
-
size: number; // Size in bytes of the recorded audio
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface RecorderState {
|
|
37
|
-
isRecording: boolean;
|
|
38
|
-
isPaused: boolean;
|
|
39
|
-
duration: number;
|
|
40
|
-
size: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
type RecorderAction =
|
|
44
|
-
| { type: "START" | "STOP" | "PAUSE" | "RESUME" }
|
|
45
|
-
| { type: "UPDATE_STATUS"; payload: { duration: number; size: number } };
|
|
46
|
-
|
|
47
|
-
function recorderReducer(
|
|
48
|
-
state: RecorderState,
|
|
49
|
-
action: RecorderAction,
|
|
50
|
-
): RecorderState {
|
|
51
|
-
switch (action.type) {
|
|
52
|
-
case "START":
|
|
53
|
-
return {
|
|
54
|
-
...state,
|
|
55
|
-
isRecording: true,
|
|
56
|
-
isPaused: false,
|
|
57
|
-
duration: 0,
|
|
58
|
-
size: 0,
|
|
59
|
-
};
|
|
60
|
-
case "STOP":
|
|
61
|
-
return { ...state, isRecording: false, isPaused: false };
|
|
62
|
-
case "PAUSE":
|
|
63
|
-
return { ...state, isPaused: true, isRecording: false };
|
|
64
|
-
case "RESUME":
|
|
65
|
-
return { ...state, isPaused: false, isRecording: true };
|
|
66
|
-
case "UPDATE_STATUS":
|
|
67
|
-
return {
|
|
68
|
-
...state,
|
|
69
|
-
duration: action.payload.duration,
|
|
70
|
-
size: action.payload.size,
|
|
71
|
-
};
|
|
72
|
-
default:
|
|
73
|
-
return state;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const TAG = "[ useAudioRecorder ] ";
|
|
77
|
-
|
|
78
|
-
export function useAudioRecorder({
|
|
79
|
-
debug = false,
|
|
80
|
-
}: UseAudioRecorderProps = {}): UseAudioRecorderState {
|
|
81
|
-
const [state, dispatch] = useReducer(recorderReducer, {
|
|
82
|
-
isRecording: false,
|
|
83
|
-
isPaused: false,
|
|
84
|
-
duration: 0,
|
|
85
|
-
size: 0,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const onAudioStreamRef = useRef<
|
|
89
|
-
((_: AudioDataEvent) => Promise<void>) | null
|
|
90
|
-
>(null);
|
|
91
|
-
|
|
92
|
-
const logDebug = useCallback(
|
|
93
|
-
(message: string, data?: any) => {
|
|
94
|
-
if (debug) {
|
|
95
|
-
if (data) {
|
|
96
|
-
console.log(`${TAG} ${message}`, data);
|
|
97
|
-
} else {
|
|
98
|
-
console.log(`${TAG} ${message}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
[debug],
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const handleAudioEvent = useCallback(
|
|
106
|
-
async (eventData: AudioEventPayload) => {
|
|
107
|
-
const {
|
|
108
|
-
fileUri,
|
|
109
|
-
deltaSize,
|
|
110
|
-
totalSize,
|
|
111
|
-
lastEmittedSize,
|
|
112
|
-
position,
|
|
113
|
-
streamUuid,
|
|
114
|
-
encoded,
|
|
115
|
-
mimeType,
|
|
116
|
-
buffer,
|
|
117
|
-
} = eventData;
|
|
118
|
-
logDebug(`useAudioRecorder] Received audio event:`, {
|
|
119
|
-
fileUri,
|
|
120
|
-
deltaSize,
|
|
121
|
-
totalSize,
|
|
122
|
-
position,
|
|
123
|
-
mimeType,
|
|
124
|
-
lastEmittedSize,
|
|
125
|
-
streamUuid,
|
|
126
|
-
encodedLength: encoded?.length,
|
|
127
|
-
});
|
|
128
|
-
if (deltaSize === 0) {
|
|
129
|
-
// Ignore packet with no data
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
// Coming from native ( ios / android ) otherwise buffer is set
|
|
134
|
-
if (Platform.OS !== "web") {
|
|
135
|
-
// Read the audio file as a base64 string for comparison
|
|
136
|
-
if (!encoded) {
|
|
137
|
-
console.error(`${TAG} Encoded audio data is missing`);
|
|
138
|
-
throw new Error("Encoded audio data is missing");
|
|
139
|
-
}
|
|
140
|
-
onAudioStreamRef.current?.({
|
|
141
|
-
data: encoded,
|
|
142
|
-
position,
|
|
143
|
-
fileUri,
|
|
144
|
-
eventDataSize: deltaSize,
|
|
145
|
-
totalSize,
|
|
146
|
-
});
|
|
147
|
-
} else if (buffer) {
|
|
148
|
-
// Coming from web
|
|
149
|
-
onAudioStreamRef.current?.({
|
|
150
|
-
data: buffer,
|
|
151
|
-
position,
|
|
152
|
-
fileUri,
|
|
153
|
-
eventDataSize: deltaSize,
|
|
154
|
-
totalSize,
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
} catch (error) {
|
|
158
|
-
console.error(`${TAG} Error processing audio event:`, error);
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
[logDebug],
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
const checkStatus = useCallback(async () => {
|
|
165
|
-
try {
|
|
166
|
-
if (!state.isRecording) {
|
|
167
|
-
logDebug(`${TAG} Not recording, exiting status check.`);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const status: AudioStreamStatus = ExpoAudioStreamModule.status();
|
|
172
|
-
if (debug) {
|
|
173
|
-
logDebug(`${TAG} Status:`, status);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (!status.isRecording) {
|
|
177
|
-
dispatch({ type: "STOP" });
|
|
178
|
-
} else {
|
|
179
|
-
dispatch({
|
|
180
|
-
type: "UPDATE_STATUS",
|
|
181
|
-
payload: { duration: status.duration, size: status.size },
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
} catch (error) {
|
|
185
|
-
console.error(`${TAG} Error getting status:`, error);
|
|
186
|
-
}
|
|
187
|
-
}, [state.isRecording, logDebug]);
|
|
188
|
-
|
|
189
|
-
useEffect(() => {
|
|
190
|
-
let interval: number;
|
|
191
|
-
if (state.isRecording) {
|
|
192
|
-
interval = setInterval(checkStatus, 1000);
|
|
193
|
-
}
|
|
194
|
-
return () => {
|
|
195
|
-
if (interval) {
|
|
196
|
-
clearInterval(interval);
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
}, [checkStatus, state.isRecording]);
|
|
200
|
-
|
|
201
|
-
useEffect(() => {
|
|
202
|
-
logDebug(`${TAG} Registering audio event listener`);
|
|
203
|
-
const subscribe = addAudioEventListener(handleAudioEvent);
|
|
204
|
-
logDebug(`${TAG} Subscribed to audio event listener`, subscribe);
|
|
205
|
-
|
|
206
|
-
return () => {
|
|
207
|
-
logDebug(`${TAG} Removing audio event listener`);
|
|
208
|
-
subscribe.remove();
|
|
209
|
-
};
|
|
210
|
-
}, [handleAudioEvent, logDebug]);
|
|
211
|
-
|
|
212
|
-
const startRecording = useCallback(
|
|
213
|
-
async (recordingOptions: RecordingConfig) => {
|
|
214
|
-
if (debug) {
|
|
215
|
-
logDebug(`${TAG} start recoding`, recordingOptions);
|
|
216
|
-
}
|
|
217
|
-
// remove onAudioStream from recordingOptions
|
|
218
|
-
const { onAudioStream, ...options } = recordingOptions;
|
|
219
|
-
if (typeof onAudioStream === "function") {
|
|
220
|
-
onAudioStreamRef.current = onAudioStream;
|
|
221
|
-
} else {
|
|
222
|
-
console.warn(`${TAG} onAudioStream is not a function`, onAudioStream);
|
|
223
|
-
onAudioStreamRef.current = null;
|
|
224
|
-
}
|
|
225
|
-
const startResult: StartAudioStreamResult =
|
|
226
|
-
await ExpoAudioStreamModule.startRecording(options);
|
|
227
|
-
dispatch({ type: "START" });
|
|
228
|
-
|
|
229
|
-
return startResult;
|
|
230
|
-
},
|
|
231
|
-
[logDebug],
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
const stopRecording = useCallback(async () => {
|
|
235
|
-
logDebug(`${TAG} stoping recording`);
|
|
236
|
-
const stopResult: AudioStreamResult =
|
|
237
|
-
await ExpoAudioStreamModule.stopRecording();
|
|
238
|
-
onAudioStreamRef.current = null;
|
|
239
|
-
logDebug(`${TAG} recording stopped`, stopResult);
|
|
240
|
-
dispatch({ type: "STOP" });
|
|
241
|
-
return stopResult;
|
|
242
|
-
}, [logDebug]);
|
|
243
|
-
|
|
244
|
-
const pauseRecording = useCallback(async () => {
|
|
245
|
-
logDebug(`${TAG} pause recording`);
|
|
246
|
-
const pauseResult = await ExpoAudioStreamModule.pauseRecording();
|
|
247
|
-
dispatch({ type: "PAUSE" });
|
|
248
|
-
return pauseResult;
|
|
249
|
-
}, [logDebug]);
|
|
250
|
-
|
|
251
|
-
const resumeRecording = useCallback(async () => {
|
|
252
|
-
logDebug(`${TAG} resume recording`);
|
|
253
|
-
const resumeResult = await ExpoAudioStreamModule.resumeRecording();
|
|
254
|
-
dispatch({ type: "RESUME" });
|
|
255
|
-
return resumeResult;
|
|
256
|
-
}, [logDebug]);
|
|
257
|
-
|
|
258
|
-
return {
|
|
259
|
-
startRecording,
|
|
260
|
-
stopRecording,
|
|
261
|
-
pauseRecording,
|
|
262
|
-
resumeRecording,
|
|
263
|
-
isPaused: state.isPaused,
|
|
264
|
-
isRecording: state.isRecording,
|
|
265
|
-
duration: state.duration,
|
|
266
|
-
size: state.size,
|
|
267
|
-
};
|
|
268
|
-
}
|