@siteed/expo-audio-stream 2.1.0 → 2.2.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 (187) hide show
  1. package/README.md +40 -222
  2. package/build/index.d.ts +11 -15
  3. package/build/index.js +44 -14
  4. package/package.json +49 -110
  5. package/src/index.ts +18 -32
  6. package/CHANGELOG.md +0 -206
  7. package/android/build.gradle +0 -105
  8. package/android/src/main/AndroidManifest.xml +0 -27
  9. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +0 -166
  10. package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +0 -9
  11. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +0 -131
  12. package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +0 -103
  13. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +0 -435
  14. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +0 -2235
  15. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +0 -1437
  16. package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +0 -152
  17. package/android/src/main/java/net/siteed/audiostream/AudioTrimmer.kt +0 -1099
  18. package/android/src/main/java/net/siteed/audiostream/Constants.kt +0 -21
  19. package/android/src/main/java/net/siteed/audiostream/EventSender.kt +0 -7
  20. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +0 -739
  21. package/android/src/main/java/net/siteed/audiostream/FFT.kt +0 -99
  22. package/android/src/main/java/net/siteed/audiostream/Features.kt +0 -98
  23. package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +0 -70
  24. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +0 -59
  25. package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +0 -59
  26. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +0 -205
  27. package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +0 -19
  28. package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +0 -159
  29. package/android/src/main/res/drawable/ic_default_action_icon.xml +0 -16
  30. package/android/src/main/res/drawable/ic_microphone.xml +0 -13
  31. package/android/src/main/res/drawable/ic_pause.xml +0 -10
  32. package/android/src/main/res/drawable/ic_play.xml +0 -10
  33. package/android/src/main/res/drawable/ic_stop.xml +0 -10
  34. package/android/src/main/res/layout/notification_recording.xml +0 -37
  35. package/android/src/main/test/java/net/siteed/audiostream/AudioProcessorTest.kt +0 -56
  36. package/app.plugin.js +0 -1
  37. package/build/AudioAnalysis/AudioAnalysis.types.d.ts +0 -179
  38. package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +0 -1
  39. package/build/AudioAnalysis/AudioAnalysis.types.js +0 -3
  40. package/build/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  41. package/build/AudioAnalysis/extractAudioAnalysis.d.ts +0 -68
  42. package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +0 -1
  43. package/build/AudioAnalysis/extractAudioAnalysis.js +0 -203
  44. package/build/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  45. package/build/AudioAnalysis/extractAudioData.d.ts +0 -3
  46. package/build/AudioAnalysis/extractAudioData.d.ts.map +0 -1
  47. package/build/AudioAnalysis/extractAudioData.js +0 -5
  48. package/build/AudioAnalysis/extractAudioData.js.map +0 -1
  49. package/build/AudioAnalysis/extractMelSpectrogram.d.ts +0 -14
  50. package/build/AudioAnalysis/extractMelSpectrogram.d.ts.map +0 -1
  51. package/build/AudioAnalysis/extractMelSpectrogram.js +0 -85
  52. package/build/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  53. package/build/AudioAnalysis/extractPreview.d.ts +0 -11
  54. package/build/AudioAnalysis/extractPreview.d.ts.map +0 -1
  55. package/build/AudioAnalysis/extractPreview.js +0 -25
  56. package/build/AudioAnalysis/extractPreview.js.map +0 -1
  57. package/build/AudioAnalysis/extractWaveform.d.ts +0 -8
  58. package/build/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  59. package/build/AudioAnalysis/extractWaveform.js +0 -11
  60. package/build/AudioAnalysis/extractWaveform.js.map +0 -1
  61. package/build/AudioRecorder.provider.d.ts +0 -11
  62. package/build/AudioRecorder.provider.d.ts.map +0 -1
  63. package/build/AudioRecorder.provider.js +0 -37
  64. package/build/AudioRecorder.provider.js.map +0 -1
  65. package/build/ExpoAudioStream.native.d.ts +0 -3
  66. package/build/ExpoAudioStream.native.d.ts.map +0 -1
  67. package/build/ExpoAudioStream.native.js +0 -6
  68. package/build/ExpoAudioStream.native.js.map +0 -1
  69. package/build/ExpoAudioStream.types.d.ts +0 -532
  70. package/build/ExpoAudioStream.types.d.ts.map +0 -1
  71. package/build/ExpoAudioStream.types.js +0 -2
  72. package/build/ExpoAudioStream.types.js.map +0 -1
  73. package/build/ExpoAudioStream.web.d.ts +0 -59
  74. package/build/ExpoAudioStream.web.d.ts.map +0 -1
  75. package/build/ExpoAudioStream.web.js +0 -285
  76. package/build/ExpoAudioStream.web.js.map +0 -1
  77. package/build/ExpoAudioStreamModule.d.ts +0 -3
  78. package/build/ExpoAudioStreamModule.d.ts.map +0 -1
  79. package/build/ExpoAudioStreamModule.js +0 -693
  80. package/build/ExpoAudioStreamModule.js.map +0 -1
  81. package/build/WebRecorder.web.d.ts +0 -119
  82. package/build/WebRecorder.web.d.ts.map +0 -1
  83. package/build/WebRecorder.web.js +0 -436
  84. package/build/WebRecorder.web.js.map +0 -1
  85. package/build/constants.d.ts +0 -11
  86. package/build/constants.d.ts.map +0 -1
  87. package/build/constants.js +0 -14
  88. package/build/constants.js.map +0 -1
  89. package/build/events.d.ts +0 -26
  90. package/build/events.d.ts.map +0 -1
  91. package/build/events.js +0 -21
  92. package/build/events.js.map +0 -1
  93. package/build/index.d.ts.map +0 -1
  94. package/build/index.js.map +0 -1
  95. package/build/trimAudio.d.ts +0 -25
  96. package/build/trimAudio.d.ts.map +0 -1
  97. package/build/trimAudio.js +0 -67
  98. package/build/trimAudio.js.map +0 -1
  99. package/build/useAudioRecorder.d.ts +0 -21
  100. package/build/useAudioRecorder.d.ts.map +0 -1
  101. package/build/useAudioRecorder.js +0 -427
  102. package/build/useAudioRecorder.js.map +0 -1
  103. package/build/utils/BlobFix.d.ts +0 -9
  104. package/build/utils/BlobFix.d.ts.map +0 -1
  105. package/build/utils/BlobFix.js +0 -498
  106. package/build/utils/BlobFix.js.map +0 -1
  107. package/build/utils/audioProcessing.d.ts +0 -24
  108. package/build/utils/audioProcessing.d.ts.map +0 -1
  109. package/build/utils/audioProcessing.js +0 -133
  110. package/build/utils/audioProcessing.js.map +0 -1
  111. package/build/utils/concatenateBuffers.d.ts +0 -8
  112. package/build/utils/concatenateBuffers.d.ts.map +0 -1
  113. package/build/utils/concatenateBuffers.js +0 -21
  114. package/build/utils/concatenateBuffers.js.map +0 -1
  115. package/build/utils/convertPCMToFloat32.d.ts +0 -13
  116. package/build/utils/convertPCMToFloat32.d.ts.map +0 -1
  117. package/build/utils/convertPCMToFloat32.js +0 -120
  118. package/build/utils/convertPCMToFloat32.js.map +0 -1
  119. package/build/utils/encodingToBitDepth.d.ts +0 -5
  120. package/build/utils/encodingToBitDepth.d.ts.map +0 -1
  121. package/build/utils/encodingToBitDepth.js +0 -13
  122. package/build/utils/encodingToBitDepth.js.map +0 -1
  123. package/build/utils/getWavFileInfo.d.ts +0 -26
  124. package/build/utils/getWavFileInfo.d.ts.map +0 -1
  125. package/build/utils/getWavFileInfo.js +0 -92
  126. package/build/utils/getWavFileInfo.js.map +0 -1
  127. package/build/utils/writeWavHeader.d.ts +0 -49
  128. package/build/utils/writeWavHeader.d.ts.map +0 -1
  129. package/build/utils/writeWavHeader.js +0 -91
  130. package/build/utils/writeWavHeader.js.map +0 -1
  131. package/build/workers/InlineFeaturesExtractor.web.d.ts +0 -2
  132. package/build/workers/InlineFeaturesExtractor.web.d.ts.map +0 -1
  133. package/build/workers/InlineFeaturesExtractor.web.js +0 -828
  134. package/build/workers/InlineFeaturesExtractor.web.js.map +0 -1
  135. package/build/workers/inlineAudioWebWorker.web.d.ts +0 -2
  136. package/build/workers/inlineAudioWebWorker.web.d.ts.map +0 -1
  137. package/build/workers/inlineAudioWebWorker.web.js +0 -157
  138. package/build/workers/inlineAudioWebWorker.web.js.map +0 -1
  139. package/expo-module.config.json +0 -9
  140. package/ios/AudioAnalysisData.swift +0 -74
  141. package/ios/AudioNotificationManager.swift +0 -135
  142. package/ios/AudioProcessingHelpers.swift +0 -743
  143. package/ios/AudioProcessor.swift +0 -1313
  144. package/ios/AudioStreamError.swift +0 -7
  145. package/ios/AudioStreamManager.swift +0 -1708
  146. package/ios/AudioStreamManagerDelegate.swift +0 -16
  147. package/ios/DataPoint.swift +0 -54
  148. package/ios/DecodingConfig.swift +0 -47
  149. package/ios/ExpoAudioStream.podspec +0 -27
  150. package/ios/ExpoAudioStreamModule.swift +0 -805
  151. package/ios/FFT.swift +0 -62
  152. package/ios/Features.swift +0 -95
  153. package/ios/Logger.swift +0 -7
  154. package/ios/NotificationExtension.swift +0 -15
  155. package/ios/RecordingResult.swift +0 -22
  156. package/ios/RecordingSettings.swift +0 -265
  157. package/ios/WaveformExtractor.swift +0 -105
  158. package/plugin/build/index.d.ts +0 -21
  159. package/plugin/build/index.js +0 -191
  160. package/plugin/src/index.ts +0 -278
  161. package/plugin/tsconfig.json +0 -10
  162. package/plugin/tsconfig.tsbuildinfo +0 -1
  163. package/src/AudioAnalysis/AudioAnalysis.types.ts +0 -202
  164. package/src/AudioAnalysis/extractAudioAnalysis.ts +0 -333
  165. package/src/AudioAnalysis/extractAudioData.ts +0 -6
  166. package/src/AudioAnalysis/extractMelSpectrogram.ts +0 -144
  167. package/src/AudioAnalysis/extractPreview.ts +0 -34
  168. package/src/AudioAnalysis/extractWaveform.ts +0 -22
  169. package/src/AudioRecorder.provider.tsx +0 -54
  170. package/src/ExpoAudioStream.native.ts +0 -6
  171. package/src/ExpoAudioStream.types.ts +0 -641
  172. package/src/ExpoAudioStream.web.ts +0 -359
  173. package/src/ExpoAudioStreamModule.ts +0 -967
  174. package/src/WebRecorder.web.ts +0 -580
  175. package/src/constants.ts +0 -18
  176. package/src/events.ts +0 -60
  177. package/src/trimAudio.ts +0 -90
  178. package/src/useAudioRecorder.tsx +0 -620
  179. package/src/utils/BlobFix.ts +0 -559
  180. package/src/utils/audioProcessing.ts +0 -205
  181. package/src/utils/concatenateBuffers.ts +0 -24
  182. package/src/utils/convertPCMToFloat32.ts +0 -170
  183. package/src/utils/encodingToBitDepth.ts +0 -18
  184. package/src/utils/getWavFileInfo.ts +0 -132
  185. package/src/utils/writeWavHeader.ts +0 -114
  186. package/src/workers/InlineFeaturesExtractor.web.tsx +0 -827
  187. 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
- }