@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.
Files changed (142) hide show
  1. package/.size-limit.json +6 -0
  2. package/README.md +6 -6
  3. package/android/build.gradle +5 -0
  4. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +120 -0
  5. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +34 -4
  6. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +635 -0
  7. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +194 -79
  8. package/android/src/main/java/net/siteed/audiostream/Constants.kt +1 -0
  9. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +48 -2
  10. package/android/src/main/java/net/siteed/audiostream/FFT.kt +44 -0
  11. package/android/src/main/java/net/siteed/audiostream/Features.kt +56 -0
  12. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +12 -0
  13. package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +56 -0
  14. package/app.plugin.js +1 -1
  15. package/build/AudioAnalysis/AudioAnalysis.types.d.ts +76 -0
  16. package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -0
  17. package/build/AudioAnalysis/AudioAnalysis.types.js +3 -0
  18. package/build/AudioAnalysis/AudioAnalysis.types.js.map +1 -0
  19. package/build/AudioAnalysis/extractAudioAnalysis.d.ts +4 -0
  20. package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -0
  21. package/build/AudioAnalysis/extractAudioAnalysis.js +101 -0
  22. package/build/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
  23. package/build/AudioAnalysis/extractWaveform.d.ts +8 -0
  24. package/build/AudioAnalysis/extractWaveform.d.ts.map +1 -0
  25. package/build/AudioAnalysis/extractWaveform.js +14 -0
  26. package/build/AudioAnalysis/extractWaveform.js.map +1 -0
  27. package/build/AudioRecorder.provider.d.ts +14 -1
  28. package/build/AudioRecorder.provider.d.ts.map +1 -1
  29. package/build/AudioRecorder.provider.js +18 -5
  30. package/build/AudioRecorder.provider.js.map +1 -1
  31. package/build/ExpoAudioStream.native.d.ts +3 -0
  32. package/build/ExpoAudioStream.native.d.ts.map +1 -0
  33. package/build/ExpoAudioStream.native.js +6 -0
  34. package/build/ExpoAudioStream.native.js.map +1 -0
  35. package/build/ExpoAudioStream.types.d.ts +35 -20
  36. package/build/ExpoAudioStream.types.d.ts.map +1 -1
  37. package/build/ExpoAudioStream.types.js.map +1 -1
  38. package/build/ExpoAudioStream.web.d.ts +42 -0
  39. package/build/ExpoAudioStream.web.d.ts.map +1 -0
  40. package/build/ExpoAudioStream.web.js +185 -0
  41. package/build/ExpoAudioStream.web.js.map +1 -0
  42. package/build/ExpoAudioStreamModule.d.ts +2 -2
  43. package/build/ExpoAudioStreamModule.d.ts.map +1 -1
  44. package/build/ExpoAudioStreamModule.js +16 -3
  45. package/build/ExpoAudioStreamModule.js.map +1 -1
  46. package/build/WebRecorder.web.d.ts +51 -0
  47. package/build/WebRecorder.web.d.ts.map +1 -0
  48. package/build/WebRecorder.web.js +288 -0
  49. package/build/WebRecorder.web.js.map +1 -0
  50. package/build/constants.d.ts +11 -0
  51. package/build/constants.d.ts.map +1 -0
  52. package/build/constants.js +14 -0
  53. package/build/constants.js.map +1 -0
  54. package/build/events.d.ts +6 -0
  55. package/build/events.d.ts.map +1 -0
  56. package/build/events.js +15 -0
  57. package/build/events.js.map +1 -0
  58. package/build/index.d.ts +8 -7
  59. package/build/index.d.ts.map +1 -1
  60. package/build/index.js +7 -14
  61. package/build/index.js.map +1 -1
  62. package/build/logger.d.ts +9 -0
  63. package/build/logger.d.ts.map +1 -0
  64. package/build/logger.js +17 -0
  65. package/build/logger.js.map +1 -0
  66. package/build/useAudioRecorder.d.ts +37 -0
  67. package/build/useAudioRecorder.d.ts.map +1 -0
  68. package/build/useAudioRecorder.js +271 -0
  69. package/build/useAudioRecorder.js.map +1 -0
  70. package/build/utils/convertPCMToFloat32.d.ts +11 -0
  71. package/build/utils/convertPCMToFloat32.d.ts.map +1 -0
  72. package/build/utils/convertPCMToFloat32.js +41 -0
  73. package/build/utils/convertPCMToFloat32.js.map +1 -0
  74. package/build/utils/encodingToBitDepth.d.ts +5 -0
  75. package/build/utils/encodingToBitDepth.d.ts.map +1 -0
  76. package/build/utils/encodingToBitDepth.js +13 -0
  77. package/build/utils/encodingToBitDepth.js.map +1 -0
  78. package/build/utils/getWavFileInfo.d.ts +25 -0
  79. package/build/utils/getWavFileInfo.d.ts.map +1 -0
  80. package/build/utils/getWavFileInfo.js +89 -0
  81. package/build/utils/getWavFileInfo.js.map +1 -0
  82. package/build/utils/writeWavHeader.d.ts +9 -0
  83. package/build/utils/writeWavHeader.d.ts.map +1 -0
  84. package/build/utils/writeWavHeader.js +41 -0
  85. package/build/utils/writeWavHeader.js.map +1 -0
  86. package/build/workers/InlineFeaturesExtractor.web.d.ts +2 -0
  87. package/build/workers/InlineFeaturesExtractor.web.d.ts.map +1 -0
  88. package/build/workers/InlineFeaturesExtractor.web.js +303 -0
  89. package/build/workers/InlineFeaturesExtractor.web.js.map +1 -0
  90. package/build/workers/inlineAudioWebWorker.web.d.ts +2 -0
  91. package/build/workers/inlineAudioWebWorker.web.d.ts.map +1 -0
  92. package/build/workers/inlineAudioWebWorker.web.js +243 -0
  93. package/build/workers/inlineAudioWebWorker.web.js.map +1 -0
  94. package/expo-module.config.json +13 -4
  95. package/ios/AudioAnalysisData.swift +39 -0
  96. package/ios/AudioProcessingHelpers.swift +59 -0
  97. package/ios/AudioProcessor.swift +317 -0
  98. package/ios/AudioStreamError.swift +7 -0
  99. package/ios/AudioStreamManager.swift +243 -54
  100. package/ios/AudioStreamManagerDelegate.swift +4 -0
  101. package/ios/DataPoint.swift +41 -0
  102. package/ios/ExpoAudioStreamModule.swift +198 -6
  103. package/ios/Features.swift +44 -0
  104. package/ios/RecordingResult.swift +19 -0
  105. package/ios/RecordingSettings.swift +13 -0
  106. package/ios/WaveformExtractor.swift +105 -0
  107. package/package.json +13 -12
  108. package/plugin/tsconfig.json +13 -8
  109. package/publish.sh +8 -0
  110. package/src/AudioAnalysis/AudioAnalysis.types.ts +85 -0
  111. package/src/AudioAnalysis/extractAudioAnalysis.ts +136 -0
  112. package/src/AudioAnalysis/extractWaveform.ts +25 -0
  113. package/src/AudioRecorder.provider.tsx +36 -8
  114. package/src/ExpoAudioStream.native.ts +6 -0
  115. package/src/ExpoAudioStream.types.ts +50 -25
  116. package/src/ExpoAudioStream.web.ts +229 -0
  117. package/src/ExpoAudioStreamModule.ts +22 -3
  118. package/src/WebRecorder.web.ts +416 -0
  119. package/src/constants.ts +18 -0
  120. package/src/events.ts +25 -0
  121. package/src/index.ts +14 -29
  122. package/src/logger.ts +26 -0
  123. package/src/useAudioRecorder.tsx +415 -0
  124. package/src/utils/convertPCMToFloat32.ts +48 -0
  125. package/src/utils/encodingToBitDepth.ts +18 -0
  126. package/src/utils/getWavFileInfo.ts +125 -0
  127. package/src/utils/writeWavHeader.ts +56 -0
  128. package/src/workers/InlineFeaturesExtractor.web.tsx +302 -0
  129. package/src/workers/inlineAudioWebWorker.web.tsx +242 -0
  130. package/build/ExpoAudioStreamModule.web.d.ts +0 -37
  131. package/build/ExpoAudioStreamModule.web.d.ts.map +0 -1
  132. package/build/ExpoAudioStreamModule.web.js +0 -156
  133. package/build/ExpoAudioStreamModule.web.js.map +0 -1
  134. package/build/useAudioRecording.d.ts +0 -23
  135. package/build/useAudioRecording.d.ts.map +0 -1
  136. package/build/useAudioRecording.js +0 -189
  137. package/build/useAudioRecording.js.map +0 -1
  138. package/docs/demo.gif +0 -0
  139. package/release-it.js +0 -18
  140. package/src/ExpoAudioStreamModule.web.ts +0 -181
  141. package/src/useAudioRecording.ts +0 -268
  142. package/yarn-error.log +0 -7793
@@ -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
- }