@siteed/expo-audio-stream 2.1.0 → 2.2.1-beta.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.
Files changed (189) hide show
  1. package/README.md +23 -260
  2. package/build/index.d.ts +11 -15
  3. package/build/index.js +54 -14
  4. package/build/src/index.d.ts +11 -0
  5. package/build/src/index.js +54 -0
  6. package/package.json +49 -110
  7. package/src/index.ts +18 -32
  8. package/CHANGELOG.md +0 -206
  9. package/android/build.gradle +0 -105
  10. package/android/src/main/AndroidManifest.xml +0 -27
  11. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +0 -166
  12. package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +0 -9
  13. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +0 -131
  14. package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +0 -103
  15. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +0 -435
  16. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +0 -2235
  17. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +0 -1437
  18. package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +0 -152
  19. package/android/src/main/java/net/siteed/audiostream/AudioTrimmer.kt +0 -1099
  20. package/android/src/main/java/net/siteed/audiostream/Constants.kt +0 -21
  21. package/android/src/main/java/net/siteed/audiostream/EventSender.kt +0 -7
  22. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +0 -739
  23. package/android/src/main/java/net/siteed/audiostream/FFT.kt +0 -99
  24. package/android/src/main/java/net/siteed/audiostream/Features.kt +0 -98
  25. package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +0 -70
  26. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +0 -59
  27. package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +0 -59
  28. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +0 -205
  29. package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +0 -19
  30. package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +0 -159
  31. package/android/src/main/res/drawable/ic_default_action_icon.xml +0 -16
  32. package/android/src/main/res/drawable/ic_microphone.xml +0 -13
  33. package/android/src/main/res/drawable/ic_pause.xml +0 -10
  34. package/android/src/main/res/drawable/ic_play.xml +0 -10
  35. package/android/src/main/res/drawable/ic_stop.xml +0 -10
  36. package/android/src/main/res/layout/notification_recording.xml +0 -37
  37. package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +0 -56
  38. package/app.plugin.js +0 -1
  39. package/build/AudioAnalysis/AudioAnalysis.types.d.ts +0 -179
  40. package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +0 -1
  41. package/build/AudioAnalysis/AudioAnalysis.types.js +0 -3
  42. package/build/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  43. package/build/AudioAnalysis/extractAudioAnalysis.d.ts +0 -68
  44. package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +0 -1
  45. package/build/AudioAnalysis/extractAudioAnalysis.js +0 -203
  46. package/build/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  47. package/build/AudioAnalysis/extractAudioData.d.ts +0 -3
  48. package/build/AudioAnalysis/extractAudioData.d.ts.map +0 -1
  49. package/build/AudioAnalysis/extractAudioData.js +0 -5
  50. package/build/AudioAnalysis/extractAudioData.js.map +0 -1
  51. package/build/AudioAnalysis/extractMelSpectrogram.d.ts +0 -14
  52. package/build/AudioAnalysis/extractMelSpectrogram.d.ts.map +0 -1
  53. package/build/AudioAnalysis/extractMelSpectrogram.js +0 -85
  54. package/build/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  55. package/build/AudioAnalysis/extractPreview.d.ts +0 -11
  56. package/build/AudioAnalysis/extractPreview.d.ts.map +0 -1
  57. package/build/AudioAnalysis/extractPreview.js +0 -25
  58. package/build/AudioAnalysis/extractPreview.js.map +0 -1
  59. package/build/AudioAnalysis/extractWaveform.d.ts +0 -8
  60. package/build/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  61. package/build/AudioAnalysis/extractWaveform.js +0 -11
  62. package/build/AudioAnalysis/extractWaveform.js.map +0 -1
  63. package/build/AudioRecorder.provider.d.ts +0 -11
  64. package/build/AudioRecorder.provider.d.ts.map +0 -1
  65. package/build/AudioRecorder.provider.js +0 -37
  66. package/build/AudioRecorder.provider.js.map +0 -1
  67. package/build/ExpoAudioStream.native.d.ts +0 -3
  68. package/build/ExpoAudioStream.native.d.ts.map +0 -1
  69. package/build/ExpoAudioStream.native.js +0 -6
  70. package/build/ExpoAudioStream.native.js.map +0 -1
  71. package/build/ExpoAudioStream.types.d.ts +0 -532
  72. package/build/ExpoAudioStream.types.d.ts.map +0 -1
  73. package/build/ExpoAudioStream.types.js +0 -2
  74. package/build/ExpoAudioStream.types.js.map +0 -1
  75. package/build/ExpoAudioStream.web.d.ts +0 -59
  76. package/build/ExpoAudioStream.web.d.ts.map +0 -1
  77. package/build/ExpoAudioStream.web.js +0 -285
  78. package/build/ExpoAudioStream.web.js.map +0 -1
  79. package/build/ExpoAudioStreamModule.d.ts +0 -3
  80. package/build/ExpoAudioStreamModule.d.ts.map +0 -1
  81. package/build/ExpoAudioStreamModule.js +0 -693
  82. package/build/ExpoAudioStreamModule.js.map +0 -1
  83. package/build/WebRecorder.web.d.ts +0 -119
  84. package/build/WebRecorder.web.d.ts.map +0 -1
  85. package/build/WebRecorder.web.js +0 -436
  86. package/build/WebRecorder.web.js.map +0 -1
  87. package/build/constants.d.ts +0 -11
  88. package/build/constants.d.ts.map +0 -1
  89. package/build/constants.js +0 -14
  90. package/build/constants.js.map +0 -1
  91. package/build/events.d.ts +0 -26
  92. package/build/events.d.ts.map +0 -1
  93. package/build/events.js +0 -21
  94. package/build/events.js.map +0 -1
  95. package/build/index.d.ts.map +0 -1
  96. package/build/index.js.map +0 -1
  97. package/build/trimAudio.d.ts +0 -25
  98. package/build/trimAudio.d.ts.map +0 -1
  99. package/build/trimAudio.js +0 -67
  100. package/build/trimAudio.js.map +0 -1
  101. package/build/useAudioRecorder.d.ts +0 -21
  102. package/build/useAudioRecorder.d.ts.map +0 -1
  103. package/build/useAudioRecorder.js +0 -427
  104. package/build/useAudioRecorder.js.map +0 -1
  105. package/build/utils/BlobFix.d.ts +0 -9
  106. package/build/utils/BlobFix.d.ts.map +0 -1
  107. package/build/utils/BlobFix.js +0 -498
  108. package/build/utils/BlobFix.js.map +0 -1
  109. package/build/utils/audioProcessing.d.ts +0 -24
  110. package/build/utils/audioProcessing.d.ts.map +0 -1
  111. package/build/utils/audioProcessing.js +0 -133
  112. package/build/utils/audioProcessing.js.map +0 -1
  113. package/build/utils/concatenateBuffers.d.ts +0 -8
  114. package/build/utils/concatenateBuffers.d.ts.map +0 -1
  115. package/build/utils/concatenateBuffers.js +0 -21
  116. package/build/utils/concatenateBuffers.js.map +0 -1
  117. package/build/utils/convertPCMToFloat32.d.ts +0 -13
  118. package/build/utils/convertPCMToFloat32.d.ts.map +0 -1
  119. package/build/utils/convertPCMToFloat32.js +0 -120
  120. package/build/utils/convertPCMToFloat32.js.map +0 -1
  121. package/build/utils/encodingToBitDepth.d.ts +0 -5
  122. package/build/utils/encodingToBitDepth.d.ts.map +0 -1
  123. package/build/utils/encodingToBitDepth.js +0 -13
  124. package/build/utils/encodingToBitDepth.js.map +0 -1
  125. package/build/utils/getWavFileInfo.d.ts +0 -26
  126. package/build/utils/getWavFileInfo.d.ts.map +0 -1
  127. package/build/utils/getWavFileInfo.js +0 -92
  128. package/build/utils/getWavFileInfo.js.map +0 -1
  129. package/build/utils/writeWavHeader.d.ts +0 -49
  130. package/build/utils/writeWavHeader.d.ts.map +0 -1
  131. package/build/utils/writeWavHeader.js +0 -91
  132. package/build/utils/writeWavHeader.js.map +0 -1
  133. package/build/workers/InlineFeaturesExtractor.web.d.ts +0 -2
  134. package/build/workers/InlineFeaturesExtractor.web.d.ts.map +0 -1
  135. package/build/workers/InlineFeaturesExtractor.web.js +0 -828
  136. package/build/workers/InlineFeaturesExtractor.web.js.map +0 -1
  137. package/build/workers/inlineAudioWebWorker.web.d.ts +0 -2
  138. package/build/workers/inlineAudioWebWorker.web.d.ts.map +0 -1
  139. package/build/workers/inlineAudioWebWorker.web.js +0 -157
  140. package/build/workers/inlineAudioWebWorker.web.js.map +0 -1
  141. package/expo-module.config.json +0 -9
  142. package/ios/AudioAnalysisData.swift +0 -74
  143. package/ios/AudioNotificationManager.swift +0 -135
  144. package/ios/AudioProcessingHelpers.swift +0 -743
  145. package/ios/AudioProcessor.swift +0 -1313
  146. package/ios/AudioStreamError.swift +0 -7
  147. package/ios/AudioStreamManager.swift +0 -1708
  148. package/ios/AudioStreamManagerDelegate.swift +0 -16
  149. package/ios/DataPoint.swift +0 -54
  150. package/ios/DecodingConfig.swift +0 -47
  151. package/ios/ExpoAudioStream.podspec +0 -27
  152. package/ios/ExpoAudioStreamModule.swift +0 -805
  153. package/ios/FFT.swift +0 -62
  154. package/ios/Features.swift +0 -95
  155. package/ios/Logger.swift +0 -7
  156. package/ios/NotificationExtension.swift +0 -15
  157. package/ios/RecordingResult.swift +0 -22
  158. package/ios/RecordingSettings.swift +0 -265
  159. package/ios/WaveformExtractor.swift +0 -105
  160. package/plugin/build/index.d.ts +0 -21
  161. package/plugin/build/index.js +0 -191
  162. package/plugin/src/index.ts +0 -278
  163. package/plugin/tsconfig.json +0 -10
  164. package/plugin/tsconfig.tsbuildinfo +0 -1
  165. package/src/AudioAnalysis/AudioAnalysis.types.ts +0 -202
  166. package/src/AudioAnalysis/extractAudioAnalysis.ts +0 -333
  167. package/src/AudioAnalysis/extractAudioData.ts +0 -6
  168. package/src/AudioAnalysis/extractMelSpectrogram.ts +0 -144
  169. package/src/AudioAnalysis/extractPreview.ts +0 -34
  170. package/src/AudioAnalysis/extractWaveform.ts +0 -22
  171. package/src/AudioRecorder.provider.tsx +0 -54
  172. package/src/ExpoAudioStream.native.ts +0 -6
  173. package/src/ExpoAudioStream.types.ts +0 -641
  174. package/src/ExpoAudioStream.web.ts +0 -359
  175. package/src/ExpoAudioStreamModule.ts +0 -967
  176. package/src/WebRecorder.web.ts +0 -580
  177. package/src/constants.ts +0 -18
  178. package/src/events.ts +0 -60
  179. package/src/trimAudio.ts +0 -90
  180. package/src/useAudioRecorder.tsx +0 -620
  181. package/src/utils/BlobFix.ts +0 -559
  182. package/src/utils/audioProcessing.ts +0 -205
  183. package/src/utils/concatenateBuffers.ts +0 -24
  184. package/src/utils/convertPCMToFloat32.ts +0 -170
  185. package/src/utils/encodingToBitDepth.ts +0 -18
  186. package/src/utils/getWavFileInfo.ts +0 -132
  187. package/src/utils/writeWavHeader.ts +0 -114
  188. package/src/workers/InlineFeaturesExtractor.web.tsx +0 -827
  189. package/src/workers/inlineAudioWebWorker.web.tsx +0 -156
@@ -1,359 +0,0 @@
1
- // src/ExpoAudioStreamModule.web.ts
2
- import { LegacyEventEmitter } from 'expo-modules-core'
3
-
4
- import { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'
5
- import {
6
- AudioRecording,
7
- AudioStreamStatus,
8
- BitDepth,
9
- ConsoleLike,
10
- RecordingConfig,
11
- StartRecordingResult,
12
- } from './ExpoAudioStream.types'
13
- import { WebRecorder } from './WebRecorder.web'
14
- import { AudioEventPayload } from './events'
15
- import { encodingToBitDepth } from './utils/encodingToBitDepth'
16
-
17
- export interface EmitAudioEventProps {
18
- data: Float32Array
19
- position: number
20
- compression?: {
21
- data: Blob
22
- size: number
23
- totalSize: number
24
- mimeType: string
25
- format: string
26
- bitrate: number
27
- }
28
- }
29
- export type EmitAudioEventFunction = (_: EmitAudioEventProps) => void
30
- export type EmitAudioAnalysisFunction = (_: AudioAnalysis) => void
31
-
32
- export interface ExpoAudioStreamWebProps {
33
- logger?: ConsoleLike
34
- audioWorkletUrl: string
35
- featuresExtratorUrl: string
36
- maxBufferSize?: number // Maximum number of chunks to keep in memory
37
- }
38
-
39
- export class ExpoAudioStreamWeb extends LegacyEventEmitter {
40
- customRecorder: WebRecorder | null
41
- audioChunks: Float32Array[]
42
- isRecording: boolean
43
- isPaused: boolean
44
- recordingStartTime: number
45
- pausedTime: number
46
- currentDurationMs: number
47
- currentSize: number
48
- currentInterval: number
49
- currentIntervalAnalysis: number
50
- lastEmittedSize: number
51
- lastEmittedTime: number
52
- lastEmittedCompressionSize: number
53
- lastEmittedAnalysisTime: number
54
- streamUuid: string | null
55
- extension: 'webm' | 'wav' = 'wav' // Default extension is 'wav'
56
- recordingConfig?: RecordingConfig
57
- bitDepth: BitDepth // Bit depth of the audio
58
- audioWorkletUrl: string
59
- featuresExtratorUrl: string
60
- logger?: ConsoleLike
61
- latestPosition: number = 0
62
- totalCompressedSize: number = 0
63
- private readonly maxBufferSize: number
64
-
65
- constructor({
66
- audioWorkletUrl,
67
- featuresExtratorUrl,
68
- logger,
69
- maxBufferSize = 100, // Default to storing last 100 chunks (1 chunk = 0.5 seconds)
70
- }: ExpoAudioStreamWebProps) {
71
- const mockNativeModule = {
72
- addListener: () => {
73
- // Not used on web
74
- },
75
- removeListeners: () => {
76
- // Not used on web
77
- },
78
- }
79
- super(mockNativeModule) // Pass the mock native module to the parent class
80
-
81
- this.logger = logger
82
- this.customRecorder = null
83
- this.audioChunks = []
84
- this.isRecording = false
85
- this.isPaused = false
86
- this.recordingStartTime = 0
87
- this.pausedTime = 0
88
- this.currentDurationMs = 0
89
- this.currentSize = 0
90
- this.bitDepth = 32 // Default
91
- this.currentInterval = 1000 // Default interval in ms
92
- this.currentIntervalAnalysis = 500 // Default analysis interval in ms
93
- this.lastEmittedSize = 0
94
- this.lastEmittedTime = 0
95
- this.latestPosition = 0
96
- this.lastEmittedCompressionSize = 0
97
- this.lastEmittedAnalysisTime = 0
98
- this.streamUuid = null // Initialize UUID on first recording start
99
- this.audioWorkletUrl = audioWorkletUrl
100
- this.featuresExtratorUrl = featuresExtratorUrl
101
- this.maxBufferSize = maxBufferSize
102
- }
103
-
104
- // Utility to handle user media stream
105
- async getMediaStream() {
106
- try {
107
- return await navigator.mediaDevices.getUserMedia({ audio: true })
108
- } catch (error) {
109
- this.logger?.error('Failed to get media stream:', error)
110
- throw error
111
- }
112
- }
113
-
114
- // Start recording with options
115
- async startRecording(
116
- recordingConfig: RecordingConfig = {}
117
- ): Promise<StartRecordingResult> {
118
- if (this.isRecording) {
119
- throw new Error('Recording is already in progress')
120
- }
121
-
122
- this.bitDepth = encodingToBitDepth({
123
- encoding: recordingConfig.encoding ?? 'pcm_32bit',
124
- })
125
-
126
- const audioContext = new (window.AudioContext ||
127
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
128
- // @ts-ignore - Allow webkitAudioContext for Safari
129
- window.webkitAudioContext)()
130
- const stream = await this.getMediaStream()
131
-
132
- const source = audioContext.createMediaStreamSource(stream)
133
-
134
- this.customRecorder = new WebRecorder({
135
- logger: this.logger,
136
- audioContext,
137
- source,
138
- recordingConfig,
139
- emitAudioEventCallback: ({
140
- data,
141
- position,
142
- compression,
143
- }: EmitAudioEventProps) => {
144
- // Keep only the latest chunks based on maxBufferSize
145
- this.audioChunks.push(new Float32Array(data))
146
- if (this.audioChunks.length > this.maxBufferSize) {
147
- this.audioChunks.shift() // Remove oldest chunk
148
- }
149
- this.currentSize += data.byteLength
150
- this.emitAudioEvent({ data, position, compression })
151
- this.lastEmittedTime = Date.now()
152
- this.lastEmittedSize = this.currentSize
153
- this.lastEmittedCompressionSize = compression?.size ?? 0
154
- },
155
- emitAudioAnalysisCallback: (audioAnalysisData: AudioAnalysis) => {
156
- this.logger?.log(`Emitted AudioAnalysis:`, audioAnalysisData)
157
- this.emit('AudioAnalysis', audioAnalysisData)
158
- },
159
- })
160
- await this.customRecorder.init()
161
- this.customRecorder.start()
162
-
163
- // // Set a timer to stop recording after 5 seconds
164
- // setTimeout(() => {
165
- // logger.log("AUTO Stopping recording");
166
- // this.customRecorder?.stopAndPlay();
167
- // this.isRecording = false;
168
- // }, 3000);
169
-
170
- this.isRecording = true
171
- this.recordingConfig = recordingConfig
172
- this.recordingStartTime = Date.now()
173
- this.pausedTime = 0
174
- this.isPaused = false
175
- this.lastEmittedSize = 0
176
- this.lastEmittedTime = 0
177
- this.lastEmittedCompressionSize = 0
178
- this.currentInterval = recordingConfig.interval ?? 1000
179
- this.currentIntervalAnalysis = recordingConfig.intervalAnalysis ?? 500
180
- this.lastEmittedAnalysisTime = Date.now()
181
-
182
- // Use custom filename if provided, otherwise fallback to timestamp
183
- if (recordingConfig.filename) {
184
- // Remove any existing extension from the filename
185
- this.streamUuid = recordingConfig.filename.replace(/\.[^/.]+$/, '')
186
- } else {
187
- this.streamUuid = Date.now().toString()
188
- }
189
-
190
- const fileUri = `${this.streamUuid}.${this.extension}`
191
- const streamConfig: StartRecordingResult = {
192
- fileUri,
193
- mimeType: `audio/${this.extension}`,
194
- bitDepth: this.bitDepth,
195
- channels: recordingConfig.channels ?? 1,
196
- sampleRate: recordingConfig.sampleRate ?? 44100,
197
- compression: recordingConfig.compression
198
- ? {
199
- ...recordingConfig.compression,
200
- bitrate: recordingConfig.compression?.bitrate ?? 128000,
201
- size: 0,
202
- mimeType: 'audio/webm',
203
- format: recordingConfig.compression?.format ?? 'opus',
204
- compressedFileUri: '',
205
- }
206
- : undefined,
207
- }
208
- return streamConfig
209
- }
210
-
211
- emitAudioEvent({ data, position, compression }: EmitAudioEventProps) {
212
- const fileUri = `${this.streamUuid}.${this.extension}`
213
- if (compression?.size) {
214
- this.lastEmittedCompressionSize = compression.size
215
- this.totalCompressedSize = compression.totalSize
216
- }
217
- this.latestPosition = position
218
- this.currentDurationMs = position * 1000 // Convert position (in seconds) to ms
219
-
220
- const audioEventPayload: AudioEventPayload = {
221
- fileUri,
222
- mimeType: `audio/${this.extension}`,
223
- lastEmittedSize: this.lastEmittedSize,
224
- deltaSize: data.byteLength,
225
- position,
226
- totalSize: this.currentSize,
227
- buffer: data,
228
- streamUuid: this.streamUuid ?? '',
229
- compression: compression
230
- ? {
231
- data: compression?.data,
232
- totalSize: this.totalCompressedSize,
233
- eventDataSize: compression?.size ?? 0,
234
- position,
235
- }
236
- : undefined,
237
- }
238
-
239
- this.emit('AudioData', audioEventPayload)
240
- }
241
-
242
- // Stop recording
243
- async stopRecording(): Promise<AudioRecording> {
244
- if (!this.customRecorder) {
245
- throw new Error('Recorder is not initialized')
246
- }
247
-
248
- this.logger?.debug('[Stop] Starting stop process')
249
- const startTime = performance.now()
250
-
251
- try {
252
- this.logger?.debug('[Stop] Stopping recorder')
253
- const { compressedBlob } = await this.customRecorder.stop()
254
-
255
- this.isRecording = false
256
- this.isPaused = false
257
- this.currentDurationMs = Date.now() - this.recordingStartTime
258
-
259
- let compression: AudioRecording['compression']
260
- let fileUri = `${this.streamUuid}.${this.extension}`
261
- let mimeType = `audio/${this.extension}`
262
-
263
- if (compressedBlob && this.recordingConfig?.compression?.enabled) {
264
- const compressedUri = URL.createObjectURL(compressedBlob)
265
- compression = {
266
- compressedFileUri: compressedUri,
267
- size: compressedBlob.size,
268
- mimeType: 'audio/webm',
269
- format: 'opus',
270
- bitrate: this.recordingConfig.compression.bitrate ?? 128000,
271
- }
272
- // Use compressed values when compression is enabled
273
- fileUri = compressedUri
274
- mimeType = 'audio/webm'
275
- }
276
-
277
- this.logger?.debug(
278
- `[Stop] Completed stop process in ${performance.now() - startTime}ms`,
279
- {
280
- durationMs: this.currentDurationMs,
281
- compressedSize: compression?.size,
282
- }
283
- )
284
-
285
- // Use the stored streamUuid (which contains our custom filename) for the final filename
286
- const filename = `${this.streamUuid}.${this.extension}`
287
- const result: AudioRecording = {
288
- fileUri,
289
- filename, // This will now use our custom filename
290
- bitDepth: this.bitDepth,
291
- createdAt: this.recordingStartTime,
292
- channels: this.recordingConfig?.channels ?? 1,
293
- sampleRate: this.recordingConfig?.sampleRate ?? 44100,
294
- durationMs: this.currentDurationMs,
295
- size: this.currentSize,
296
- mimeType,
297
- compression,
298
- }
299
-
300
- // Reset after creating the result
301
- this.streamUuid = null
302
-
303
- return result
304
- } catch (error) {
305
- this.logger?.error('[Stop] Error stopping recording:', error)
306
- throw error
307
- }
308
- }
309
-
310
- // Pause recording
311
- async pauseRecording() {
312
- if (!this.isRecording || this.isPaused) {
313
- throw new Error('Recording is not active or already paused')
314
- }
315
-
316
- if (this.customRecorder) {
317
- this.customRecorder.pause()
318
- }
319
- this.isPaused = true
320
- this.pausedTime = Date.now()
321
- }
322
-
323
- // Resume recording
324
- async resumeRecording() {
325
- if (!this.isPaused) {
326
- throw new Error('Recording is not paused')
327
- }
328
-
329
- if (this.customRecorder) {
330
- this.customRecorder.resume()
331
- }
332
- this.isPaused = false
333
- this.recordingStartTime += Date.now() - this.pausedTime
334
- }
335
-
336
- // Get current status
337
- status() {
338
- const status: AudioStreamStatus = {
339
- isRecording: this.isRecording,
340
- isPaused: this.isPaused,
341
- durationMs: this.currentDurationMs,
342
- size: this.currentSize,
343
- interval: this.currentInterval,
344
- intervalAnalysis: this.currentIntervalAnalysis,
345
- mimeType: `audio/${this.extension}`,
346
- compression: this.recordingConfig?.compression?.enabled
347
- ? {
348
- size: this.totalCompressedSize,
349
- mimeType: 'audio/webm',
350
- format: this.recordingConfig.compression.format ?? 'opus',
351
- bitrate:
352
- this.recordingConfig.compression.bitrate ?? 128000,
353
- compressedFileUri: `${this.streamUuid}.webm`,
354
- }
355
- : undefined,
356
- }
357
- return status
358
- }
359
- }