@siteed/expo-audio-stream 1.16.0 → 1.17.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 +8 -1
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +136 -23
- package/android/src/main/java/net/siteed/audiostream/Constants.kt +1 -0
- package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +2 -0
- package/build/ExpoAudioStream.types.d.ts +2 -0
- package/build/ExpoAudioStream.types.d.ts.map +1 -1
- package/build/ExpoAudioStream.types.js.map +1 -1
- package/build/ExpoAudioStream.web.d.ts +2 -0
- package/build/ExpoAudioStream.web.d.ts.map +1 -1
- package/build/ExpoAudioStream.web.js +8 -0
- package/build/ExpoAudioStream.web.js.map +1 -1
- package/build/WebRecorder.web.d.ts.map +1 -1
- package/build/WebRecorder.web.js +1 -0
- package/build/WebRecorder.web.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 +21 -4
- package/build/workers/InlineFeaturesExtractor.web.js.map +1 -1
- package/ios/AudioStreamManager.swift +64 -19
- package/ios/ExpoAudioStreamModule.swift +2 -1
- package/ios/RecordingSettings.swift +2 -0
- package/package.json +1 -1
- package/plugin/build/index.d.ts +2 -0
- package/plugin/build/index.js +10 -3
- package/plugin/src/index.ts +10 -1
- package/src/ExpoAudioStream.types.ts +6 -2
- package/src/ExpoAudioStream.web.ts +8 -0
- package/src/WebRecorder.web.ts +1 -0
- package/src/workers/InlineFeaturesExtractor.web.tsx +21 -4
package/plugin/build/index.js
CHANGED
|
@@ -21,19 +21,26 @@ const withRecordingPermission = (config, props) => {
|
|
|
21
21
|
useLocation: false,
|
|
22
22
|
useExternalAccessory: false,
|
|
23
23
|
},
|
|
24
|
+
iosConfig: {
|
|
25
|
+
microphoneUsageDescription: MICROPHONE_USAGE,
|
|
26
|
+
notificationUsageDescription: NOTIFICATION_USAGE,
|
|
27
|
+
},
|
|
24
28
|
...(props || {}),
|
|
25
29
|
};
|
|
26
30
|
const { enablePhoneStateHandling, enableNotifications, enableBackgroundAudio, } = options;
|
|
27
31
|
debugLog('📱 Configuring Recording Permissions Plugin...', options);
|
|
28
32
|
// iOS Configuration
|
|
29
33
|
config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
|
|
30
|
-
//
|
|
34
|
+
// Always set the microphone usage description from options first
|
|
31
35
|
config.modResults['NSMicrophoneUsageDescription'] =
|
|
32
|
-
|
|
36
|
+
options.iosConfig?.microphoneUsageDescription ||
|
|
37
|
+
config.modResults['NSMicrophoneUsageDescription'] ||
|
|
33
38
|
MICROPHONE_USAGE;
|
|
34
39
|
if (enableNotifications) {
|
|
35
40
|
config.modResults['NSUserNotificationsUsageDescription'] =
|
|
36
|
-
|
|
41
|
+
options.iosConfig?.notificationUsageDescription ||
|
|
42
|
+
config.modResults['NSUserNotificationsUsageDescription'] ||
|
|
43
|
+
NOTIFICATION_USAGE;
|
|
37
44
|
config.modResults['NSUserNotificationAlertStyle'] = 'alert';
|
|
38
45
|
}
|
|
39
46
|
const existingBackgroundModes = config.modResults.UIBackgroundModes || [];
|
package/plugin/src/index.ts
CHANGED
|
@@ -30,6 +30,8 @@ interface AudioStreamPluginOptions {
|
|
|
30
30
|
iosConfig?: {
|
|
31
31
|
allowBackgroundAudioControls?: boolean
|
|
32
32
|
backgroundProcessingTitle?: string
|
|
33
|
+
microphoneUsageDescription?: string
|
|
34
|
+
notificationUsageDescription?: string
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -48,6 +50,10 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
48
50
|
useLocation: false,
|
|
49
51
|
useExternalAccessory: false,
|
|
50
52
|
},
|
|
53
|
+
iosConfig: {
|
|
54
|
+
microphoneUsageDescription: MICROPHONE_USAGE,
|
|
55
|
+
notificationUsageDescription: NOTIFICATION_USAGE,
|
|
56
|
+
},
|
|
51
57
|
...(props || {}),
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -61,13 +67,16 @@ const withRecordingPermission: ConfigPlugin<AudioStreamPluginOptions> = (
|
|
|
61
67
|
|
|
62
68
|
// iOS Configuration
|
|
63
69
|
config = withInfoPlist(config as any, (config) => {
|
|
64
|
-
//
|
|
70
|
+
// Always set the microphone usage description from options first
|
|
65
71
|
config.modResults['NSMicrophoneUsageDescription'] =
|
|
72
|
+
options.iosConfig?.microphoneUsageDescription ||
|
|
66
73
|
config.modResults['NSMicrophoneUsageDescription'] ||
|
|
67
74
|
MICROPHONE_USAGE
|
|
68
75
|
|
|
69
76
|
if (enableNotifications) {
|
|
70
77
|
config.modResults['NSUserNotificationsUsageDescription'] =
|
|
78
|
+
options.iosConfig?.notificationUsageDescription ||
|
|
79
|
+
config.modResults['NSUserNotificationsUsageDescription'] ||
|
|
71
80
|
NOTIFICATION_USAGE
|
|
72
81
|
config.modResults['NSUserNotificationAlertStyle'] = 'alert'
|
|
73
82
|
}
|
|
@@ -20,6 +20,7 @@ export interface AudioStreamStatus {
|
|
|
20
20
|
durationMs: number
|
|
21
21
|
size: number
|
|
22
22
|
interval: number
|
|
23
|
+
intervalAnalysis: number
|
|
23
24
|
mimeType: string
|
|
24
25
|
compression?: CompressionInfo
|
|
25
26
|
}
|
|
@@ -36,7 +37,7 @@ export interface AudioDataEvent {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export type EncodingType = 'pcm_32bit' | 'pcm_16bit' | 'pcm_8bit'
|
|
39
|
-
export type SampleRate = 16000 | 44100 | 48000
|
|
40
|
+
export type SampleRate = 16000 | 44100 | 48000
|
|
40
41
|
export type BitDepth = 8 | 16 | 32
|
|
41
42
|
|
|
42
43
|
export type ConsoleLike = {
|
|
@@ -147,7 +148,10 @@ export interface RecordingConfig {
|
|
|
147
148
|
// Interval in milliseconds at which to emit recording data
|
|
148
149
|
interval?: number
|
|
149
150
|
|
|
150
|
-
//
|
|
151
|
+
// Interval in milliseconds at which to emit analysis data
|
|
152
|
+
intervalAnalysis?: number
|
|
153
|
+
|
|
154
|
+
// Keep the device awake while recording (default is false)
|
|
151
155
|
keepAwake?: boolean
|
|
152
156
|
|
|
153
157
|
// Show a notification during recording (default is false)
|
|
@@ -46,9 +46,11 @@ export class ExpoAudioStreamWeb extends LegacyEventEmitter {
|
|
|
46
46
|
currentDurationMs: number
|
|
47
47
|
currentSize: number
|
|
48
48
|
currentInterval: number
|
|
49
|
+
currentIntervalAnalysis: number
|
|
49
50
|
lastEmittedSize: number
|
|
50
51
|
lastEmittedTime: number
|
|
51
52
|
lastEmittedCompressionSize: number
|
|
53
|
+
lastEmittedAnalysisTime: number
|
|
52
54
|
streamUuid: string | null
|
|
53
55
|
extension: 'webm' | 'wav' = 'wav' // Default extension is 'wav'
|
|
54
56
|
recordingConfig?: RecordingConfig
|
|
@@ -87,10 +89,12 @@ export class ExpoAudioStreamWeb extends LegacyEventEmitter {
|
|
|
87
89
|
this.currentSize = 0
|
|
88
90
|
this.bitDepth = 32 // Default
|
|
89
91
|
this.currentInterval = 1000 // Default interval in ms
|
|
92
|
+
this.currentIntervalAnalysis = 500 // Default analysis interval in ms
|
|
90
93
|
this.lastEmittedSize = 0
|
|
91
94
|
this.lastEmittedTime = 0
|
|
92
95
|
this.latestPosition = 0
|
|
93
96
|
this.lastEmittedCompressionSize = 0
|
|
97
|
+
this.lastEmittedAnalysisTime = 0
|
|
94
98
|
this.streamUuid = null // Initialize UUID on first recording start
|
|
95
99
|
this.audioWorkletUrl = audioWorkletUrl
|
|
96
100
|
this.featuresExtratorUrl = featuresExtratorUrl
|
|
@@ -172,6 +176,9 @@ export class ExpoAudioStreamWeb extends LegacyEventEmitter {
|
|
|
172
176
|
this.lastEmittedSize = 0
|
|
173
177
|
this.lastEmittedTime = 0
|
|
174
178
|
this.lastEmittedCompressionSize = 0
|
|
179
|
+
this.currentInterval = recordingConfig.interval ?? 1000
|
|
180
|
+
this.currentIntervalAnalysis = recordingConfig.intervalAnalysis ?? 500
|
|
181
|
+
this.lastEmittedAnalysisTime = Date.now()
|
|
175
182
|
|
|
176
183
|
// Use custom filename if provided, otherwise fallback to timestamp
|
|
177
184
|
if (recordingConfig.filename) {
|
|
@@ -335,6 +342,7 @@ export class ExpoAudioStreamWeb extends LegacyEventEmitter {
|
|
|
335
342
|
durationMs: this.currentDurationMs,
|
|
336
343
|
size: this.currentSize,
|
|
337
344
|
interval: this.currentInterval,
|
|
345
|
+
intervalAnalysis: this.currentIntervalAnalysis,
|
|
338
346
|
mimeType: `audio/${this.extension}`,
|
|
339
347
|
compression: this.recordingConfig?.compression?.enabled
|
|
340
348
|
? {
|
package/src/WebRecorder.web.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const InlineFeaturesExtractor = `
|
|
2
2
|
// Unique ID counter
|
|
3
3
|
let uniqueIdCounter = 0
|
|
4
|
+
let accumulatedDataPoints = [] // Move outside message handler
|
|
5
|
+
let lastEmitTime = Date.now() // Move outside message handler
|
|
4
6
|
|
|
5
7
|
self.onmessage = function (event) {
|
|
6
8
|
const {
|
|
@@ -12,6 +14,7 @@ self.onmessage = function (event) {
|
|
|
12
14
|
fullAudioDurationMs,
|
|
13
15
|
numberOfChannels,
|
|
14
16
|
features: _features,
|
|
17
|
+
intervalAnalysis = 500, // Use intervalAnalysis instead of interval
|
|
15
18
|
} = event.data
|
|
16
19
|
const features = _features || {}
|
|
17
20
|
|
|
@@ -295,10 +298,24 @@ self.onmessage = function (event) {
|
|
|
295
298
|
pointsPerSecond,
|
|
296
299
|
algorithm
|
|
297
300
|
)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
301
|
+
|
|
302
|
+
// Accumulate data points
|
|
303
|
+
accumulatedDataPoints = accumulatedDataPoints.concat(result.dataPoints)
|
|
304
|
+
|
|
305
|
+
const currentTime = Date.now()
|
|
306
|
+
const shouldEmitAccumulated = currentTime - lastEmitTime >= intervalAnalysis
|
|
307
|
+
|
|
308
|
+
if (shouldEmitAccumulated) {
|
|
309
|
+
self.postMessage({
|
|
310
|
+
command: 'features',
|
|
311
|
+
result: {
|
|
312
|
+
...result,
|
|
313
|
+
dataPoints: accumulatedDataPoints
|
|
314
|
+
}
|
|
315
|
+
})
|
|
316
|
+
accumulatedDataPoints = [] // Reset accumulator
|
|
317
|
+
lastEmitTime = currentTime
|
|
318
|
+
}
|
|
302
319
|
} catch (error) {
|
|
303
320
|
console.error('[AudioFeaturesExtractor] Error in processing', error)
|
|
304
321
|
self.postMessage({ error: error.message })
|