@siteed/expo-audio-studio 2.4.1 → 2.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/CHANGELOG.md +14 -1
- package/README.md +25 -0
- package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +22 -0
- package/android/src/main/java/net/siteed/audiostream/AudioDeviceManager.kt +1501 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +10 -5
- package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +27 -25
- package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +73 -71
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +576 -252
- package/android/src/main/java/net/siteed/audiostream/Constants.kt +17 -1
- package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +419 -155
- package/android/src/main/java/net/siteed/audiostream/LogUtils.kt +65 -0
- package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +9 -1
- package/build/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
- package/build/AudioDeviceManager.d.ts +107 -0
- package/build/AudioDeviceManager.d.ts.map +1 -0
- package/build/AudioDeviceManager.js +493 -0
- package/build/AudioDeviceManager.js.map +1 -0
- package/build/AudioRecorder.provider.d.ts.map +1 -1
- package/build/AudioRecorder.provider.js +3 -0
- package/build/AudioRecorder.provider.js.map +1 -1
- package/build/ExpoAudioStream.types.d.ts +104 -1
- package/build/ExpoAudioStream.types.d.ts.map +1 -1
- package/build/ExpoAudioStream.types.js +7 -1
- package/build/ExpoAudioStream.types.js.map +1 -1
- package/build/ExpoAudioStream.web.d.ts +37 -0
- package/build/ExpoAudioStream.web.d.ts.map +1 -1
- package/build/ExpoAudioStream.web.js +478 -62
- package/build/ExpoAudioStream.web.js.map +1 -1
- package/build/ExpoAudioStreamModule.d.ts.map +1 -1
- package/build/ExpoAudioStreamModule.js +20 -0
- package/build/ExpoAudioStreamModule.js.map +1 -1
- package/build/WebRecorder.web.d.ts +74 -11
- package/build/WebRecorder.web.d.ts.map +1 -1
- package/build/WebRecorder.web.js +390 -74
- package/build/WebRecorder.web.js.map +1 -1
- package/build/hooks/useAudioDevices.d.ts +14 -0
- package/build/hooks/useAudioDevices.d.ts.map +1 -0
- package/build/hooks/useAudioDevices.js +151 -0
- package/build/hooks/useAudioDevices.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/build/useAudioRecorder.d.ts +1 -0
- package/build/useAudioRecorder.d.ts.map +1 -1
- package/build/useAudioRecorder.js +20 -1
- package/build/useAudioRecorder.js.map +1 -1
- package/build/utils/BlobFix.d.ts.map +1 -1
- package/build/utils/BlobFix.js +2 -2
- package/build/utils/BlobFix.js.map +1 -1
- package/build/utils/writeWavHeader.d.ts +3 -18
- package/build/utils/writeWavHeader.d.ts.map +1 -1
- package/build/utils/writeWavHeader.js +19 -26
- package/build/utils/writeWavHeader.js.map +1 -1
- package/build/workers/InlineFeaturesExtractor.web.d.ts +1 -1
- package/build/workers/InlineFeaturesExtractor.web.d.ts.map +1 -1
- package/build/workers/InlineFeaturesExtractor.web.js +27 -26
- package/build/workers/InlineFeaturesExtractor.web.js.map +1 -1
- package/build/workers/inlineAudioWebWorker.web.d.ts +1 -1
- package/build/workers/inlineAudioWebWorker.web.d.ts.map +1 -1
- package/build/workers/inlineAudioWebWorker.web.js +25 -1
- package/build/workers/inlineAudioWebWorker.web.js.map +1 -1
- package/ios/AudioDeviceManager.swift +654 -0
- package/ios/AudioStreamManager.swift +964 -760
- package/ios/ExpoAudioStreamModule.swift +174 -19
- package/ios/Features.swift +1 -1
- package/ios/ISSUE_IOS.md +45 -0
- package/ios/Logger.swift +13 -1
- package/ios/RecordingSettings.swift +12 -0
- package/package.json +2 -2
- package/src/AudioAnalysis/AudioAnalysis.types.ts +2 -2
- package/src/AudioDeviceManager.ts +571 -0
- package/src/AudioRecorder.provider.tsx +3 -0
- package/src/ExpoAudioStream.types.ts +113 -1
- package/src/ExpoAudioStream.web.ts +609 -69
- package/src/ExpoAudioStreamModule.ts +23 -0
- package/src/WebRecorder.web.ts +482 -92
- package/src/hooks/useAudioDevices.ts +180 -0
- package/src/index.ts +6 -0
- package/src/types/crc-32.d.ts +6 -6
- package/src/useAudioRecorder.tsx +27 -1
- package/src/utils/BlobFix.ts +6 -4
- package/src/utils/writeWavHeader.ts +26 -25
- package/src/workers/InlineFeaturesExtractor.web.tsx +27 -26
- package/src/workers/inlineAudioWebWorker.web.tsx +25 -1
|
@@ -145,7 +145,7 @@ export interface StartRecordingResult {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
export interface AudioSessionConfig {
|
|
148
|
-
/**
|
|
148
|
+
/**
|
|
149
149
|
* Audio session category that defines the audio behavior
|
|
150
150
|
* - 'Ambient': Audio continues with silent switch, mixes with other audio
|
|
151
151
|
* - 'SoloAmbient': Audio continues with silent switch, interrupts other audio
|
|
@@ -207,6 +207,19 @@ export interface IOSConfig {
|
|
|
207
207
|
audioSession?: AudioSessionConfig
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
/** Web platform specific configuration options */
|
|
211
|
+
export interface WebConfig {
|
|
212
|
+
/**
|
|
213
|
+
* Whether to store uncompressed audio data for WAV generation
|
|
214
|
+
*
|
|
215
|
+
* When true, all PCM chunks are stored in memory to create a WAV file when compression is disabled
|
|
216
|
+
* When false, uncompressed audio won't be available, but memory usage will be lower
|
|
217
|
+
*
|
|
218
|
+
* Default: true (for backward compatibility)
|
|
219
|
+
*/
|
|
220
|
+
storeUncompressedAudio?: boolean
|
|
221
|
+
}
|
|
222
|
+
|
|
210
223
|
// Add new type for interruption reasons
|
|
211
224
|
export type RecordingInterruptionReason =
|
|
212
225
|
/** Audio focus was lost to another app */
|
|
@@ -219,6 +232,14 @@ export type RecordingInterruptionReason =
|
|
|
219
232
|
| 'phoneCallEnded'
|
|
220
233
|
/** Recording was stopped by the system or another app */
|
|
221
234
|
| 'recordingStopped'
|
|
235
|
+
/** Recording device was disconnected */
|
|
236
|
+
| 'deviceDisconnected'
|
|
237
|
+
/** Recording switched to default device after disconnection */
|
|
238
|
+
| 'deviceFallback'
|
|
239
|
+
/** A new audio device was connected */
|
|
240
|
+
| 'deviceConnected'
|
|
241
|
+
/** Device switching failed */
|
|
242
|
+
| 'deviceSwitchFailed'
|
|
222
243
|
|
|
223
244
|
// Add new interface for interruption events
|
|
224
245
|
export interface RecordingInterruptionEvent {
|
|
@@ -228,6 +249,48 @@ export interface RecordingInterruptionEvent {
|
|
|
228
249
|
isPaused: boolean
|
|
229
250
|
}
|
|
230
251
|
|
|
252
|
+
export interface AudioDeviceCapabilities {
|
|
253
|
+
/** Supported sample rates for the device */
|
|
254
|
+
sampleRates: number[]
|
|
255
|
+
/** Supported channel counts for the device */
|
|
256
|
+
channelCounts: number[]
|
|
257
|
+
/** Supported bit depths for the device */
|
|
258
|
+
bitDepths: number[]
|
|
259
|
+
/** Whether the device supports echo cancellation */
|
|
260
|
+
hasEchoCancellation?: boolean
|
|
261
|
+
/** Whether the device supports noise suppression */
|
|
262
|
+
hasNoiseSuppression?: boolean
|
|
263
|
+
/** Whether the device supports automatic gain control */
|
|
264
|
+
hasAutomaticGainControl?: boolean
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface AudioDevice {
|
|
268
|
+
/** Unique identifier for the device */
|
|
269
|
+
id: string
|
|
270
|
+
/** Human-readable name of the device */
|
|
271
|
+
name: string
|
|
272
|
+
/** Device type (builtin_mic, bluetooth, etc.) */
|
|
273
|
+
type: string
|
|
274
|
+
/** Whether this is the system default device */
|
|
275
|
+
isDefault: boolean
|
|
276
|
+
/** Audio capabilities for the device */
|
|
277
|
+
capabilities: AudioDeviceCapabilities
|
|
278
|
+
/** Whether the device is currently available */
|
|
279
|
+
isAvailable: boolean
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Defines how recording should behave when a device becomes unavailable */
|
|
283
|
+
export const DeviceDisconnectionBehavior = {
|
|
284
|
+
/** Pause recording when device disconnects */
|
|
285
|
+
PAUSE: 'pause',
|
|
286
|
+
/** Switch to default device and continue recording */
|
|
287
|
+
FALLBACK: 'fallback',
|
|
288
|
+
} as const
|
|
289
|
+
|
|
290
|
+
/** Type for DeviceDisconnectionBehavior values */
|
|
291
|
+
export type DeviceDisconnectionBehaviorType =
|
|
292
|
+
(typeof DeviceDisconnectionBehavior)[keyof typeof DeviceDisconnectionBehavior]
|
|
293
|
+
|
|
231
294
|
export interface RecordingConfig {
|
|
232
295
|
/** Sample rate for recording in Hz (16000, 44100, or 48000) */
|
|
233
296
|
sampleRate?: SampleRate
|
|
@@ -262,6 +325,9 @@ export interface RecordingConfig {
|
|
|
262
325
|
/** iOS-specific configuration */
|
|
263
326
|
ios?: IOSConfig
|
|
264
327
|
|
|
328
|
+
/** Web-specific configuration options */
|
|
329
|
+
web?: WebConfig
|
|
330
|
+
|
|
265
331
|
/** Duration of each segment in milliseconds for analysis (default: 100) */
|
|
266
332
|
segmentDurationMs?: number
|
|
267
333
|
|
|
@@ -294,6 +360,12 @@ export interface RecordingConfig {
|
|
|
294
360
|
outputDirectory?: string // If not provided, uses default app directory
|
|
295
361
|
/** Optional filename for the recording (uses UUID if not provided) */
|
|
296
362
|
filename?: string // If not provided, uses UUID
|
|
363
|
+
|
|
364
|
+
/** ID of the device to use for recording (if not specified, uses default) */
|
|
365
|
+
deviceId?: string
|
|
366
|
+
|
|
367
|
+
/** How to handle device disconnection during recording */
|
|
368
|
+
deviceDisconnectionBehavior?: DeviceDisconnectionBehaviorType
|
|
297
369
|
}
|
|
298
370
|
|
|
299
371
|
export interface NotificationConfig {
|
|
@@ -420,6 +492,46 @@ export interface ExtractedAudioData {
|
|
|
420
492
|
}
|
|
421
493
|
|
|
422
494
|
export interface UseAudioRecorderState {
|
|
495
|
+
/**
|
|
496
|
+
* Prepares recording with the specified configuration without starting it.
|
|
497
|
+
*
|
|
498
|
+
* This method eliminates the latency between calling startRecording and the actual recording beginning.
|
|
499
|
+
* It pre-initializes all audio resources, requests permissions, and sets up audio sessions in advance,
|
|
500
|
+
* allowing for true zero-latency recording start when startRecording is called later.
|
|
501
|
+
*
|
|
502
|
+
* Technical benefits:
|
|
503
|
+
* - Eliminates audio pipeline initialization delay (50-300ms depending on platform)
|
|
504
|
+
* - Pre-allocates audio buffers to avoid memory allocation during recording start
|
|
505
|
+
* - Initializes audio hardware in advance (particularly important on iOS)
|
|
506
|
+
* - Requests and verifies permissions before the critical recording moment
|
|
507
|
+
*
|
|
508
|
+
* Use this method when:
|
|
509
|
+
* - You need zero-latency recording start (e.g., voice commands, musical applications)
|
|
510
|
+
* - You're building time-sensitive applications where missing initial audio would be problematic
|
|
511
|
+
* - You want to prepare resources during app initialization, screen loading, or preceding user interaction
|
|
512
|
+
* - You need to ensure recording starts reliably and instantly on all platforms
|
|
513
|
+
*
|
|
514
|
+
* @param config - The recording configuration, identical to what you would pass to startRecording
|
|
515
|
+
* @returns A promise that resolves when preparation is complete
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* // Prepare during component mounting
|
|
519
|
+
* useEffect(() => {
|
|
520
|
+
* prepareRecording({
|
|
521
|
+
* sampleRate: 44100,
|
|
522
|
+
* channels: 1,
|
|
523
|
+
* encoding: 'pcm_16bit',
|
|
524
|
+
* });
|
|
525
|
+
* }, []);
|
|
526
|
+
*
|
|
527
|
+
* // Later when user taps record button, it starts with zero latency
|
|
528
|
+
* const handleRecordPress = () => startRecording({
|
|
529
|
+
* sampleRate: 44100,
|
|
530
|
+
* channels: 1,
|
|
531
|
+
* encoding: 'pcm_16bit',
|
|
532
|
+
* });
|
|
533
|
+
*/
|
|
534
|
+
prepareRecording: (_: RecordingConfig) => Promise<void>
|
|
423
535
|
/** Starts recording with the specified configuration */
|
|
424
536
|
startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>
|
|
425
537
|
/** Stops the current recording and returns the recording data */
|