@siteed/expo-audio-studio 2.1.1
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 +210 -0
- package/LICENSE +21 -0
- package/README.md +269 -0
- package/android/build.gradle +105 -0
- package/android/src/main/AndroidManifest.xml +27 -0
- package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +166 -0
- package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +9 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +131 -0
- package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +103 -0
- package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +435 -0
- package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +2235 -0
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +1437 -0
- package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +166 -0
- package/android/src/main/java/net/siteed/audiostream/AudioTrimmer.kt +1099 -0
- package/android/src/main/java/net/siteed/audiostream/Constants.kt +21 -0
- package/android/src/main/java/net/siteed/audiostream/EventSender.kt +7 -0
- package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +739 -0
- package/android/src/main/java/net/siteed/audiostream/FFT.kt +99 -0
- package/android/src/main/java/net/siteed/audiostream/Features.kt +98 -0
- package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +70 -0
- package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +59 -0
- package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +59 -0
- package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +205 -0
- package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +19 -0
- package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +159 -0
- package/android/src/main/res/drawable/ic_default_action_icon.xml +16 -0
- package/android/src/main/res/drawable/ic_microphone.xml +13 -0
- package/android/src/main/res/drawable/ic_pause.xml +10 -0
- package/android/src/main/res/drawable/ic_play.xml +10 -0
- package/android/src/main/res/drawable/ic_stop.xml +10 -0
- package/android/src/main/res/layout/notification_recording.xml +37 -0
- package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +56 -0
- package/app.plugin.js +1 -0
- package/build/AudioAnalysis/AudioAnalysis.types.d.ts +179 -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 +68 -0
- package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js +203 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
- package/build/AudioAnalysis/extractAudioData.d.ts +3 -0
- package/build/AudioAnalysis/extractAudioData.d.ts.map +1 -0
- package/build/AudioAnalysis/extractAudioData.js +5 -0
- package/build/AudioAnalysis/extractAudioData.js.map +1 -0
- package/build/AudioAnalysis/extractMelSpectrogram.d.ts +14 -0
- package/build/AudioAnalysis/extractMelSpectrogram.d.ts.map +1 -0
- package/build/AudioAnalysis/extractMelSpectrogram.js +85 -0
- package/build/AudioAnalysis/extractMelSpectrogram.js.map +1 -0
- package/build/AudioAnalysis/extractPreview.d.ts +11 -0
- package/build/AudioAnalysis/extractPreview.d.ts.map +1 -0
- package/build/AudioAnalysis/extractPreview.js +25 -0
- package/build/AudioAnalysis/extractPreview.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 +11 -0
- package/build/AudioAnalysis/extractWaveform.js.map +1 -0
- package/build/AudioRecorder.provider.d.ts +11 -0
- package/build/AudioRecorder.provider.d.ts.map +1 -0
- package/build/AudioRecorder.provider.js +37 -0
- package/build/AudioRecorder.provider.js.map +1 -0
- 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 +532 -0
- package/build/ExpoAudioStream.types.d.ts.map +1 -0
- package/build/ExpoAudioStream.types.js +2 -0
- package/build/ExpoAudioStream.types.js.map +1 -0
- package/build/ExpoAudioStream.web.d.ts +59 -0
- package/build/ExpoAudioStream.web.d.ts.map +1 -0
- package/build/ExpoAudioStream.web.js +285 -0
- package/build/ExpoAudioStream.web.js.map +1 -0
- package/build/ExpoAudioStreamModule.d.ts +3 -0
- package/build/ExpoAudioStreamModule.d.ts.map +1 -0
- package/build/ExpoAudioStreamModule.js +693 -0
- package/build/ExpoAudioStreamModule.js.map +1 -0
- package/build/WebRecorder.web.d.ts +119 -0
- package/build/WebRecorder.web.d.ts.map +1 -0
- package/build/WebRecorder.web.js +436 -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 +26 -0
- package/build/events.d.ts.map +1 -0
- package/build/events.js +21 -0
- package/build/events.js.map +1 -0
- package/build/index.d.ts +15 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +14 -0
- package/build/index.js.map +1 -0
- package/build/trimAudio.d.ts +25 -0
- package/build/trimAudio.d.ts.map +1 -0
- package/build/trimAudio.js +67 -0
- package/build/trimAudio.js.map +1 -0
- package/build/useAudioRecorder.d.ts +21 -0
- package/build/useAudioRecorder.d.ts.map +1 -0
- package/build/useAudioRecorder.js +427 -0
- package/build/useAudioRecorder.js.map +1 -0
- package/build/utils/BlobFix.d.ts +9 -0
- package/build/utils/BlobFix.d.ts.map +1 -0
- package/build/utils/BlobFix.js +498 -0
- package/build/utils/BlobFix.js.map +1 -0
- package/build/utils/audioProcessing.d.ts +24 -0
- package/build/utils/audioProcessing.d.ts.map +1 -0
- package/build/utils/audioProcessing.js +133 -0
- package/build/utils/audioProcessing.js.map +1 -0
- package/build/utils/concatenateBuffers.d.ts +8 -0
- package/build/utils/concatenateBuffers.d.ts.map +1 -0
- package/build/utils/concatenateBuffers.js +21 -0
- package/build/utils/concatenateBuffers.js.map +1 -0
- package/build/utils/convertPCMToFloat32.d.ts +13 -0
- package/build/utils/convertPCMToFloat32.d.ts.map +1 -0
- package/build/utils/convertPCMToFloat32.js +120 -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 +26 -0
- package/build/utils/getWavFileInfo.d.ts.map +1 -0
- package/build/utils/getWavFileInfo.js +92 -0
- package/build/utils/getWavFileInfo.js.map +1 -0
- package/build/utils/writeWavHeader.d.ts +49 -0
- package/build/utils/writeWavHeader.d.ts.map +1 -0
- package/build/utils/writeWavHeader.js +91 -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 +828 -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 +157 -0
- package/build/workers/inlineAudioWebWorker.web.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/AudioAnalysisData.swift +74 -0
- package/ios/AudioNotificationManager.swift +135 -0
- package/ios/AudioProcessingHelpers.swift +743 -0
- package/ios/AudioProcessor.swift +1313 -0
- package/ios/AudioStreamError.swift +7 -0
- package/ios/AudioStreamManager.swift +1708 -0
- package/ios/AudioStreamManagerDelegate.swift +16 -0
- package/ios/DataPoint.swift +54 -0
- package/ios/DecodingConfig.swift +47 -0
- package/ios/ExpoAudioStream.podspec +27 -0
- package/ios/ExpoAudioStreamModule.swift +805 -0
- package/ios/FFT.swift +62 -0
- package/ios/Features.swift +95 -0
- package/ios/Logger.swift +7 -0
- package/ios/NotificationExtension.swift +15 -0
- package/ios/RecordingResult.swift +22 -0
- package/ios/RecordingSettings.swift +265 -0
- package/ios/WaveformExtractor.swift +105 -0
- package/package.json +128 -0
- package/plugin/build/index.d.ts +21 -0
- package/plugin/build/index.js +192 -0
- package/plugin/src/index.ts +279 -0
- package/plugin/tsconfig.json +10 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/src/AudioAnalysis/AudioAnalysis.types.ts +202 -0
- package/src/AudioAnalysis/extractAudioAnalysis.ts +333 -0
- package/src/AudioAnalysis/extractAudioData.ts +6 -0
- package/src/AudioAnalysis/extractMelSpectrogram.ts +144 -0
- package/src/AudioAnalysis/extractPreview.ts +34 -0
- package/src/AudioAnalysis/extractWaveform.ts +22 -0
- package/src/AudioRecorder.provider.tsx +54 -0
- package/src/ExpoAudioStream.native.ts +6 -0
- package/src/ExpoAudioStream.types.ts +641 -0
- package/src/ExpoAudioStream.web.ts +359 -0
- package/src/ExpoAudioStreamModule.ts +967 -0
- package/src/WebRecorder.web.ts +580 -0
- package/src/constants.ts +18 -0
- package/src/events.ts +60 -0
- package/src/index.ts +36 -0
- package/src/trimAudio.ts +90 -0
- package/src/useAudioRecorder.tsx +620 -0
- package/src/utils/BlobFix.ts +559 -0
- package/src/utils/audioProcessing.ts +205 -0
- package/src/utils/concatenateBuffers.ts +24 -0
- package/src/utils/convertPCMToFloat32.ts +170 -0
- package/src/utils/encodingToBitDepth.ts +18 -0
- package/src/utils/getWavFileInfo.ts +132 -0
- package/src/utils/writeWavHeader.ts +114 -0
- package/src/workers/InlineFeaturesExtractor.web.tsx +827 -0
- package/src/workers/inlineAudioWebWorker.web.tsx +156 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
package net.siteed.audiostream
|
|
2
|
+
|
|
3
|
+
import android.app.Service
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.os.Build
|
|
7
|
+
import android.os.IBinder
|
|
8
|
+
import android.util.Log
|
|
9
|
+
import android.os.Handler
|
|
10
|
+
import android.os.Looper
|
|
11
|
+
import expo.modules.kotlin.Promise
|
|
12
|
+
import android.app.NotificationChannel
|
|
13
|
+
import android.app.NotificationManager
|
|
14
|
+
import androidx.core.app.NotificationCompat
|
|
15
|
+
|
|
16
|
+
class AudioRecordingService : Service() {
|
|
17
|
+
private val notificationManager by lazy {
|
|
18
|
+
AudioNotificationManager.getInstance(applicationContext)
|
|
19
|
+
}
|
|
20
|
+
private val mainHandler = Handler(Looper.getMainLooper())
|
|
21
|
+
private var isRunning = false
|
|
22
|
+
|
|
23
|
+
override fun onBind(intent: Intent?): IBinder? = null
|
|
24
|
+
|
|
25
|
+
override fun onCreate() {
|
|
26
|
+
super.onCreate()
|
|
27
|
+
Log.d(Constants.TAG, "AudioRecordingService onCreate")
|
|
28
|
+
isRunning = true
|
|
29
|
+
setServiceRunning(true)
|
|
30
|
+
|
|
31
|
+
// Start foreground immediately in onCreate to prevent timing issues
|
|
32
|
+
startForegroundWithNotification()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
36
|
+
Log.d(Constants.TAG, "AudioRecordingService onStartCommand")
|
|
37
|
+
return START_STICKY
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun startForegroundWithNotification() {
|
|
41
|
+
try {
|
|
42
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
43
|
+
// Create a minimal notification channel if needed
|
|
44
|
+
val channel = NotificationChannel(
|
|
45
|
+
"recording_service",
|
|
46
|
+
"Recording Service",
|
|
47
|
+
NotificationManager.IMPORTANCE_LOW
|
|
48
|
+
).apply {
|
|
49
|
+
setSound(null, null)
|
|
50
|
+
enableLights(false)
|
|
51
|
+
enableVibration(false)
|
|
52
|
+
}
|
|
53
|
+
val notificationManager = getSystemService(NotificationManager::class.java)
|
|
54
|
+
notificationManager.createNotificationChannel(channel)
|
|
55
|
+
|
|
56
|
+
// Create minimal silent notification with minimal text
|
|
57
|
+
val notification = NotificationCompat.Builder(this, "recording_service")
|
|
58
|
+
.setContentTitle(" ") // Space character instead of empty string
|
|
59
|
+
.setContentText(" ") // Space character instead of empty string
|
|
60
|
+
.setSmallIcon(R.drawable.ic_microphone)
|
|
61
|
+
.setOngoing(true)
|
|
62
|
+
.setSound(null)
|
|
63
|
+
.setVibrate(null)
|
|
64
|
+
.setDefaults(0)
|
|
65
|
+
.setPriority(NotificationCompat.PRIORITY_LOW)
|
|
66
|
+
.build()
|
|
67
|
+
|
|
68
|
+
startForeground(1, notification)
|
|
69
|
+
Log.d(Constants.TAG, "Started foreground service with minimal notification")
|
|
70
|
+
}
|
|
71
|
+
} catch (e: Exception) {
|
|
72
|
+
Log.e(Constants.TAG, "Failed to start foreground service: ${e.message}", e)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun onDestroy() {
|
|
77
|
+
Log.d(Constants.TAG, "AudioRecordingService onDestroy")
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
stopForeground(STOP_FOREGROUND_REMOVE)
|
|
81
|
+
} catch (e: Exception) {
|
|
82
|
+
Log.e(Constants.TAG, "Error stopping foreground service: ${e.message}", e)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
isRunning = false
|
|
86
|
+
setServiceRunning(false)
|
|
87
|
+
super.onDestroy()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override fun onTaskRemoved(rootIntent: Intent?) {
|
|
91
|
+
super.onTaskRemoved(rootIntent)
|
|
92
|
+
Log.d(Constants.TAG, "AudioRecordingService onTaskRemoved")
|
|
93
|
+
|
|
94
|
+
// Stop recording when app is killed
|
|
95
|
+
AudioRecorderManager.getInstance()?.let { manager ->
|
|
96
|
+
mainHandler.post {
|
|
97
|
+
// Create a simple promise object for internal use
|
|
98
|
+
val promise = object : Promise {
|
|
99
|
+
override fun resolve(value: Any?) {
|
|
100
|
+
Log.d(Constants.TAG, "Successfully stopped recording on task removed")
|
|
101
|
+
cleanup()
|
|
102
|
+
}
|
|
103
|
+
override fun reject(code: String, message: String?, cause: Throwable?) {
|
|
104
|
+
Log.e(Constants.TAG, "Failed to stop recording on task removed: $message")
|
|
105
|
+
cleanup()
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
manager.stopRecording(promise)
|
|
111
|
+
} catch (e: Exception) {
|
|
112
|
+
promise.reject("ERROR", e.message, e)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
private fun cleanup() {
|
|
120
|
+
try {
|
|
121
|
+
stopForeground(STOP_FOREGROUND_REMOVE)
|
|
122
|
+
} catch (e: Exception) {
|
|
123
|
+
Log.e(Constants.TAG, "Error stopping foreground in cleanup: ${e.message}", e)
|
|
124
|
+
}
|
|
125
|
+
stopSelf()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
companion object {
|
|
129
|
+
// Static flag to track if service is running
|
|
130
|
+
private var isServiceRunningStatic = false
|
|
131
|
+
|
|
132
|
+
fun isServiceRunning(): Boolean {
|
|
133
|
+
return isServiceRunningStatic
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fun setServiceRunning(running: Boolean) {
|
|
137
|
+
isServiceRunningStatic = running
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fun startService(context: Context) {
|
|
141
|
+
try {
|
|
142
|
+
val serviceIntent = Intent(context, AudioRecordingService::class.java)
|
|
143
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
144
|
+
context.startForegroundService(serviceIntent)
|
|
145
|
+
Log.d(Constants.TAG, "Started foreground service")
|
|
146
|
+
} else {
|
|
147
|
+
context.startService(serviceIntent)
|
|
148
|
+
Log.d(Constants.TAG, "Started regular service")
|
|
149
|
+
}
|
|
150
|
+
setServiceRunning(true)
|
|
151
|
+
} catch (e: Exception) {
|
|
152
|
+
Log.e(Constants.TAG, "Failed to start service: ${e.message}", e)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
fun stopService(context: Context) {
|
|
157
|
+
try {
|
|
158
|
+
context.stopService(Intent(context, AudioRecordingService::class.java))
|
|
159
|
+
setServiceRunning(false)
|
|
160
|
+
Log.d(Constants.TAG, "Stopped service")
|
|
161
|
+
} catch (e: Exception) {
|
|
162
|
+
Log.e(Constants.TAG, "Failed to stop service: ${e.message}", e)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|