@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/.size-limit.json
ADDED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @siteed/expo-audio-stream
|
|
2
2
|
|
|
3
|
-
`@siteed/expo-audio-stream` is a comprehensive library designed to facilitate real-time audio processing and streaming across iOS, Android, and web platforms.
|
|
3
|
+
`@siteed/expo-audio-stream` is a comprehensive library designed to facilitate real-time audio processing and streaming across iOS, Android, and web platforms.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- Listeners for audio data events with detailed event payloads.
|
|
12
12
|
- Utility functions for recording control and file management.
|
|
13
13
|
|
|
14
|
-
## Example Application
|
|
14
|
+
## Playground Example Application
|
|
15
15
|
|
|
16
16
|
The project comes with a fully functional example application that demonstrates how to use the library in a real-world scenario.
|
|
17
17
|
|
|
@@ -23,9 +23,9 @@ To try it:
|
|
|
23
23
|
git clone https://github.com/deeeed/expo-audio-stream.git
|
|
24
24
|
cd expo-audio-stream
|
|
25
25
|
yarn
|
|
26
|
-
yarn
|
|
27
|
-
yarn
|
|
28
|
-
yarn
|
|
26
|
+
yarn playground ios
|
|
27
|
+
yarn playground android
|
|
28
|
+
yarn playground web
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## Installation
|
|
@@ -60,7 +60,7 @@ This library provides two hooks: `useAudioRecorder` for standalone use and `useS
|
|
|
60
60
|
|
|
61
61
|
### Standalone Recording
|
|
62
62
|
|
|
63
|
-
The `
|
|
63
|
+
The `playground/` folder contains a fully functional React Native application demonstrating how to integrate and use `useAudioRecorder` from `@siteed/expo-audio-stream`. This includes starting and stopping recordings, handling permissions, and processing live audio data.
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
#### Standalone Usage
|
package/android/build.gradle
CHANGED
|
@@ -89,4 +89,9 @@ repositories {
|
|
|
89
89
|
dependencies {
|
|
90
90
|
implementation project(':expo-modules-core')
|
|
91
91
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
92
|
+
|
|
93
|
+
// Add testing dependencies
|
|
94
|
+
testImplementation 'junit:junit:4.13.2'
|
|
95
|
+
testImplementation 'org.jetbrains.kotlin:kotlin-test:1.8.10'
|
|
96
|
+
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit:1.8.10'
|
|
92
97
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// net/siteed/audiostream/AudioAnalysisData.kt
|
|
2
|
+
package net.siteed.audiostream
|
|
3
|
+
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import androidx.core.os.bundleOf
|
|
6
|
+
|
|
7
|
+
data class DataPoint(
|
|
8
|
+
val id: Long,
|
|
9
|
+
val amplitude: Float,
|
|
10
|
+
val activeSpeech: Boolean? = null,
|
|
11
|
+
val dB: Float? = null,
|
|
12
|
+
val silent: Boolean? = null,
|
|
13
|
+
val features: Features? = null,
|
|
14
|
+
val startTime: Float? = null,
|
|
15
|
+
val endTime: Float? = null,
|
|
16
|
+
val startPosition: Int? = null,
|
|
17
|
+
val endPosition: Int? = null,
|
|
18
|
+
val samples: Int = 0,
|
|
19
|
+
val speaker: Int? = null
|
|
20
|
+
) {
|
|
21
|
+
fun toDictionary(): Map<String, Any?> {
|
|
22
|
+
return mapOf(
|
|
23
|
+
"id" to id,
|
|
24
|
+
"amplitude" to amplitude,
|
|
25
|
+
"activeSpeech" to activeSpeech,
|
|
26
|
+
"dB" to dB,
|
|
27
|
+
"silent" to silent,
|
|
28
|
+
"features" to features?.toDictionary(),
|
|
29
|
+
"startTime" to startTime,
|
|
30
|
+
"endTime" to endTime,
|
|
31
|
+
"startPosition" to startPosition,
|
|
32
|
+
"endPosition" to endPosition,
|
|
33
|
+
"samples" to samples,
|
|
34
|
+
"speaker" to speaker
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun toBundle(): Bundle {
|
|
39
|
+
return bundleOf(
|
|
40
|
+
"id" to id,
|
|
41
|
+
"amplitude" to amplitude,
|
|
42
|
+
"activeSpeech" to activeSpeech,
|
|
43
|
+
"dB" to dB,
|
|
44
|
+
"silent" to silent,
|
|
45
|
+
"features" to features?.toBundle(),
|
|
46
|
+
"startTime" to startTime,
|
|
47
|
+
"endTime" to endTime,
|
|
48
|
+
"startPosition" to startPosition,
|
|
49
|
+
"endPosition" to endPosition,
|
|
50
|
+
"samples" to samples,
|
|
51
|
+
"speaker" to speaker
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
data class AudioAnalysisData(
|
|
57
|
+
val pointsPerSecond: Double,
|
|
58
|
+
val durationMs: Int,
|
|
59
|
+
val bitDepth: Int,
|
|
60
|
+
val numberOfChannels: Int,
|
|
61
|
+
val sampleRate: Int,
|
|
62
|
+
val samples: Int,
|
|
63
|
+
val dataPoints: List<DataPoint>,
|
|
64
|
+
val amplitudeRange: AmplitudeRange,
|
|
65
|
+
val speakerChanges: List<SpeakerChange>,
|
|
66
|
+
val extractionTimeMs: Float
|
|
67
|
+
) {
|
|
68
|
+
data class AmplitudeRange(val min: Float, val max: Float) {
|
|
69
|
+
fun toDictionary(): Map<String, Float> {
|
|
70
|
+
return mapOf("min" to min, "max" to max)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fun toBundle(): Bundle {
|
|
74
|
+
return bundleOf("min" to min, "max" to max)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
data class SpeakerChange(val timestamp: Float, val speaker: Int) {
|
|
79
|
+
fun toDictionary(): Map<String, Any> {
|
|
80
|
+
return mapOf("timestamp" to timestamp, "speaker" to speaker)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fun toBundle(): Bundle {
|
|
84
|
+
return bundleOf("timestamp" to timestamp, "speaker" to speaker)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
fun toDictionary(): Map<String, Any> {
|
|
89
|
+
return mapOf(
|
|
90
|
+
"pointsPerSecond" to pointsPerSecond,
|
|
91
|
+
"durationMs" to durationMs,
|
|
92
|
+
"bitDepth" to bitDepth,
|
|
93
|
+
"numberOfChannels" to numberOfChannels,
|
|
94
|
+
"sampleRate" to sampleRate,
|
|
95
|
+
"samples" to samples,
|
|
96
|
+
"dataPoints" to dataPoints.map { it.toDictionary() },
|
|
97
|
+
"amplitudeRange" to amplitudeRange.toDictionary(),
|
|
98
|
+
"speakerChanges" to speakerChanges.map { it.toDictionary() },
|
|
99
|
+
"extractionTimeMs" to extractionTimeMs
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fun toBundle(): Bundle {
|
|
104
|
+
val dataPointsBundleArray = dataPoints.map { it.toBundle() }.toTypedArray()
|
|
105
|
+
val speakerChangesBundleArray = speakerChanges.map { it.toBundle() }.toTypedArray()
|
|
106
|
+
|
|
107
|
+
return bundleOf(
|
|
108
|
+
"pointsPerSecond" to pointsPerSecond,
|
|
109
|
+
"durationMs" to durationMs,
|
|
110
|
+
"bitDepth" to bitDepth,
|
|
111
|
+
"numberOfChannels" to numberOfChannels,
|
|
112
|
+
"sampleRate" to sampleRate,
|
|
113
|
+
"samples" to samples,
|
|
114
|
+
"dataPoints" to dataPointsBundleArray,
|
|
115
|
+
"amplitudeRange" to amplitudeRange.toBundle(),
|
|
116
|
+
"speakerChanges" to speakerChangesBundleArray,
|
|
117
|
+
"extractionTimeMs" to extractionTimeMs
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -14,25 +14,55 @@ class AudioFileHandler(private val filesDir: File) {
|
|
|
14
14
|
|
|
15
15
|
// RIFF/WAVE header
|
|
16
16
|
"RIFF".toByteArray().copyInto(header, 0)
|
|
17
|
-
|
|
17
|
+
// (file size - 8) to be updated later
|
|
18
|
+
header[4] = 0 // Placeholder
|
|
19
|
+
header[5] = 0 // Placeholder
|
|
20
|
+
header[6] = 0 // Placeholder
|
|
21
|
+
header[7] = 0 // Placeholder
|
|
18
22
|
"WAVE".toByteArray().copyInto(header, 8)
|
|
19
23
|
"fmt ".toByteArray().copyInto(header, 12)
|
|
20
24
|
|
|
21
25
|
// 16 for PCM
|
|
22
26
|
header[16] = 16
|
|
27
|
+
header[17] = 0
|
|
28
|
+
header[18] = 0
|
|
29
|
+
header[19] = 0
|
|
30
|
+
|
|
31
|
+
// PCM format ID
|
|
23
32
|
header[20] = 1 // Audio format 1 for PCM (not compressed)
|
|
24
|
-
header[
|
|
33
|
+
header[21] = 0
|
|
34
|
+
|
|
35
|
+
// Number of channels
|
|
36
|
+
header[22] = (channels and 0xff).toByte()
|
|
37
|
+
header[23] = (channels shr 8 and 0xff).toByte()
|
|
38
|
+
|
|
39
|
+
// Sample rate
|
|
25
40
|
header[24] = (sampleRateInHz and 0xff).toByte()
|
|
26
41
|
header[25] = (sampleRateInHz shr 8 and 0xff).toByte()
|
|
27
42
|
header[26] = (sampleRateInHz shr 16 and 0xff).toByte()
|
|
28
43
|
header[27] = (sampleRateInHz shr 24 and 0xff).toByte()
|
|
44
|
+
|
|
45
|
+
// Byte rate
|
|
29
46
|
header[28] = (byteRate and 0xff).toByte()
|
|
30
47
|
header[29] = (byteRate shr 8 and 0xff).toByte()
|
|
31
48
|
header[30] = (byteRate shr 16 and 0xff).toByte()
|
|
32
49
|
header[31] = (byteRate shr 24 and 0xff).toByte()
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
|
|
51
|
+
// Block align
|
|
52
|
+
header[32] = (blockAlign and 0xff).toByte()
|
|
53
|
+
header[33] = (blockAlign shr 8 and 0xff).toByte()
|
|
54
|
+
|
|
55
|
+
// Bits per sample
|
|
56
|
+
header[34] = (bitDepth and 0xff).toByte()
|
|
57
|
+
header[35] = (bitDepth shr 8 and 0xff).toByte()
|
|
58
|
+
|
|
59
|
+
// Data chunk
|
|
35
60
|
"data".toByteArray().copyInto(header, 36)
|
|
61
|
+
// Data size to be updated later
|
|
62
|
+
header[40] = 0 // Placeholder
|
|
63
|
+
header[41] = 0 // Placeholder
|
|
64
|
+
header[42] = 0 // Placeholder
|
|
65
|
+
header[43] = 0 // Placeholder
|
|
36
66
|
|
|
37
67
|
out.write(header, 0, 44)
|
|
38
68
|
}
|