@siteed/expo-audio-studio 2.18.6 → 3.0.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.
Files changed (329) hide show
  1. package/README.md +13 -297
  2. package/index.d.ts +1 -0
  3. package/index.js +1 -0
  4. package/package.json +7 -136
  5. package/CHANGELOG.md +0 -501
  6. package/LICENSE +0 -21
  7. package/android/build.gradle +0 -129
  8. package/android/src/androidTest/assets/chorus.wav +0 -0
  9. package/android/src/androidTest/assets/jfk.wav +0 -0
  10. package/android/src/androidTest/assets/osr_us_000_0010_8k.wav +0 -0
  11. package/android/src/androidTest/assets/recorder_hello_world.wav +0 -0
  12. package/android/src/androidTest/java/net/siteed/audiostream/AudioProcessorInstrumentedTest.kt +0 -197
  13. package/android/src/androidTest/java/net/siteed/audiostream/AudioRecorderInstrumentedTest.kt +0 -541
  14. package/android/src/androidTest/java/net/siteed/audiostream/AudioRecorderPerformanceInstrumentedTest.kt +0 -234
  15. package/android/src/androidTest/java/net/siteed/audiostream/integration/AudioFocusStrategyIntegrationTest.kt +0 -332
  16. package/android/src/androidTest/java/net/siteed/audiostream/integration/BufferDurationIntegrationTest.kt +0 -324
  17. package/android/src/androidTest/java/net/siteed/audiostream/integration/CompressedOnlyOutputTest.kt +0 -253
  18. package/android/src/androidTest/java/net/siteed/audiostream/integration/DeviceDisconnectionFallbackTest.kt +0 -218
  19. package/android/src/androidTest/java/net/siteed/audiostream/integration/EventEmissionIntervalTest.kt +0 -120
  20. package/android/src/androidTest/java/net/siteed/audiostream/integration/M4aFormatTest.kt +0 -345
  21. package/android/src/androidTest/java/net/siteed/audiostream/integration/OutputControlIntegrationTest.kt +0 -340
  22. package/android/src/androidTest/java/net/siteed/audiostream/integration/PcmStreamingDurationTest.kt +0 -252
  23. package/android/src/androidTest/java/net/siteed/audiostream/integration/README.md +0 -95
  24. package/android/src/androidTest/java/net/siteed/audiostream/integration/run_integration_tests.sh +0 -43
  25. package/android/src/main/AndroidManifest.xml +0 -30
  26. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +0 -188
  27. package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +0 -9
  28. package/android/src/main/java/net/siteed/audiostream/AudioDeviceManager.kt +0 -1741
  29. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +0 -136
  30. package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +0 -354
  31. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +0 -439
  32. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +0 -2237
  33. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +0 -2141
  34. package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +0 -167
  35. package/android/src/main/java/net/siteed/audiostream/AudioTrimmer.kt +0 -1099
  36. package/android/src/main/java/net/siteed/audiostream/Constants.kt +0 -37
  37. package/android/src/main/java/net/siteed/audiostream/EventSender.kt +0 -7
  38. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +0 -1113
  39. package/android/src/main/java/net/siteed/audiostream/FFT.kt +0 -99
  40. package/android/src/main/java/net/siteed/audiostream/Features.kt +0 -98
  41. package/android/src/main/java/net/siteed/audiostream/LogUtils.kt +0 -93
  42. package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +0 -72
  43. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +0 -68
  44. package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +0 -59
  45. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +0 -257
  46. package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +0 -19
  47. package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +0 -159
  48. package/android/src/main/res/drawable/ic_default_action_icon.xml +0 -16
  49. package/android/src/main/res/drawable/ic_microphone.xml +0 -13
  50. package/android/src/main/res/drawable/ic_pause.xml +0 -10
  51. package/android/src/main/res/drawable/ic_play.xml +0 -10
  52. package/android/src/main/res/drawable/ic_stop.xml +0 -10
  53. package/android/src/main/res/layout/notification_recording.xml +0 -37
  54. package/android/src/test/java/net/siteed/audiostream/AudioFileHandlerTest.kt +0 -279
  55. package/android/src/test/java/net/siteed/audiostream/AudioFocusStrategyTest.kt +0 -249
  56. package/android/src/test/java/net/siteed/audiostream/AudioFormatTest.kt +0 -151
  57. package/android/src/test/java/net/siteed/audiostream/AudioFormatUtilsTest.kt +0 -273
  58. package/android/src/test/java/net/siteed/audiostream/DeviceDisconnectionFallbackUnitTest.kt +0 -140
  59. package/android/src/test/resources/chorus.wav +0 -0
  60. package/android/src/test/resources/generate_test_audio.py +0 -94
  61. package/android/src/test/resources/jfk.wav +0 -0
  62. package/android/src/test/resources/osr_us_000_0010_8k.wav +0 -0
  63. package/android/src/test/resources/recorder_hello_world.wav +0 -0
  64. package/app.plugin.js +0 -3
  65. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js +0 -4
  66. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  67. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +0 -210
  68. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  69. package/build/cjs/AudioAnalysis/extractAudioData.js +0 -21
  70. package/build/cjs/AudioAnalysis/extractAudioData.js.map +0 -1
  71. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js +0 -92
  72. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  73. package/build/cjs/AudioAnalysis/extractPreview.js +0 -28
  74. package/build/cjs/AudioAnalysis/extractPreview.js.map +0 -1
  75. package/build/cjs/AudioAnalysis/extractWaveform.js +0 -18
  76. package/build/cjs/AudioAnalysis/extractWaveform.js.map +0 -1
  77. package/build/cjs/AudioDeviceManager.js +0 -689
  78. package/build/cjs/AudioDeviceManager.js.map +0 -1
  79. package/build/cjs/AudioRecorder.provider.js +0 -78
  80. package/build/cjs/AudioRecorder.provider.js.map +0 -1
  81. package/build/cjs/ExpoAudioStream.native.js +0 -8
  82. package/build/cjs/ExpoAudioStream.native.js.map +0 -1
  83. package/build/cjs/ExpoAudioStream.types.js +0 -11
  84. package/build/cjs/ExpoAudioStream.types.js.map +0 -1
  85. package/build/cjs/ExpoAudioStream.web.js +0 -708
  86. package/build/cjs/ExpoAudioStream.web.js.map +0 -1
  87. package/build/cjs/ExpoAudioStreamModule.js +0 -718
  88. package/build/cjs/ExpoAudioStreamModule.js.map +0 -1
  89. package/build/cjs/WebRecorder.web.js +0 -777
  90. package/build/cjs/WebRecorder.web.js.map +0 -1
  91. package/build/cjs/constants/platformLimitations.js +0 -99
  92. package/build/cjs/constants/platformLimitations.js.map +0 -1
  93. package/build/cjs/constants.js +0 -17
  94. package/build/cjs/constants.js.map +0 -1
  95. package/build/cjs/events.js +0 -29
  96. package/build/cjs/events.js.map +0 -1
  97. package/build/cjs/hooks/useAudioDevices.js +0 -179
  98. package/build/cjs/hooks/useAudioDevices.js.map +0 -1
  99. package/build/cjs/index.js +0 -58
  100. package/build/cjs/index.js.map +0 -1
  101. package/build/cjs/trimAudio.js +0 -76
  102. package/build/cjs/trimAudio.js.map +0 -1
  103. package/build/cjs/useAudioRecorder.js +0 -518
  104. package/build/cjs/useAudioRecorder.js.map +0 -1
  105. package/build/cjs/utils/BlobFix.js +0 -502
  106. package/build/cjs/utils/BlobFix.js.map +0 -1
  107. package/build/cjs/utils/audioProcessing.js +0 -136
  108. package/build/cjs/utils/audioProcessing.js.map +0 -1
  109. package/build/cjs/utils/cleanNativeOptions.js +0 -22
  110. package/build/cjs/utils/cleanNativeOptions.js.map +0 -1
  111. package/build/cjs/utils/concatenateBuffers.js +0 -25
  112. package/build/cjs/utils/concatenateBuffers.js.map +0 -1
  113. package/build/cjs/utils/convertPCMToFloat32.js +0 -124
  114. package/build/cjs/utils/convertPCMToFloat32.js.map +0 -1
  115. package/build/cjs/utils/crc32.js +0 -52
  116. package/build/cjs/utils/crc32.js.map +0 -1
  117. package/build/cjs/utils/encodingToBitDepth.js +0 -17
  118. package/build/cjs/utils/encodingToBitDepth.js.map +0 -1
  119. package/build/cjs/utils/getWavFileInfo.js +0 -96
  120. package/build/cjs/utils/getWavFileInfo.js.map +0 -1
  121. package/build/cjs/utils/writeWavHeader.js +0 -88
  122. package/build/cjs/utils/writeWavHeader.js.map +0 -1
  123. package/build/cjs/workers/InlineFeaturesExtractor.web.js +0 -859
  124. package/build/cjs/workers/InlineFeaturesExtractor.web.js.map +0 -1
  125. package/build/cjs/workers/inlineAudioWebWorker.web.js +0 -184
  126. package/build/cjs/workers/inlineAudioWebWorker.web.js.map +0 -1
  127. package/build/esm/AudioAnalysis/AudioAnalysis.types.js +0 -3
  128. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  129. package/build/esm/AudioAnalysis/extractAudioAnalysis.js +0 -202
  130. package/build/esm/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  131. package/build/esm/AudioAnalysis/extractAudioData.js +0 -14
  132. package/build/esm/AudioAnalysis/extractAudioData.js.map +0 -1
  133. package/build/esm/AudioAnalysis/extractMelSpectrogram.js +0 -89
  134. package/build/esm/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  135. package/build/esm/AudioAnalysis/extractPreview.js +0 -25
  136. package/build/esm/AudioAnalysis/extractPreview.js.map +0 -1
  137. package/build/esm/AudioAnalysis/extractWaveform.js +0 -11
  138. package/build/esm/AudioAnalysis/extractWaveform.js.map +0 -1
  139. package/build/esm/AudioDeviceManager.js +0 -682
  140. package/build/esm/AudioDeviceManager.js.map +0 -1
  141. package/build/esm/AudioRecorder.provider.js +0 -40
  142. package/build/esm/AudioRecorder.provider.js.map +0 -1
  143. package/build/esm/ExpoAudioStream.native.js +0 -6
  144. package/build/esm/ExpoAudioStream.native.js.map +0 -1
  145. package/build/esm/ExpoAudioStream.types.js +0 -8
  146. package/build/esm/ExpoAudioStream.types.js.map +0 -1
  147. package/build/esm/ExpoAudioStream.web.js +0 -704
  148. package/build/esm/ExpoAudioStream.web.js.map +0 -1
  149. package/build/esm/ExpoAudioStreamModule.js +0 -713
  150. package/build/esm/ExpoAudioStreamModule.js.map +0 -1
  151. package/build/esm/WebRecorder.web.js +0 -773
  152. package/build/esm/WebRecorder.web.js.map +0 -1
  153. package/build/esm/constants/platformLimitations.js +0 -90
  154. package/build/esm/constants/platformLimitations.js.map +0 -1
  155. package/build/esm/constants.js +0 -14
  156. package/build/esm/constants.js.map +0 -1
  157. package/build/esm/events.js +0 -21
  158. package/build/esm/events.js.map +0 -1
  159. package/build/esm/hooks/useAudioDevices.js +0 -176
  160. package/build/esm/hooks/useAudioDevices.js.map +0 -1
  161. package/build/esm/index.js +0 -20
  162. package/build/esm/index.js.map +0 -1
  163. package/build/esm/trimAudio.js +0 -69
  164. package/build/esm/trimAudio.js.map +0 -1
  165. package/build/esm/useAudioRecorder.js +0 -512
  166. package/build/esm/useAudioRecorder.js.map +0 -1
  167. package/build/esm/utils/BlobFix.js +0 -498
  168. package/build/esm/utils/BlobFix.js.map +0 -1
  169. package/build/esm/utils/audioProcessing.js +0 -133
  170. package/build/esm/utils/audioProcessing.js.map +0 -1
  171. package/build/esm/utils/cleanNativeOptions.js +0 -19
  172. package/build/esm/utils/cleanNativeOptions.js.map +0 -1
  173. package/build/esm/utils/concatenateBuffers.js +0 -21
  174. package/build/esm/utils/concatenateBuffers.js.map +0 -1
  175. package/build/esm/utils/convertPCMToFloat32.js +0 -120
  176. package/build/esm/utils/convertPCMToFloat32.js.map +0 -1
  177. package/build/esm/utils/crc32.js +0 -50
  178. package/build/esm/utils/crc32.js.map +0 -1
  179. package/build/esm/utils/encodingToBitDepth.js +0 -13
  180. package/build/esm/utils/encodingToBitDepth.js.map +0 -1
  181. package/build/esm/utils/getWavFileInfo.js +0 -92
  182. package/build/esm/utils/getWavFileInfo.js.map +0 -1
  183. package/build/esm/utils/writeWavHeader.js +0 -84
  184. package/build/esm/utils/writeWavHeader.js.map +0 -1
  185. package/build/esm/workers/InlineFeaturesExtractor.web.js +0 -856
  186. package/build/esm/workers/InlineFeaturesExtractor.web.js.map +0 -1
  187. package/build/esm/workers/inlineAudioWebWorker.web.js +0 -181
  188. package/build/esm/workers/inlineAudioWebWorker.web.js.map +0 -1
  189. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +0 -196
  190. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +0 -1
  191. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts +0 -74
  192. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +0 -1
  193. package/build/types/AudioAnalysis/extractAudioData.d.ts +0 -3
  194. package/build/types/AudioAnalysis/extractAudioData.d.ts.map +0 -1
  195. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts +0 -14
  196. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts.map +0 -1
  197. package/build/types/AudioAnalysis/extractPreview.d.ts +0 -11
  198. package/build/types/AudioAnalysis/extractPreview.d.ts.map +0 -1
  199. package/build/types/AudioAnalysis/extractWaveform.d.ts +0 -8
  200. package/build/types/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  201. package/build/types/AudioDeviceManager.d.ts +0 -187
  202. package/build/types/AudioDeviceManager.d.ts.map +0 -1
  203. package/build/types/AudioRecorder.provider.d.ts +0 -11
  204. package/build/types/AudioRecorder.provider.d.ts.map +0 -1
  205. package/build/types/ExpoAudioStream.native.d.ts +0 -3
  206. package/build/types/ExpoAudioStream.native.d.ts.map +0 -1
  207. package/build/types/ExpoAudioStream.types.d.ts +0 -738
  208. package/build/types/ExpoAudioStream.types.d.ts.map +0 -1
  209. package/build/types/ExpoAudioStream.web.d.ts +0 -96
  210. package/build/types/ExpoAudioStream.web.d.ts.map +0 -1
  211. package/build/types/ExpoAudioStreamModule.d.ts +0 -3
  212. package/build/types/ExpoAudioStreamModule.d.ts.map +0 -1
  213. package/build/types/WebRecorder.web.d.ts +0 -198
  214. package/build/types/WebRecorder.web.d.ts.map +0 -1
  215. package/build/types/constants/platformLimitations.d.ts +0 -40
  216. package/build/types/constants/platformLimitations.d.ts.map +0 -1
  217. package/build/types/constants.d.ts +0 -11
  218. package/build/types/constants.d.ts.map +0 -1
  219. package/build/types/events.d.ts +0 -26
  220. package/build/types/events.d.ts.map +0 -1
  221. package/build/types/hooks/useAudioDevices.d.ts +0 -15
  222. package/build/types/hooks/useAudioDevices.d.ts.map +0 -1
  223. package/build/types/index.d.ts +0 -18
  224. package/build/types/index.d.ts.map +0 -1
  225. package/build/types/trimAudio.d.ts +0 -25
  226. package/build/types/trimAudio.d.ts.map +0 -1
  227. package/build/types/useAudioRecorder.d.ts +0 -22
  228. package/build/types/useAudioRecorder.d.ts.map +0 -1
  229. package/build/types/utils/BlobFix.d.ts +0 -9
  230. package/build/types/utils/BlobFix.d.ts.map +0 -1
  231. package/build/types/utils/audioProcessing.d.ts +0 -24
  232. package/build/types/utils/audioProcessing.d.ts.map +0 -1
  233. package/build/types/utils/cleanNativeOptions.d.ts +0 -15
  234. package/build/types/utils/cleanNativeOptions.d.ts.map +0 -1
  235. package/build/types/utils/concatenateBuffers.d.ts +0 -8
  236. package/build/types/utils/concatenateBuffers.d.ts.map +0 -1
  237. package/build/types/utils/convertPCMToFloat32.d.ts +0 -13
  238. package/build/types/utils/convertPCMToFloat32.d.ts.map +0 -1
  239. package/build/types/utils/crc32.d.ts +0 -7
  240. package/build/types/utils/crc32.d.ts.map +0 -1
  241. package/build/types/utils/encodingToBitDepth.d.ts +0 -5
  242. package/build/types/utils/encodingToBitDepth.d.ts.map +0 -1
  243. package/build/types/utils/getWavFileInfo.d.ts +0 -26
  244. package/build/types/utils/getWavFileInfo.d.ts.map +0 -1
  245. package/build/types/utils/writeWavHeader.d.ts +0 -34
  246. package/build/types/utils/writeWavHeader.d.ts.map +0 -1
  247. package/build/types/workers/InlineFeaturesExtractor.web.d.ts +0 -2
  248. package/build/types/workers/InlineFeaturesExtractor.web.d.ts.map +0 -1
  249. package/build/types/workers/inlineAudioWebWorker.web.d.ts +0 -2
  250. package/build/types/workers/inlineAudioWebWorker.web.d.ts.map +0 -1
  251. package/expo-module.config.json +0 -10
  252. package/ios/AudioAnalysisData.swift +0 -74
  253. package/ios/AudioDeviceManager.swift +0 -670
  254. package/ios/AudioNotificationManager.swift +0 -154
  255. package/ios/AudioProcessingHelpers.swift +0 -743
  256. package/ios/AudioProcessor.swift +0 -1151
  257. package/ios/AudioStreamError.swift +0 -7
  258. package/ios/AudioStreamManager.swift +0 -2369
  259. package/ios/AudioStreamManagerDelegate.swift +0 -16
  260. package/ios/DataPoint.swift +0 -54
  261. package/ios/DecodingConfig.swift +0 -59
  262. package/ios/ExpoAudioStream.podspec +0 -33
  263. package/ios/ExpoAudioStreamModule.swift +0 -1019
  264. package/ios/ExpoAudioStudioTests/AudioFileHandlerTests.swift +0 -338
  265. package/ios/ExpoAudioStudioTests/AudioFormatUtilsTests.swift +0 -331
  266. package/ios/ExpoAudioStudioTests/AudioTestHelpers.swift +0 -130
  267. package/ios/ExpoAudioStudioTests/CompressedOnlyOutputTests.swift +0 -294
  268. package/ios/ExpoAudioStudioTests/EventEmissionIntervalTests.swift +0 -105
  269. package/ios/ExpoAudioStudioTests/Info.plist +0 -22
  270. package/ios/ExpoAudioStudioTests/README.md +0 -39
  271. package/ios/ExpoAudioStudioTests/SimpleAudioTest.swift +0 -98
  272. package/ios/ExpoAudioStudioTests/TestAudioGenerator.swift +0 -75
  273. package/ios/FFT.swift +0 -62
  274. package/ios/Features.swift +0 -95
  275. package/ios/ISSUE_IOS.md +0 -68
  276. package/ios/Logger.swift +0 -39
  277. package/ios/NotificationExtension.swift +0 -15
  278. package/ios/RecordingResult.swift +0 -22
  279. package/ios/RecordingSettings.swift +0 -308
  280. package/ios/WaveformExtractor.swift +0 -105
  281. package/ios/tests/README.md +0 -41
  282. package/ios/tests/integration/buffer_and_fallback_test.swift +0 -178
  283. package/ios/tests/integration/buffer_duration_test.swift +0 -185
  284. package/ios/tests/integration/compressed_only_output_test.swift +0 -271
  285. package/ios/tests/integration/output_control_test.swift +0 -322
  286. package/ios/tests/integration/run_integration_tests.sh +0 -37
  287. package/ios/tests/opus_support_test_macos.swift +0 -154
  288. package/ios/tests/standalone/audio_processing_test.swift +0 -144
  289. package/ios/tests/standalone/audio_recording_test.swift +0 -277
  290. package/ios/tests/standalone/audio_streaming_test.swift +0 -249
  291. package/ios/tests/standalone/standalone_test.swift +0 -144
  292. package/plugin/build/index.cjs +0 -194
  293. package/plugin/build/index.d.cts +0 -22
  294. package/plugin/build/index.js +0 -194
  295. package/plugin/src/index.ts +0 -285
  296. package/plugin/tsconfig.json +0 -10
  297. package/plugin/tsconfig.tsbuildinfo +0 -1
  298. package/src/AudioAnalysis/AudioAnalysis.types.ts +0 -224
  299. package/src/AudioAnalysis/extractAudioAnalysis.ts +0 -344
  300. package/src/AudioAnalysis/extractAudioData.ts +0 -17
  301. package/src/AudioAnalysis/extractMelSpectrogram.ts +0 -154
  302. package/src/AudioAnalysis/extractPreview.ts +0 -34
  303. package/src/AudioAnalysis/extractWaveform.ts +0 -22
  304. package/src/AudioDeviceManager.ts +0 -803
  305. package/src/AudioRecorder.provider.tsx +0 -57
  306. package/src/ExpoAudioStream.native.ts +0 -6
  307. package/src/ExpoAudioStream.types.ts +0 -874
  308. package/src/ExpoAudioStream.web.ts +0 -905
  309. package/src/ExpoAudioStreamModule.ts +0 -990
  310. package/src/WebRecorder.web.ts +0 -1005
  311. package/src/constants/platformLimitations.ts +0 -118
  312. package/src/constants.ts +0 -18
  313. package/src/events.ts +0 -60
  314. package/src/hooks/useAudioDevices.ts +0 -213
  315. package/src/index.ts +0 -54
  316. package/src/trimAudio.ts +0 -94
  317. package/src/types/crc-32.d.ts +0 -9
  318. package/src/useAudioRecorder.tsx +0 -766
  319. package/src/utils/BlobFix.ts +0 -561
  320. package/src/utils/audioProcessing.ts +0 -205
  321. package/src/utils/cleanNativeOptions.ts +0 -18
  322. package/src/utils/concatenateBuffers.ts +0 -24
  323. package/src/utils/convertPCMToFloat32.ts +0 -170
  324. package/src/utils/crc32.ts +0 -59
  325. package/src/utils/encodingToBitDepth.ts +0 -18
  326. package/src/utils/getWavFileInfo.ts +0 -132
  327. package/src/utils/writeWavHeader.ts +0 -115
  328. package/src/workers/InlineFeaturesExtractor.web.tsx +0 -855
  329. package/src/workers/inlineAudioWebWorker.web.tsx +0 -180
@@ -1,766 +0,0 @@
1
- // src/useAudioRecorder.ts
2
- import { EventSubscription, Platform } from 'expo-modules-core'
3
- import { useCallback, useEffect, useReducer, useRef, useId } from 'react'
4
-
5
- import { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'
6
- import { audioDeviceManager } from './AudioDeviceManager'
7
- import {
8
- AudioDataEvent,
9
- AudioRecording,
10
- AudioStreamStatus,
11
- CompressionInfo,
12
- ConsoleLike,
13
- RecordingConfig,
14
- StartRecordingResult,
15
- } from './ExpoAudioStream.types'
16
- import ExpoAudioStreamModule from './ExpoAudioStreamModule'
17
- import { validateRecordingConfig } from './constants/platformLimitations'
18
- import {
19
- addAudioAnalysisListener,
20
- addAudioEventListener,
21
- AudioEventPayload,
22
- addRecordingInterruptionListener,
23
- } from './events'
24
- import { cleanNativeOptions } from './utils/cleanNativeOptions'
25
-
26
- export interface UseAudioRecorderProps {
27
- logger?: ConsoleLike
28
- audioWorkletUrl?: string
29
- featuresExtratorUrl?: string
30
- }
31
-
32
- export interface UseAudioRecorderState {
33
- prepareRecording: (_: RecordingConfig) => Promise<void>
34
- startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>
35
- stopRecording: () => Promise<AudioRecording>
36
- pauseRecording: () => Promise<void>
37
- resumeRecording: () => Promise<void>
38
- isRecording: boolean
39
- isPaused: boolean
40
- durationMs: number
41
- size: number
42
- compression?: CompressionInfo
43
- analysisData?: AudioAnalysis
44
- }
45
-
46
- interface RecorderReducerState {
47
- isRecording: boolean
48
- isPaused: boolean
49
- durationMs: number
50
- size: number
51
- compression?: CompressionInfo
52
- analysisData?: AudioAnalysis
53
- }
54
-
55
- type RecorderAction =
56
- | { type: 'START' | 'STOP' | 'PAUSE' | 'RESUME' }
57
- | {
58
- type: 'UPDATE_RECORDING_STATE'
59
- payload: {
60
- isRecording: boolean
61
- isPaused: boolean
62
- }
63
- }
64
- | {
65
- type: 'UPDATE_STATUS'
66
- payload: {
67
- durationMs: number
68
- size: number
69
- compression?: CompressionInfo
70
- }
71
- }
72
- | { type: 'UPDATE_ANALYSIS'; payload: AudioAnalysis }
73
-
74
- const defaultAnalysis: AudioAnalysis = {
75
- segmentDurationMs: 100,
76
- bitDepth: 32,
77
- numberOfChannels: 1,
78
- durationMs: 0,
79
- sampleRate: 44100,
80
- samples: 0,
81
- dataPoints: [],
82
- rmsRange: {
83
- min: Number.POSITIVE_INFINITY,
84
- max: Number.NEGATIVE_INFINITY,
85
- },
86
- amplitudeRange: {
87
- min: Number.POSITIVE_INFINITY,
88
- max: Number.NEGATIVE_INFINITY,
89
- },
90
- extractionTimeMs: 0,
91
- }
92
-
93
- function audioRecorderReducer(
94
- state: RecorderReducerState,
95
- action: RecorderAction
96
- ): RecorderReducerState {
97
- switch (action.type) {
98
- case 'START':
99
- return {
100
- ...state,
101
- isRecording: true,
102
- isPaused: false,
103
- durationMs: 0,
104
- size: 0,
105
- compression: undefined,
106
- analysisData: defaultAnalysis,
107
- }
108
- case 'STOP':
109
- return {
110
- ...state,
111
- isRecording: false,
112
- isPaused: false,
113
- durationMs: 0,
114
- size: 0,
115
- compression: undefined,
116
- analysisData: undefined,
117
- }
118
- case 'PAUSE':
119
- return { ...state, isPaused: true, isRecording: false }
120
- case 'RESUME':
121
- return { ...state, isPaused: false, isRecording: true }
122
- case 'UPDATE_RECORDING_STATE':
123
- return {
124
- ...state,
125
- isPaused: action.payload.isPaused,
126
- isRecording: action.payload.isRecording,
127
- }
128
- case 'UPDATE_STATUS': {
129
- const newState = {
130
- ...state,
131
- durationMs: action.payload.durationMs,
132
- size: action.payload.size,
133
- compression: action.payload.compression
134
- ? {
135
- size: action.payload.compression.size,
136
- mimeType: action.payload.compression.mimeType,
137
- bitrate: action.payload.compression.bitrate,
138
- format: action.payload.compression.format,
139
- }
140
- : undefined,
141
- }
142
- return newState
143
- }
144
- case 'UPDATE_ANALYSIS':
145
- return {
146
- ...state,
147
- analysisData: action.payload,
148
- }
149
- default:
150
- return state
151
- }
152
- }
153
-
154
- interface HandleAudioAnalysisProps {
155
- analysis: AudioAnalysis
156
- visualizationDuration: number
157
- }
158
-
159
- export function useAudioRecorder({
160
- logger,
161
- audioWorkletUrl,
162
- featuresExtratorUrl,
163
- }: UseAudioRecorderProps = {}): UseAudioRecorderState {
164
- // Initialize AudioDeviceManager with logger (once)
165
- if (logger) {
166
- audioDeviceManager.setLogger(logger)
167
- }
168
- const [state, dispatch] = useReducer(audioRecorderReducer, {
169
- isRecording: false,
170
- isPaused: false,
171
- durationMs: 0,
172
- size: 0,
173
- compression: undefined,
174
- analysisData: undefined,
175
- })
176
-
177
- const startResultRef = useRef<StartRecordingResult | null>(null)
178
-
179
- const analysisListenerRef = useRef<EventSubscription | null>(null)
180
- // analysisRef is the current analysis data (last 10 seconds by default)
181
- const analysisRef = useRef<AudioAnalysis>({ ...defaultAnalysis })
182
- // fullAnalysisRef is the full analysis data (all data points)
183
- const fullAnalysisRef = useRef<AudioAnalysis>({
184
- ...defaultAnalysis,
185
- })
186
-
187
- // Instantiate the module for web with URLs
188
- const ExpoAudioStream =
189
- Platform.OS === 'web'
190
- ? ExpoAudioStreamModule({
191
- audioWorkletUrl,
192
- featuresExtratorUrl,
193
- logger,
194
- })
195
- : ExpoAudioStreamModule
196
-
197
- const onAudioStreamRef = useRef<
198
- ((_: AudioDataEvent) => Promise<void>) | null
199
- >(null)
200
-
201
- const stateRef = useRef({
202
- isRecording: false,
203
- isPaused: false,
204
- durationMs: 0,
205
- size: 0,
206
- compression: undefined as CompressionInfo | undefined,
207
- })
208
-
209
- const recordingConfigRef = useRef<RecordingConfig | null>(null)
210
-
211
- // Generate unique instance ID for debugging
212
- const instanceId = useId().replace(/:/g, '').slice(0, 5)
213
-
214
- const handleAudioAnalysis = useCallback(
215
- async ({
216
- analysis,
217
- visualizationDuration,
218
- }: HandleAudioAnalysisProps) => {
219
- const savedAnalysisData = analysisRef.current || {
220
- ...defaultAnalysis,
221
- }
222
-
223
- const maxDuration = visualizationDuration
224
-
225
- logger?.debug(
226
- `[handleAudioAnalysis] Received audio analysis: maxDuration=${maxDuration} analysis.dataPoints=${analysis.dataPoints.length} analysisData.dataPoints=${savedAnalysisData.dataPoints.length}`
227
- )
228
-
229
- // Combine data points
230
- const combinedDataPoints = [
231
- ...savedAnalysisData.dataPoints,
232
- ...analysis.dataPoints,
233
- ]
234
-
235
- const fullCombinedDataPoints = [
236
- ...(fullAnalysisRef.current?.dataPoints ?? []),
237
- ...analysis.dataPoints,
238
- ]
239
-
240
- // Calculate the new duration
241
- // The number of segments is based on how many segments of segmentDurationMs can fit in visualizationDuration
242
- const numberOfSegments = Math.ceil(
243
- visualizationDuration / analysis.segmentDurationMs
244
- )
245
- // maxDataPoints should be the number of data points, not milliseconds
246
- const maxDataPoints = numberOfSegments
247
-
248
- logger?.debug(
249
- `[handleAudioAnalysis] Combined data points before trimming: numberOfSegments=${numberOfSegments} visualizationDuration=${visualizationDuration} combinedDataPointsLength=${combinedDataPoints.length} vs maxDataPoints=${maxDataPoints}`
250
- )
251
-
252
- // Trim data points to keep within the maximum number of data points
253
- if (combinedDataPoints.length > maxDataPoints) {
254
- combinedDataPoints.splice(
255
- 0,
256
- combinedDataPoints.length - maxDataPoints
257
- )
258
- }
259
-
260
- // Keep the full data points
261
- fullAnalysisRef.current = {
262
- ...fullAnalysisRef.current,
263
- dataPoints: fullCombinedDataPoints,
264
- }
265
- fullAnalysisRef.current.durationMs =
266
- fullCombinedDataPoints.length * analysis.segmentDurationMs
267
- savedAnalysisData.dataPoints = combinedDataPoints
268
- savedAnalysisData.bitDepth =
269
- analysis.bitDepth || savedAnalysisData.bitDepth
270
- savedAnalysisData.durationMs =
271
- combinedDataPoints.length * analysis.segmentDurationMs
272
-
273
- // Update amplitude range
274
- const newMin = Math.min(
275
- savedAnalysisData.amplitudeRange.min,
276
- analysis.amplitudeRange.min
277
- )
278
- const newMax = Math.max(
279
- savedAnalysisData.amplitudeRange.max,
280
- analysis.amplitudeRange.max
281
- )
282
-
283
- savedAnalysisData.amplitudeRange = {
284
- min: newMin,
285
- max: newMax,
286
- }
287
- fullAnalysisRef.current.amplitudeRange = {
288
- min: newMin,
289
- max: newMax,
290
- }
291
-
292
- logger?.debug(
293
- `[handleAudioAnalysis] Updated analysis data: durationMs=${savedAnalysisData.durationMs}`,
294
- { dataPoints: savedAnalysisData.dataPoints.length }
295
- )
296
-
297
- // Call the onAudioAnalysis callback if it exists in the recording config
298
- if (recordingConfigRef.current?.onAudioAnalysis) {
299
- recordingConfigRef.current
300
- .onAudioAnalysis(analysis)
301
- .catch((error) => {
302
- logger?.warn(`Error processing audio analysis:`, error)
303
- })
304
- }
305
-
306
- // Update the ref
307
- analysisRef.current = savedAnalysisData
308
-
309
- // Dispatch the updated analysis data to state to trigger re-render
310
- dispatch({
311
- type: 'UPDATE_ANALYSIS',
312
- payload: { ...savedAnalysisData },
313
- })
314
- },
315
- [dispatch]
316
- )
317
-
318
- const handleAudioEvent = useCallback(
319
- async (eventData: AudioEventPayload) => {
320
- const {
321
- fileUri,
322
- deltaSize,
323
- totalSize,
324
- lastEmittedSize,
325
- position,
326
- streamUuid,
327
- encoded,
328
- mimeType,
329
- buffer,
330
- compression,
331
- } = eventData
332
- logger?.debug(`[handleAudioEvent] Received audio event:`, {
333
- fileUri,
334
- deltaSize,
335
- totalSize,
336
- position,
337
- mimeType,
338
- lastEmittedSize,
339
- streamUuid,
340
- encodedLength: encoded?.length,
341
- compression,
342
- })
343
- if (deltaSize === 0) {
344
- // Ignore packet with no data
345
- return
346
- }
347
- try {
348
- // Coming from native ( ios / android ) otherwise buffer is set
349
- if (Platform.OS !== 'web') {
350
- // Read the audio file as a base64 string for comparison
351
- if (!encoded) {
352
- logger?.error(`Encoded audio data is missing`)
353
- throw new Error('Encoded audio data is missing')
354
- }
355
- onAudioStreamRef.current?.({
356
- data: encoded,
357
- position,
358
- fileUri,
359
- eventDataSize: deltaSize,
360
- totalSize,
361
- compression:
362
- compression && startResultRef.current?.compression
363
- ? {
364
- data: compression.data,
365
- size: compression.totalSize,
366
- mimeType:
367
- startResultRef.current.compression
368
- ?.mimeType,
369
- bitrate:
370
- startResultRef.current.compression
371
- ?.bitrate,
372
- format: startResultRef.current.compression
373
- ?.format,
374
- }
375
- : undefined,
376
- })
377
- } else if (buffer) {
378
- // Coming from web
379
- const webEvent: AudioDataEvent = {
380
- data: buffer,
381
- position,
382
- fileUri,
383
- eventDataSize: deltaSize,
384
- totalSize,
385
- compression:
386
- compression && startResultRef.current?.compression
387
- ? {
388
- data: compression.data,
389
- size: compression.totalSize,
390
- mimeType:
391
- startResultRef.current.compression
392
- ?.mimeType,
393
- bitrate:
394
- startResultRef.current.compression
395
- ?.bitrate,
396
- format: startResultRef.current.compression
397
- ?.format,
398
- }
399
- : undefined,
400
- }
401
- onAudioStreamRef.current?.(webEvent)
402
- logger?.debug(
403
- `[handleAudioEvent] Audio data sent to onAudioStream`,
404
- webEvent
405
- )
406
- }
407
- } catch (error) {
408
- logger?.error(`Error processing audio event:`, error)
409
- }
410
- },
411
- []
412
- )
413
-
414
- const checkStatus = useCallback(async () => {
415
- try {
416
- const status: AudioStreamStatus = ExpoAudioStream.status()
417
- logger?.debug(
418
- `Status: paused: ${status.isPaused} isRecording: ${status.isRecording} durationMs: ${status.durationMs} size: ${status.size}`,
419
- status.compression
420
- )
421
-
422
- // Only dispatch if values actually changed
423
- if (
424
- status.isRecording !== stateRef.current.isRecording ||
425
- status.isPaused !== stateRef.current.isPaused
426
- ) {
427
- stateRef.current.isRecording = status.isRecording
428
- stateRef.current.isPaused = status.isPaused
429
- dispatch({
430
- type: 'UPDATE_RECORDING_STATE',
431
- payload: {
432
- isRecording: status.isRecording,
433
- isPaused: status.isPaused,
434
- },
435
- })
436
- }
437
-
438
- if (
439
- status.durationMs !== stateRef.current.durationMs ||
440
- status.size !== stateRef.current.size
441
- ) {
442
- stateRef.current.durationMs = status.durationMs
443
- stateRef.current.size = status.size
444
- stateRef.current.compression = status.compression
445
- dispatch({
446
- type: 'UPDATE_STATUS',
447
- payload: {
448
- durationMs: status.durationMs,
449
- size: status.size,
450
- compression: status.compression,
451
- },
452
- })
453
- }
454
- } catch (error) {
455
- logger?.error(`Error getting status:`, error)
456
- }
457
- }, [ExpoAudioStream, logger]) // Only depend on ExpoAudioStream and logger
458
-
459
- // Update ref when state changes
460
- useEffect(() => {
461
- stateRef.current = {
462
- isRecording: state.isRecording,
463
- isPaused: state.isPaused,
464
- durationMs: state.durationMs,
465
- size: state.size,
466
- compression: state.compression,
467
- }
468
- }, [
469
- state.isRecording,
470
- state.isPaused,
471
- state.durationMs,
472
- state.size,
473
- state.compression,
474
- ])
475
-
476
- const startRecording = useCallback(
477
- async (recordingOptions: RecordingConfig) => {
478
- // Validate the encoding configuration
479
- const validationResult = validateRecordingConfig({
480
- encoding: recordingOptions.encoding,
481
- })
482
-
483
- // Log warnings if any
484
- if (validationResult.warnings.length > 0) {
485
- validationResult.warnings.forEach((warning) => {
486
- logger?.warn(warning)
487
- })
488
- }
489
-
490
- // Update recording options with validated values
491
- const validatedOptions = {
492
- ...recordingOptions,
493
- encoding: validationResult.encoding,
494
- }
495
-
496
- recordingConfigRef.current = validatedOptions
497
- logger?.debug(
498
- `start recording with validated config`,
499
- validatedOptions
500
- )
501
-
502
- analysisRef.current = { ...defaultAnalysis } // Reset analysis data
503
- fullAnalysisRef.current = { ...defaultAnalysis }
504
- const {
505
- onAudioStream,
506
- onRecordingInterrupted,
507
- onAudioAnalysis,
508
- ...options
509
- } = validatedOptions
510
- const { enableProcessing } = options
511
-
512
- const maxRecentDataDuration = 10000 // TODO compute maxRecentDataDuration based on screen dimensions
513
- if (typeof onAudioStream === 'function') {
514
- onAudioStreamRef.current = onAudioStream
515
- } else {
516
- logger?.warn(`onAudioStream is not a function`, onAudioStream)
517
- onAudioStreamRef.current = null
518
- }
519
- // Strip undefined values and functions that can't cross the native bridge
520
- const cleanOptions = cleanNativeOptions(options)
521
- const startResult: StartRecordingResult =
522
- await ExpoAudioStream.startRecording(cleanOptions)
523
- dispatch({ type: 'START' })
524
-
525
- startResultRef.current = startResult
526
-
527
- if (enableProcessing) {
528
- logger?.debug(`Enabling audio analysis listener`)
529
- const listener = addAudioAnalysisListener(
530
- async (analysisData) => {
531
- try {
532
- await handleAudioAnalysis({
533
- analysis: analysisData,
534
- visualizationDuration: maxRecentDataDuration,
535
- })
536
- } catch (error) {
537
- logger?.warn(
538
- `Error processing audio analysis:`,
539
- error
540
- )
541
- }
542
- }
543
- )
544
-
545
- analysisListenerRef.current = listener
546
- }
547
-
548
- return startResult
549
- },
550
- [handleAudioAnalysis, dispatch]
551
- )
552
-
553
- const prepareRecording = useCallback(
554
- async (recordingOptions: RecordingConfig) => {
555
- recordingConfigRef.current = recordingOptions
556
- logger?.debug(`preparing recording`, recordingOptions)
557
-
558
- analysisRef.current = { ...defaultAnalysis } // Reset analysis data
559
- fullAnalysisRef.current = { ...defaultAnalysis }
560
- const {
561
- onAudioStream,
562
- onRecordingInterrupted,
563
- onAudioAnalysis,
564
- ...options
565
- } = recordingOptions
566
-
567
- // Store onAudioStream for later use when recording starts
568
- if (typeof onAudioStream === 'function') {
569
- onAudioStreamRef.current = onAudioStream
570
- } else {
571
- logger?.warn(`onAudioStream is not a function`, onAudioStream)
572
- onAudioStreamRef.current = null
573
- }
574
-
575
- // Strip undefined values and functions that can't cross the native bridge
576
- const cleanOptions = cleanNativeOptions(options)
577
- // Call the native prepareRecording method
578
- await ExpoAudioStream.prepareRecording(cleanOptions)
579
- logger?.debug(`recording prepared successfully`)
580
- },
581
- []
582
- )
583
-
584
- const stopRecording = useCallback(async () => {
585
- logger?.debug(`stoping recording`)
586
-
587
- const stopResult: AudioRecording = await ExpoAudioStream.stopRecording()
588
- stopResult.analysisData = fullAnalysisRef.current
589
-
590
- if (analysisListenerRef.current) {
591
- analysisListenerRef.current.remove()
592
- analysisListenerRef.current = null
593
- }
594
- onAudioStreamRef.current = null
595
-
596
- // Note: We deliberately DON'T clear recordingConfigRef here to preserve interruption callback
597
- logger?.debug(`recording stopped`, stopResult)
598
- dispatch({ type: 'STOP' })
599
- return stopResult
600
- }, [dispatch])
601
-
602
- const pauseRecording = useCallback(async () => {
603
- logger?.debug(`pause recording`)
604
- const pauseResult = await ExpoAudioStream.pauseRecording()
605
- dispatch({ type: 'PAUSE' })
606
- return pauseResult
607
- }, [dispatch])
608
-
609
- const resumeRecording = useCallback(async () => {
610
- logger?.debug(`resume recording`)
611
- const resumeResult = await ExpoAudioStream.resumeRecording()
612
- dispatch({ type: 'RESUME' })
613
- return resumeResult
614
- }, [dispatch])
615
-
616
- useEffect(() => {
617
- let intervalId: ReturnType<typeof setInterval> | undefined
618
-
619
- if (state.isRecording || state.isPaused) {
620
- // Immediately check status when starting
621
- checkStatus()
622
-
623
- // Start interval
624
- intervalId = setInterval(checkStatus, 1000)
625
- }
626
-
627
- return () => {
628
- if (intervalId) {
629
- clearInterval(intervalId)
630
- intervalId = undefined
631
- }
632
- }
633
- }, [checkStatus, state.isRecording, state.isPaused])
634
-
635
- useEffect(() => {
636
- logger?.debug(`Registering audio event listener`)
637
- const subscribeAudio = addAudioEventListener(handleAudioEvent)
638
-
639
- logger?.debug(
640
- `Subscribed to audio event listener and analysis listener`,
641
- {
642
- subscribeAudio,
643
- }
644
- )
645
-
646
- return () => {
647
- logger?.debug(`Removing audio event listener`)
648
- subscribeAudio.remove()
649
- }
650
- }, [handleAudioEvent, handleAudioAnalysis])
651
-
652
- useEffect(() => {
653
- // Add event subscription for recording interruptions
654
- logger?.debug(
655
- `Setting up recording interruption listener [${instanceId}]`
656
- )
657
-
658
- const subscription = addRecordingInterruptionListener((event) => {
659
- logger?.debug(
660
- `[${instanceId}] Received recording interruption event:`,
661
- event
662
- )
663
-
664
- // Handle device disconnection for UI updates
665
- if (event.reason === 'deviceDisconnected') {
666
- logger?.debug(
667
- `[${instanceId}] Device disconnected - temporarily hiding last device from UI`
668
- )
669
-
670
- // Get current device list before the native layer updates
671
- const currentDevices = audioDeviceManager.getRawDevices()
672
-
673
- // Wait a moment for native layer to update, then compare
674
- setTimeout(async () => {
675
- try {
676
- // Get updated devices without notifying yet
677
- const updatedDevices =
678
- await audioDeviceManager.getAvailableDevices({
679
- refresh: true,
680
- })
681
-
682
- // Find missing devices by comparing lists
683
- const missingDevices = currentDevices.filter(
684
- (oldDevice) =>
685
- !updatedDevices.some(
686
- (newDevice) => newDevice.id === oldDevice.id
687
- )
688
- )
689
-
690
- if (missingDevices.length > 0) {
691
- // Mark all missing devices as disconnected (silently)
692
- missingDevices.forEach((missingDevice) => {
693
- logger?.debug(
694
- `[${instanceId}] Confirmed disconnected device: ${missingDevice.name} (${missingDevice.id})`
695
- )
696
- audioDeviceManager.markDeviceAsDisconnected(
697
- missingDevice.id,
698
- false
699
- )
700
- })
701
- }
702
-
703
- // Notify listeners once with the final filtered state
704
- audioDeviceManager.notifyListeners()
705
- } catch (error) {
706
- logger?.warn(
707
- `[${instanceId}] Error in delayed device disconnection handling:`,
708
- error
709
- )
710
- }
711
- }, 500) // 500ms delay to let native layer update
712
- } else if (event.reason === 'deviceConnected') {
713
- // Device reconnected - force refresh to show it immediately
714
- logger?.debug(
715
- `[${instanceId}] Device connected, forcing refresh`
716
- )
717
- audioDeviceManager.forceRefreshDevices()
718
- }
719
-
720
- // Check if we have a callback configured
721
- logger?.debug(
722
- `[${instanceId}] recordingConfigRef.current exists:`,
723
- !!recordingConfigRef.current
724
- )
725
-
726
- if (recordingConfigRef.current?.onRecordingInterrupted) {
727
- try {
728
- logger?.debug(
729
- `[${instanceId}] Calling recording interruption callback`
730
- )
731
- recordingConfigRef.current.onRecordingInterrupted(event)
732
- } catch (error) {
733
- logger?.error(
734
- `[${instanceId}] Error in recording interruption callback:`,
735
- error
736
- )
737
- }
738
- } else {
739
- logger?.debug(
740
- `[${instanceId}] No recording interruption callback configured`
741
- )
742
- }
743
- })
744
-
745
- return () => {
746
- logger?.debug(
747
- `[${instanceId}] Removing recording interruption listener`
748
- )
749
- subscription.remove()
750
- }
751
- }, [instanceId, logger]) // Include instanceId and logger in dependencies
752
-
753
- return {
754
- prepareRecording,
755
- startRecording,
756
- stopRecording,
757
- pauseRecording,
758
- resumeRecording,
759
- isPaused: state.isPaused,
760
- isRecording: state.isRecording,
761
- durationMs: state.durationMs,
762
- size: state.size,
763
- compression: state.compression,
764
- analysisData: state.analysisData,
765
- }
766
- }