@siteed/expo-audio-stream 1.1.9 → 1.1.11
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/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -2
- package/android/build/.transforms/871e87a512fbb418f6a6523c40225bac/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioProcessor$extractMFCC$powerSpectrum$2.dex +0 -0
- package/android/build/.transforms/99bb16aff51bfafd6c73c1b96e3e0dcf/transformed/debug/debug_dex/net/siteed/audiostream/AudioProcessor.dex +0 -0
- package/android/build/.transforms/99bb16aff51bfafd6c73c1b96e3e0dcf/transformed/debug/debug_dex/net/siteed/audiostream/AudioRecorderManager.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$10.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$12.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$13.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$15.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$16.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$18.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$7.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$9.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$4.dex +0 -0
- package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule.dex +0 -0
- package/android/build/.transforms/a758925c83c348fb1544431cf45e6a05/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/AudioProcessor$extractMFCC$powerSpectrum$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/AudioProcessor.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/AudioRecorderManager.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$10.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$12.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$13.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$15.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$16.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$18.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$7.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$9.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$4.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/net/siteed/audiostream/ExpoAudioStreamModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +1 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/AudioProcessor$extractMFCC$powerSpectrum$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/AudioProcessor.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/AudioRecorderManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$10.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$12.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$13.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$15.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$16.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$18.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$7.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$9.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$4.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule.class +0 -0
- package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +14 -3
- package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +19 -1
- package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +1 -0
- package/build/WebRecorder.web.d.ts.map +1 -1
- package/build/WebRecorder.web.js +13 -1
- package/build/WebRecorder.web.js.map +1 -1
- package/package.json +7 -6
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/publish.sh +1 -2
- package/src/WebRecorder.web.ts +17 -1
- package/android/.gradle/8.1.1/checksums/checksums.lock +0 -0
- package/android/.gradle/8.1.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.1.1/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.1.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.1.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.1.1/gc.properties +0 -0
- package/android/build/.transforms/10769ccaccd8850af4ffc5504c4368cb/transformed/debug/debug_dex/net/siteed/audiostream/AudioProcessor.dex +0 -0
- package/android/build/.transforms/10769ccaccd8850af4ffc5504c4368cb/transformed/debug/debug_dex/net/siteed/audiostream/AudioRecorderManager.dex +0 -0
- package/android/build/.transforms/7bc0cb35da9eb644120553a3af66f984/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/949f6bd23bdf38f67d1eb7de8f618950/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +0 -1
- /package/android/build/.transforms/{7bc0cb35da9eb644120553a3af66f984 → 871e87a512fbb418f6a6523c40225bac}/results.bin +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/results.bin +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioAnalysisData$AmplitudeRange.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioAnalysisData$SpeakerChange.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioAnalysisData.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioDataEncoder.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioFileHandler.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioFormatUtils.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioProcessor$AudioData.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/AudioProcessor$Companion.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/BuildConfig.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/Constants.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/DataPoint.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/EventSender.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$1.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$11.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$14.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$17.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$2.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$3.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$4.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$5.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$6.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunction$8.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$1.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$2.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$AsyncFunctionWithPromise$3.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$FunctionWithoutArgs$1.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/ExpoAudioStreamModule$definition$lambda$14$$inlined$FunctionWithoutArgs$2.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/FFT.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/Features.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/PermissionUtils.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/debug_dex/net/siteed/audiostream/RecordingConfig.dex +0 -0
- /package/android/build/.transforms/{10769ccaccd8850af4ffc5504c4368cb → 99bb16aff51bfafd6c73c1b96e3e0dcf}/transformed/debug/desugar_graph.bin +0 -0
- /package/android/build/.transforms/{949f6bd23bdf38f67d1eb7de8f618950 → a758925c83c348fb1544431cf45e6a05}/results.bin +0 -0
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Tue
|
|
2
|
-
gradle.version=8.
|
|
1
|
+
#Tue Sep 17 06:54:38 HKT 2024
|
|
2
|
+
gradle.version=8.9
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Wed Oct 16 15:11:22 HKT 2024
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
19
|
|
2
2
|
0
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len
CHANGED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values
CHANGED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at
CHANGED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
��P�xȍ
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/AudioRecorderManager.class
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/net/siteed/audiostream/ExpoAudioStreamModule.class
CHANGED
|
Binary file
|
|
@@ -25,6 +25,10 @@ class AudioProcessor(private val filesDir: File) {
|
|
|
25
25
|
// Add a counter for unique IDs
|
|
26
26
|
private var uniqueIdCounter = 0L
|
|
27
27
|
|
|
28
|
+
private var cumulativeMinAmplitude = Float.MAX_VALUE
|
|
29
|
+
private var cumulativeMaxAmplitude = Float.NEGATIVE_INFINITY
|
|
30
|
+
|
|
31
|
+
|
|
28
32
|
fun loadAudioFile(originalFileUri: String, skipWavHeader: Boolean = false): AudioData? {
|
|
29
33
|
// Remove the file:// prefix if present
|
|
30
34
|
val fileUri = originalFileUri.removePrefix("file://")
|
|
@@ -165,10 +169,9 @@ class AudioProcessor(private val filesDir: File) {
|
|
|
165
169
|
|
|
166
170
|
val dataPoints = mutableListOf<DataPoint>()
|
|
167
171
|
var minAmplitude = Float.MAX_VALUE
|
|
168
|
-
var maxAmplitude = Float.
|
|
172
|
+
var maxAmplitude = Float.NEGATIVE_INFINITY
|
|
169
173
|
val durationMs = (segmentDurationSeconds * 1000).toInt()
|
|
170
174
|
|
|
171
|
-
// Measure the time taken for audio processing
|
|
172
175
|
// Measure the time taken for audio processing
|
|
173
176
|
val extractionTimeMs = measureTimeMillis {
|
|
174
177
|
var currentPosition = 0 // Track the current byte position
|
|
@@ -205,6 +208,10 @@ class AudioProcessor(private val filesDir: File) {
|
|
|
205
208
|
val startPosition = start * bytesPerSample * config.channels
|
|
206
209
|
val endPosition = end * bytesPerSample * config.channels
|
|
207
210
|
|
|
211
|
+
// Update cumulative amplitude range
|
|
212
|
+
cumulativeMinAmplitude = min(cumulativeMinAmplitude, localMinAmplitude)
|
|
213
|
+
cumulativeMaxAmplitude = max(cumulativeMaxAmplitude, localMaxAmplitude)
|
|
214
|
+
|
|
208
215
|
val dataPoint = DataPoint(
|
|
209
216
|
id = uniqueIdCounter++, // Assign unique ID and increment the counter
|
|
210
217
|
amplitude = if (algorithm == "peak") localMaxAmplitude else rms,
|
|
@@ -232,13 +239,17 @@ class AudioProcessor(private val filesDir: File) {
|
|
|
232
239
|
sampleRate = config.sampleRate,
|
|
233
240
|
samples = totalSamples,
|
|
234
241
|
dataPoints = dataPoints,
|
|
235
|
-
amplitudeRange = AudioAnalysisData.AmplitudeRange(
|
|
242
|
+
amplitudeRange = AudioAnalysisData.AmplitudeRange(cumulativeMinAmplitude, cumulativeMaxAmplitude),
|
|
236
243
|
speakerChanges = emptyList(),
|
|
237
244
|
extractionTimeMs = extractionTimeMs.toFloat() // Return the measured extraction time
|
|
238
245
|
)
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
|
|
249
|
+
fun resetCumulativeAmplitudeRange() {
|
|
250
|
+
cumulativeMinAmplitude = Float.MAX_VALUE
|
|
251
|
+
cumulativeMaxAmplitude = Float.MIN_VALUE
|
|
252
|
+
}
|
|
242
253
|
|
|
243
254
|
/**
|
|
244
255
|
* Converts the audio data to a float array.
|
|
@@ -50,6 +50,7 @@ class AudioRecorderManager(
|
|
|
50
50
|
private var mimeType = "audio/wav"
|
|
51
51
|
private var audioFormat: Int = AudioFormat.ENCODING_PCM_16BIT
|
|
52
52
|
private var audioProcessor: AudioProcessor = AudioProcessor(filesDir)
|
|
53
|
+
private var isFirstChunk = true
|
|
53
54
|
|
|
54
55
|
@RequiresApi(Build.VERSION_CODES.R)
|
|
55
56
|
fun startRecording(options: Map<String, Any?>, promise: Promise) {
|
|
@@ -226,9 +227,13 @@ class AudioRecorderManager(
|
|
|
226
227
|
return
|
|
227
228
|
}
|
|
228
229
|
|
|
230
|
+
audioProcessor.resetCumulativeAmplitudeRange()
|
|
231
|
+
|
|
229
232
|
audioRecord?.startRecording()
|
|
230
233
|
isPaused.set(false)
|
|
231
234
|
isRecording.set(true)
|
|
235
|
+
isFirstChunk = true // Reset the flag when starting a new recording
|
|
236
|
+
|
|
232
237
|
|
|
233
238
|
if (!isPaused.get()) {
|
|
234
239
|
recordingStartTime =
|
|
@@ -309,6 +314,7 @@ class AudioRecorderManager(
|
|
|
309
314
|
Log.d(Constants.TAG, "Stopping AudioRecord");
|
|
310
315
|
audioRecord!!.stop()
|
|
311
316
|
}
|
|
317
|
+
|
|
312
318
|
} catch (e: IllegalStateException) {
|
|
313
319
|
Log.e(Constants.TAG, "Error reading from AudioRecord", e);
|
|
314
320
|
} finally {
|
|
@@ -316,6 +322,8 @@ class AudioRecorderManager(
|
|
|
316
322
|
}
|
|
317
323
|
|
|
318
324
|
try {
|
|
325
|
+
audioProcessor.resetCumulativeAmplitudeRange()
|
|
326
|
+
|
|
319
327
|
val fileSize = audioFile?.length() ?: 0
|
|
320
328
|
val dataFileSize = fileSize - 44 // Subtract header size
|
|
321
329
|
val byteRate = recordingConfig.sampleRate * recordingConfig.channels * when (recordingConfig.encoding) {
|
|
@@ -538,7 +546,14 @@ class AudioRecorderManager(
|
|
|
538
546
|
}
|
|
539
547
|
|
|
540
548
|
private fun processAudioData(audioData: ByteArray) {
|
|
541
|
-
|
|
549
|
+
// Skip the WAV header only for the first chunk
|
|
550
|
+
val dataToProcess = if (isFirstChunk && audioData.size > Constants.WAV_HEADER_SIZE) {
|
|
551
|
+
audioData.copyOfRange(Constants.WAV_HEADER_SIZE, audioData.size)
|
|
552
|
+
} else {
|
|
553
|
+
audioData
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
val audioAnalysisData = audioProcessor.processAudioData(dataToProcess, recordingConfig)
|
|
542
557
|
val analysisBundle = audioAnalysisData.toBundle()
|
|
543
558
|
|
|
544
559
|
mainHandler.post {
|
|
@@ -550,6 +565,9 @@ class AudioRecorderManager(
|
|
|
550
565
|
Log.e(Constants.TAG, "Failed to send audio analysis event", e)
|
|
551
566
|
}
|
|
552
567
|
}
|
|
568
|
+
|
|
569
|
+
// Reset isFirstChunk after processing
|
|
570
|
+
isFirstChunk = false
|
|
553
571
|
}
|
|
554
572
|
|
|
555
573
|
|
|
@@ -80,6 +80,7 @@ class ExpoAudioStreamModule() : Module(), EventSender {
|
|
|
80
80
|
)
|
|
81
81
|
|
|
82
82
|
Log.d("ExpoAudioStreamModule", "extractAudioAnalysis: $recordingConfig")
|
|
83
|
+
audioProcessor.resetCumulativeAmplitudeRange()
|
|
83
84
|
|
|
84
85
|
val analysisData = audioProcessor.processAudioData(audioData.data, recordingConfig)
|
|
85
86
|
promise.resolve(analysisData.toDictionary())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebRecorder.web.d.ts","sourceRoot":"","sources":["../src/WebRecorder.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebRecorder.web.d.ts","sourceRoot":"","sources":["../src/WebRecorder.web.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EACH,yBAAyB,EACzB,sBAAsB,EACzB,MAAM,uBAAuB,CAAA;AAgB9B,UAAU,kBAAkB;IACxB,IAAI,EAAE;QACF,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,aAAa,CAAA;KACxB,CAAA;CACJ;AAWD,qBAAa,WAAW;IACpB,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,sBAAsB,CAAC,CAAQ;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,sBAAsB,CAAwB;IACtD,OAAO,CAAC,yBAAyB,CAA2B;IAC5D,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,WAAW,CAAY;gBAEnB,EACR,YAAY,EACZ,MAAM,EACN,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,yBAAyB,GAC5B,EAAE;QACC,YAAY,EAAE,YAAY,CAAA;QAC1B,MAAM,EAAE,0BAA0B,CAAA;QAClC,eAAe,EAAE,eAAe,CAAA;QAChC,eAAe,EAAE,MAAM,CAAA;QACvB,sBAAsB,EAAE,sBAAsB,CAAA;QAC9C,yBAAyB,EAAE,yBAAyB,CAAA;KACvD;IAoDK,IAAI;IAyHV,0BAA0B,CAAC,mBAAmB,CAAC,EAAE,MAAM;IA0BvD,kBAAkB;IAqBlB,iBAAiB,CAAC,KAAK,EAAE,UAAU;IAInC,6BAA6B,CAAC,KAAK,EAAE,kBAAkB;IAgCvD,KAAK;IAML,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAmF7B,KAAK;IAML,qBAAqB;IAMf,gBAAgB,CAAC,EACnB,YAAY,GACf,EAAE;QACC,YAAY,EAAE,WAAW,CAAA;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;KACpB;IAsBD,OAAO,CAAC,uBAAuB;IAoB/B,MAAM;CAKT"}
|
package/build/WebRecorder.web.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getLogger } from './logger';
|
|
2
|
+
import { convertPCMToFloat32 } from './utils/convertPCMToFloat32';
|
|
2
3
|
import { encodingToBitDepth } from './utils/encodingToBitDepth';
|
|
3
4
|
import { writeWavHeader } from './utils/writeWavHeader';
|
|
4
5
|
import { InlineFeaturesExtractor } from './workers/InlineFeaturesExtractor.web';
|
|
@@ -259,7 +260,18 @@ export class WebRecorder {
|
|
|
259
260
|
logger.debug(`recordedData.length=${rawPCMDataFull.byteLength} vs transmittedData.length=${this.audioBufferSize}`);
|
|
260
261
|
// Remove the event listener after receiving the final data
|
|
261
262
|
this.audioWorkletNode.port.removeEventListener('message', onMessage);
|
|
262
|
-
|
|
263
|
+
// Add wav header to the raw PCM data
|
|
264
|
+
const wavHeaderBuffer = writeWavHeader({
|
|
265
|
+
buffer: rawPCMDataFull.buffer,
|
|
266
|
+
sampleRate: this.audioContext.sampleRate,
|
|
267
|
+
numChannels: this.numberOfChannels,
|
|
268
|
+
bitDepth: this.exportBitDepth,
|
|
269
|
+
});
|
|
270
|
+
const convertedPCM = await convertPCMToFloat32({
|
|
271
|
+
buffer: wavHeaderBuffer,
|
|
272
|
+
bitDepth: this.exportBitDepth,
|
|
273
|
+
});
|
|
274
|
+
resolve(convertedPCM.pcmValues); // Resolve the promise with the collected buffers
|
|
263
275
|
}
|
|
264
276
|
};
|
|
265
277
|
this.audioWorkletNode.port.addEventListener('message', onMessage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebRecorder.web.js","sourceRoot":"","sources":["../src/WebRecorder.web.ts"],"names":[],"mappings":"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","sourcesContent":["// src/WebRecorder.ts\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport { RecordingConfig } from './ExpoAudioStream.types'\nimport {\n EmitAudioAnalysisFunction,\n EmitAudioEventFunction,\n} from './ExpoAudioStream.web'\nimport { getLogger } from './logger'\nimport { encodingToBitDepth } from './utils/encodingToBitDepth'\nimport { writeWavHeader } from './utils/writeWavHeader'\nimport { InlineFeaturesExtractor } from './workers/InlineFeaturesExtractor.web'\nimport { InlineAudioWebWorker } from './workers/inlineAudioWebWorker.web'\n\ninterface AudioWorkletEvent {\n data: {\n command: string\n recordedData?: Float32Array\n sampleRate?: number\n }\n}\n\ninterface AudioFeaturesEvent {\n data: {\n command: string\n result: AudioAnalysis\n }\n}\n\nconst DEFAULT_WEB_BITDEPTH = 32\nconst DEFAULT_WEB_POINTS_PER_SECOND = 10\nconst DEFAULT_WEB_INTERVAL = 500\nconst DEFAULT_WEB_NUMBER_OF_CHANNELS = 1\nconst DEFAULT_ALGORITHM = 'rms'\n\nconst TAG = 'WebRecorder'\nconst logger = getLogger(TAG)\n\nexport class WebRecorder {\n private audioContext: AudioContext\n private audioWorkletNode!: AudioWorkletNode\n private featureExtractorWorker?: Worker\n private source: MediaStreamAudioSourceNode\n private audioWorkletUrl: string\n private emitAudioEventCallback: EmitAudioEventFunction\n private emitAudioAnalysisCallback: EmitAudioAnalysisFunction\n private config: RecordingConfig\n private position: number // Track the cumulative position\n private numberOfChannels: number // Number of audio channels\n private bitDepth: number // Bit depth of the audio\n private exportBitDepth: number // Bit depth of the audio\n private audioBuffer: Float32Array // Single buffer to store the audio data\n private audioBufferSize: number // Keep track of the buffer size\n private audioAnalysisData: AudioAnalysis // Keep updating the full audio analysis data with latest events\n private packetCount: number = 0\n\n constructor({\n audioContext,\n source,\n recordingConfig,\n audioWorkletUrl,\n emitAudioEventCallback,\n emitAudioAnalysisCallback,\n }: {\n audioContext: AudioContext\n source: MediaStreamAudioSourceNode\n recordingConfig: RecordingConfig\n audioWorkletUrl: string\n emitAudioEventCallback: EmitAudioEventFunction\n emitAudioAnalysisCallback: EmitAudioAnalysisFunction\n }) {\n this.audioContext = audioContext\n this.source = source\n this.audioWorkletUrl = audioWorkletUrl\n this.emitAudioEventCallback = emitAudioEventCallback\n this.emitAudioAnalysisCallback = emitAudioAnalysisCallback\n this.config = recordingConfig\n this.position = 0\n\n const audioContextFormat = this.checkAudioContextFormat({\n sampleRate: this.audioContext.sampleRate,\n })\n logger.debug('Initialized WebRecorder with config:', {\n sampleRate: audioContextFormat.sampleRate,\n bitDepth: audioContextFormat.bitDepth,\n numberOfChannels: audioContextFormat.numberOfChannels,\n })\n\n this.bitDepth = audioContextFormat.bitDepth\n this.numberOfChannels =\n audioContextFormat.numberOfChannels ||\n DEFAULT_WEB_NUMBER_OF_CHANNELS // Default to 1 if not available\n this.exportBitDepth =\n encodingToBitDepth({\n encoding: recordingConfig.encoding ?? 'pcm_32bit',\n }) ||\n audioContextFormat.bitDepth ||\n DEFAULT_WEB_BITDEPTH\n\n // Initialize the audio buffer separately\n this.audioBuffer = new Float32Array(0)\n this.audioBufferSize = 0\n\n this.audioAnalysisData = {\n amplitudeRange: { min: 0, max: 0 },\n dataPoints: [],\n durationMs: 0,\n samples: 0,\n amplitudeAlgorithm: recordingConfig.algorithm || DEFAULT_ALGORITHM,\n bitDepth: this.bitDepth,\n numberOfChannels: this.numberOfChannels,\n sampleRate: this.config.sampleRate || this.audioContext.sampleRate,\n pointsPerSecond:\n this.config.pointsPerSecond || DEFAULT_WEB_POINTS_PER_SECOND,\n speakerChanges: [],\n }\n\n if (recordingConfig.enableProcessing) {\n this.initFeatureExtractorWorker()\n }\n }\n\n async init() {\n try {\n if (!this.audioWorkletUrl) {\n const blob = new Blob([InlineAudioWebWorker], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n await this.audioContext.audioWorklet.addModule(url)\n } else {\n await this.audioContext.audioWorklet.addModule(\n this.audioWorkletUrl\n )\n }\n this.audioWorkletNode = new AudioWorkletNode(\n this.audioContext,\n 'recorder-processor'\n )\n\n this.audioWorkletNode.port.onmessage = async (\n event: AudioWorkletEvent\n ) => {\n const command = event.data.command\n if (command !== 'newData') {\n return\n }\n const pcmBufferFloat = event.data.recordedData\n\n if (!pcmBufferFloat) {\n logger.warn('Received empty audio buffer', event)\n return\n }\n\n // Handle the audio blob (e.g., send it to the server or process it further)\n logger.debug(\n `Received audio blob from processor len:${pcmBufferFloat?.length}`,\n event\n )\n // Concatenate the incoming Float32Array to the existing buffer\n const newBuffer = new Float32Array(\n this.audioBufferSize + pcmBufferFloat.length\n )\n newBuffer.set(this.audioBuffer, 0)\n newBuffer.set(pcmBufferFloat, this.audioBufferSize)\n this.audioBuffer = newBuffer\n this.audioBufferSize += pcmBufferFloat.length\n\n const sampleRate =\n event.data.sampleRate ?? this.audioContext.sampleRate\n const duration = pcmBufferFloat.length / sampleRate // Calculate duration of the current buffer\n\n let data: Float32Array\n if (this.packetCount === 0) {\n // Initialize WAV header\n const wavHeaderBuffer = writeWavHeader({\n sampleRate: this.audioContext.sampleRate,\n numChannels: this.numberOfChannels,\n bitDepth: this.exportBitDepth,\n })\n\n // For the first packet, combine WAV header with audio data\n const headerFloatArray = new Float32Array(wavHeaderBuffer)\n data = new Float32Array(\n headerFloatArray.length + this.audioBuffer.length\n )\n data.set(headerFloatArray, 0)\n data.set(this.audioBuffer, headerFloatArray.length)\n } else {\n // For subsequent packets, just send the new audio data\n data = pcmBufferFloat\n }\n\n // Track the number of packets\n this.packetCount += 1\n\n this.emitAudioEventCallback({\n data,\n position: this.position,\n })\n this.position += duration // Update position\n\n this.featureExtractorWorker?.postMessage(\n {\n command: 'process',\n channelData: pcmBufferFloat,\n sampleRate,\n pointsPerSecond:\n this.config.pointsPerSecond ||\n DEFAULT_WEB_POINTS_PER_SECOND,\n algorithm: this.config.algorithm || 'rms',\n bitDepth: this.bitDepth,\n fullAudioDurationMs: this.position * 1000,\n numberOfChannels: this.numberOfChannels,\n features: this.config.features,\n },\n []\n )\n }\n\n logger.debug(\n `WebRecorder initialized -- recordSampleRate=${this.audioContext.sampleRate}`,\n this.config\n )\n this.audioWorkletNode.port.postMessage({\n command: 'init',\n recordSampleRate: this.audioContext.sampleRate, // Pass the original sample rate\n exportSampleRate:\n this.config.sampleRate ?? this.audioContext.sampleRate,\n bitDepth: this.bitDepth,\n exportBitDepth: this.exportBitDepth,\n channels: this.numberOfChannels,\n interval: this.config.interval ?? DEFAULT_WEB_INTERVAL,\n })\n\n // Connect the source to the AudioWorkletNode and start recording\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n } catch (error) {\n console.error(`[${TAG}] Failed to initialize WebRecorder`, error)\n }\n }\n\n initFeatureExtractorWorker(featuresExtratorUrl?: string) {\n try {\n if (featuresExtratorUrl) {\n // Initialize the feature extractor worker\n //TODO: create audio feature extractor from a Blob instead of url since we cannot include the url directly in the library\n // We keep the url during dev and use the blob in production.\n this.featureExtractorWorker = new Worker(\n new URL(featuresExtratorUrl, window.location.href)\n )\n this.featureExtractorWorker.onmessage =\n this.handleFeatureExtractorMessage.bind(this)\n this.featureExtractorWorker.onerror =\n this.handleWorkerError.bind(this)\n } else {\n // Fallback to the inline worker if the URL is not provided\n this.initFallbackWorker()\n }\n } catch (error) {\n console.error(\n `[${TAG}] Failed to initialize feature extractor worker`,\n error\n )\n this.initFallbackWorker()\n }\n }\n\n initFallbackWorker() {\n try {\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n this.featureExtractorWorker = new Worker(url)\n this.featureExtractorWorker.onmessage =\n this.handleFeatureExtractorMessage.bind(this)\n this.featureExtractorWorker.onerror = (error) => {\n console.error(`[${TAG}] Default Inline worker failed`, error)\n }\n logger.log('Inline worker initialized successfully')\n } catch (error) {\n console.error(\n `[${TAG}] Failed to initialize Inline Feature Extractor worker`,\n error\n )\n }\n }\n\n handleWorkerError(error: ErrorEvent) {\n console.error(`[${TAG}] Feature extractor worker error:`, error)\n }\n\n handleFeatureExtractorMessage(event: AudioFeaturesEvent) {\n if (event.data.command === 'features') {\n const segmentResult = event.data.result\n\n // Merge the segment result with the full audio analysis data\n this.audioAnalysisData.dataPoints.push(...segmentResult.dataPoints)\n this.audioAnalysisData.speakerChanges?.push(\n ...(segmentResult.speakerChanges ?? [])\n )\n this.audioAnalysisData.durationMs = segmentResult.durationMs\n if (segmentResult.amplitudeRange) {\n this.audioAnalysisData.amplitudeRange = {\n min: Math.min(\n this.audioAnalysisData.amplitudeRange.min,\n segmentResult.amplitudeRange.min\n ),\n max: Math.max(\n this.audioAnalysisData.amplitudeRange.max,\n segmentResult.amplitudeRange.max\n ),\n }\n }\n // Handle the extracted features (e.g., emit an event or log them)\n logger.debug('features event segmentResult', segmentResult)\n logger.debug(\n 'features event audioAnalysisData',\n this.audioAnalysisData\n )\n this.emitAudioAnalysisCallback(segmentResult)\n }\n }\n\n start() {\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n this.packetCount = 0\n }\n\n stop(): Promise<Float32Array> {\n return new Promise((resolve, reject) => {\n try {\n if (this.audioWorkletNode) {\n // this.source.disconnect(this.audioWorkletNode);\n // this.audioWorkletNode.disconnect(this.audioContext.destination);\n this.audioWorkletNode.port.postMessage({ command: 'stop' })\n\n // Set a timeout to reject the promise if no message is received within 5 seconds\n const timeout = setTimeout(() => {\n this.audioWorkletNode.port.removeEventListener(\n 'message',\n onMessage\n )\n reject(\n new Error(\n \"Timeout error, audioWorkletNode didn't complete.\"\n )\n )\n }, 5000)\n\n // Listen for the recordedData message to confirm stopping\n const onMessage = async (event: AudioWorkletEvent) => {\n const command = event.data.command\n if (command === 'recordedData') {\n clearTimeout(timeout) // Clear the timeout\n\n const rawPCMDataFull =\n event.data.recordedData?.slice(0)\n\n if (!rawPCMDataFull) {\n reject(new Error('Failed to get recorded data'))\n return\n }\n\n // Compute duration of the recorded data\n const duration =\n rawPCMDataFull.byteLength /\n (this.audioContext.sampleRate *\n (this.exportBitDepth /\n this.numberOfChannels))\n logger.debug(\n `Received recorded data -- Duration: ${duration} vs ${rawPCMDataFull.byteLength / this.audioContext.sampleRate} seconds`\n )\n logger.debug(\n `recordedData.length=${rawPCMDataFull.byteLength} vs transmittedData.length=${this.audioBufferSize}`\n )\n\n // Remove the event listener after receiving the final data\n this.audioWorkletNode.port.removeEventListener(\n 'message',\n onMessage\n )\n resolve(this.audioBuffer) // Resolve the promise with the collected buffers\n }\n }\n this.audioWorkletNode.port.addEventListener(\n 'message',\n onMessage\n )\n }\n\n // Stop all media stream tracks to stop the browser recording\n this.stopMediaStreamTracks()\n } catch (error) {\n reject(error)\n }\n })\n }\n\n pause() {\n this.source.disconnect(this.audioWorkletNode) // Disconnect the source from the AudioWorkletNode\n this.audioWorkletNode.disconnect(this.audioContext.destination) // Disconnect the AudioWorkletNode from the destination\n this.audioWorkletNode.port.postMessage({ command: 'pause' })\n }\n\n stopMediaStreamTracks() {\n // Stop all audio tracks to stop the recording icon\n const tracks = this.source.mediaStream.getTracks()\n tracks.forEach((track) => track.stop())\n }\n\n async playRecordedData({\n recordedData,\n }: {\n recordedData: ArrayBuffer\n mimeType?: string\n }) {\n try {\n const blob = new Blob([recordedData])\n const url = URL.createObjectURL(blob)\n const response = await fetch(url)\n const arrayBuffer = await response.arrayBuffer()\n\n // Decode the audio data\n const audioBuffer =\n await this.audioContext.decodeAudioData(arrayBuffer)\n\n // Create a buffer source node and play the audio\n const bufferSource = this.audioContext.createBufferSource()\n bufferSource.buffer = audioBuffer\n bufferSource.connect(this.audioContext.destination)\n bufferSource.start()\n logger.debug('Playing recorded data', recordedData)\n } catch (error) {\n console.error(`[${TAG}] Failed to play recorded data:`, error)\n }\n }\n\n private checkAudioContextFormat({ sampleRate }: { sampleRate: number }) {\n // Create a silent AudioBuffer\n const frameCount = sampleRate * 1.0 // 1 second buffer\n const audioBuffer = this.audioContext.createBuffer(\n 1,\n frameCount,\n sampleRate\n )\n\n // Check the format\n const channelData = audioBuffer.getChannelData(0)\n const bitDepth = channelData.BYTES_PER_ELEMENT * 8 // 4 bytes per element means 32-bit\n\n return {\n sampleRate: audioBuffer.sampleRate,\n bitDepth,\n numberOfChannels: audioBuffer.numberOfChannels,\n }\n }\n\n resume() {\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n this.audioWorkletNode.port.postMessage({ command: 'resume' })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WebRecorder.web.js","sourceRoot":"","sources":["../src/WebRecorder.web.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAiBzE,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAC/B,MAAM,6BAA6B,GAAG,EAAE,CAAA;AACxC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAChC,MAAM,8BAA8B,GAAG,CAAC,CAAA;AACxC,MAAM,iBAAiB,GAAG,KAAK,CAAA;AAE/B,MAAM,GAAG,GAAG,aAAa,CAAA;AACzB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;AAE7B,MAAM,OAAO,WAAW;IACZ,YAAY,CAAc;IAC1B,gBAAgB,CAAmB;IACnC,sBAAsB,CAAS;IAC/B,MAAM,CAA4B;IAClC,eAAe,CAAQ;IACvB,sBAAsB,CAAwB;IAC9C,yBAAyB,CAA2B;IACpD,MAAM,CAAiB;IACvB,QAAQ,CAAQ,CAAC,gCAAgC;IACjD,gBAAgB,CAAQ,CAAC,2BAA2B;IACpD,QAAQ,CAAQ,CAAC,yBAAyB;IAC1C,cAAc,CAAQ,CAAC,yBAAyB;IAChD,WAAW,CAAc,CAAC,wCAAwC;IAClE,eAAe,CAAQ,CAAC,gCAAgC;IACxD,iBAAiB,CAAe,CAAC,gEAAgE;IACjG,WAAW,GAAW,CAAC,CAAA;IAE/B,YAAY,EACR,YAAY,EACZ,MAAM,EACN,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,yBAAyB,GAQ5B;QACG,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAA;QACpD,IAAI,CAAC,yBAAyB,GAAG,yBAAyB,CAAA;QAC1D,IAAI,CAAC,MAAM,GAAG,eAAe,CAAA;QAC7B,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;QAEjB,MAAM,kBAAkB,GAAG,IAAI,CAAC,uBAAuB,CAAC;YACpD,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU;SAC3C,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE;YACjD,UAAU,EAAE,kBAAkB,CAAC,UAAU;YACzC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ;YACrC,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB;SACxD,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,CAAA;QAC3C,IAAI,CAAC,gBAAgB;YACjB,kBAAkB,CAAC,gBAAgB;gBACnC,8BAA8B,CAAA,CAAC,gCAAgC;QACnE,IAAI,CAAC,cAAc;YACf,kBAAkB,CAAC;gBACf,QAAQ,EAAE,eAAe,CAAC,QAAQ,IAAI,WAAW;aACpD,CAAC;gBACF,kBAAkB,CAAC,QAAQ;gBAC3B,oBAAoB,CAAA;QAExB,yCAAyC;QACzC,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAA;QACtC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;QAExB,IAAI,CAAC,iBAAiB,GAAG;YACrB,cAAc,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;YAClC,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,eAAe,CAAC,SAAS,IAAI,iBAAiB;YAClE,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU;YAClE,eAAe,EACX,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,6BAA6B;YAChE,cAAc,EAAE,EAAE;SACrB,CAAA;QAED,IAAI,eAAe,CAAC,gBAAgB,EAAE,CAAC;YACnC,IAAI,CAAC,0BAA0B,EAAE,CAAA;QACrC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACN,IAAI,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,oBAAoB,CAAC,EAAE;oBAC1C,IAAI,EAAE,wBAAwB;iBACjC,CAAC,CAAA;gBACF,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;gBACrC,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YACvD,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,CAC1C,IAAI,CAAC,eAAe,CACvB,CAAA;YACL,CAAC;YACD,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CACxC,IAAI,CAAC,YAAY,EACjB,oBAAoB,CACvB,CAAA;YAED,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,EACxC,KAAwB,EAC1B,EAAE;gBACA,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAA;gBAClC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBACxB,OAAM;gBACV,CAAC;gBACD,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAA;gBAE9C,IAAI,CAAC,cAAc,EAAE,CAAC;oBAClB,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAA;oBACjD,OAAM;gBACV,CAAC;gBAED,4EAA4E;gBAC5E,MAAM,CAAC,KAAK,CACR,0CAA0C,cAAc,EAAE,MAAM,EAAE,EAClE,KAAK,CACR,CAAA;gBACD,+DAA+D;gBAC/D,MAAM,SAAS,GAAG,IAAI,YAAY,CAC9B,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC,MAAM,CAC/C,CAAA;gBACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;gBAClC,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;gBACnD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAA;gBAC5B,IAAI,CAAC,eAAe,IAAI,cAAc,CAAC,MAAM,CAAA;gBAE7C,MAAM,UAAU,GACZ,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAA;gBACzD,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,GAAG,UAAU,CAAA,CAAC,2CAA2C;gBAE/F,IAAI,IAAkB,CAAA;gBACtB,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;oBACzB,wBAAwB;oBACxB,MAAM,eAAe,GAAG,cAAc,CAAC;wBACnC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU;wBACxC,WAAW,EAAE,IAAI,CAAC,gBAAgB;wBAClC,QAAQ,EAAE,IAAI,CAAC,cAAc;qBAChC,CAAC,CAAA;oBAEF,2DAA2D;oBAC3D,MAAM,gBAAgB,GAAG,IAAI,YAAY,CAAC,eAAe,CAAC,CAAA;oBAC1D,IAAI,GAAG,IAAI,YAAY,CACnB,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CACpD,CAAA;oBACD,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAA;oBAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAA;gBACvD,CAAC;qBAAM,CAAC;oBACJ,uDAAuD;oBACvD,IAAI,GAAG,cAAc,CAAA;gBACzB,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,CAAC,WAAW,IAAI,CAAC,CAAA;gBAErB,IAAI,CAAC,sBAAsB,CAAC;oBACxB,IAAI;oBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBAC1B,CAAC,CAAA;gBACF,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAA,CAAC,kBAAkB;gBAE5C,IAAI,CAAC,sBAAsB,EAAE,WAAW,CACpC;oBACI,OAAO,EAAE,SAAS;oBAClB,WAAW,EAAE,cAAc;oBAC3B,UAAU;oBACV,eAAe,EACX,IAAI,CAAC,MAAM,CAAC,eAAe;wBAC3B,6BAA6B;oBACjC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,KAAK;oBACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,mBAAmB,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI;oBACzC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;oBACvC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;iBACjC,EACD,EAAE,CACL,CAAA;YACL,CAAC,CAAA;YAED,MAAM,CAAC,KAAK,CACR,+CAA+C,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,EAC7E,IAAI,CAAC,MAAM,CACd,CAAA;YACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC;gBACnC,OAAO,EAAE,MAAM;gBACf,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,gCAAgC;gBAChF,gBAAgB,EACZ,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU;gBAC1D,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,QAAQ,EAAE,IAAI,CAAC,gBAAgB;gBAC/B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,oBAAoB;aACzD,CAAC,CAAA;YAEF,iEAAiE;YACjE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;YAC1C,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,oCAAoC,EAAE,KAAK,CAAC,CAAA;QACrE,CAAC;IACL,CAAC;IAED,0BAA0B,CAAC,mBAA4B;QACnD,IAAI,CAAC;YACD,IAAI,mBAAmB,EAAE,CAAC;gBACtB,0CAA0C;gBAC1C,yHAAyH;gBACzH,6DAA6D;gBAC7D,IAAI,CAAC,sBAAsB,GAAG,IAAI,MAAM,CACpC,IAAI,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CACrD,CAAA;gBACD,IAAI,CAAC,sBAAsB,CAAC,SAAS;oBACjC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACjD,IAAI,CAAC,sBAAsB,CAAC,OAAO;oBAC/B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACzC,CAAC;iBAAM,CAAC;gBACJ,2DAA2D;gBAC3D,IAAI,CAAC,kBAAkB,EAAE,CAAA;YAC7B,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACT,IAAI,GAAG,iDAAiD,EACxD,KAAK,CACR,CAAA;YACD,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAC7B,CAAC;IACL,CAAC;IAED,kBAAkB;QACd,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,uBAAuB,CAAC,EAAE;gBAC7C,IAAI,EAAE,wBAAwB;aACjC,CAAC,CAAA;YACF,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YACrC,IAAI,CAAC,sBAAsB,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAA;YAC7C,IAAI,CAAC,sBAAsB,CAAC,SAAS;gBACjC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjD,IAAI,CAAC,sBAAsB,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;gBAC5C,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,gCAAgC,EAAE,KAAK,CAAC,CAAA;YACjE,CAAC,CAAA;YACD,MAAM,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACT,IAAI,GAAG,wDAAwD,EAC/D,KAAK,CACR,CAAA;QACL,CAAC;IACL,CAAC;IAED,iBAAiB,CAAC,KAAiB;QAC/B,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,mCAAmC,EAAE,KAAK,CAAC,CAAA;IACpE,CAAC;IAED,6BAA6B,CAAC,KAAyB;QACnD,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YACpC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAA;YAEvC,6DAA6D;YAC7D,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;YACnE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CACvC,GAAG,CAAC,aAAa,CAAC,cAAc,IAAI,EAAE,CAAC,CAC1C,CAAA;YACD,IAAI,CAAC,iBAAiB,CAAC,UAAU,GAAG,aAAa,CAAC,UAAU,CAAA;YAC5D,IAAI,aAAa,CAAC,cAAc,EAAE,CAAC;gBAC/B,IAAI,CAAC,iBAAiB,CAAC,cAAc,GAAG;oBACpC,GAAG,EAAE,IAAI,CAAC,GAAG,CACT,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EACzC,aAAa,CAAC,cAAc,CAAC,GAAG,CACnC;oBACD,GAAG,EAAE,IAAI,CAAC,GAAG,CACT,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EACzC,aAAa,CAAC,cAAc,CAAC,GAAG,CACnC;iBACJ,CAAA;YACL,CAAC;YACD,kEAAkE;YAClE,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;YAC3D,MAAM,CAAC,KAAK,CACR,kCAAkC,EAClC,IAAI,CAAC,iBAAiB,CACzB,CAAA;YACD,IAAI,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAA;QACjD,CAAC;IACL,CAAC;IAED,KAAK;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QAC1C,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAC5D,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;IACxB,CAAC;IAED,IAAI;QACA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC;gBACD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,iDAAiD;oBACjD,mEAAmE;oBACnE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;oBAE3D,iFAAiF;oBACjF,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;wBAC5B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,CAC1C,SAAS,EACT,SAAS,CACZ,CAAA;wBACD,MAAM,CACF,IAAI,KAAK,CACL,kDAAkD,CACrD,CACJ,CAAA;oBACL,CAAC,EAAE,IAAI,CAAC,CAAA;oBAER,0DAA0D;oBAC1D,MAAM,SAAS,GAAG,KAAK,EAAE,KAAwB,EAAE,EAAE;wBACjD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAA;wBAClC,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;4BAC7B,YAAY,CAAC,OAAO,CAAC,CAAA,CAAC,oBAAoB;4BAE1C,MAAM,cAAc,GAChB,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;4BAErC,IAAI,CAAC,cAAc,EAAE,CAAC;gCAClB,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAA;gCAChD,OAAM;4BACV,CAAC;4BAED,wCAAwC;4BACxC,MAAM,QAAQ,GACV,cAAc,CAAC,UAAU;gCACzB,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU;oCACzB,CAAC,IAAI,CAAC,cAAc;wCAChB,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;4BACnC,MAAM,CAAC,KAAK,CACR,uCAAuC,QAAQ,OAAO,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,UAAU,CAC3H,CAAA;4BACD,MAAM,CAAC,KAAK,CACR,uBAAuB,cAAc,CAAC,UAAU,8BAA8B,IAAI,CAAC,eAAe,EAAE,CACvG,CAAA;4BAED,2DAA2D;4BAC3D,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,CAC1C,SAAS,EACT,SAAS,CACZ,CAAA;4BAED,qCAAqC;4BACrC,MAAM,eAAe,GAAG,cAAc,CAAC;gCACnC,MAAM,EAAE,cAAc,CAAC,MAAM;gCAC7B,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU;gCACxC,WAAW,EAAE,IAAI,CAAC,gBAAgB;gCAClC,QAAQ,EAAE,IAAI,CAAC,cAAc;6BAChC,CAAC,CAAA;4BACF,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC;gCAC3C,MAAM,EAAE,eAAe;gCACvB,QAAQ,EAAE,IAAI,CAAC,cAAc;6BAChC,CAAC,CAAA;4BAEF,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA,CAAC,iDAAiD;wBACrF,CAAC;oBACL,CAAC,CAAA;oBACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CACvC,SAAS,EACT,SAAS,CACZ,CAAA;gBACL,CAAC;gBAED,6DAA6D;gBAC7D,IAAI,CAAC,qBAAqB,EAAE,CAAA;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC;QACL,CAAC,CAAC,CAAA;IACN,CAAC;IAED,KAAK;QACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA,CAAC,kDAAkD;QAChG,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA,CAAC,uDAAuD;QACvH,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,qBAAqB;QACjB,mDAAmD;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,CAAA;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EACnB,YAAY,GAIf;QACG,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;YACrC,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YACrC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;YACjC,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;YAEhD,wBAAwB;YACxB,MAAM,WAAW,GACb,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,WAAW,CAAC,CAAA;YAExD,iDAAiD;YACjD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAA;YAC3D,YAAY,CAAC,MAAM,GAAG,WAAW,CAAA;YACjC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;YACnD,YAAY,CAAC,KAAK,EAAE,CAAA;YACpB,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,iCAAiC,EAAE,KAAK,CAAC,CAAA;QAClE,CAAC;IACL,CAAC;IAEO,uBAAuB,CAAC,EAAE,UAAU,EAA0B;QAClE,8BAA8B;QAC9B,MAAM,UAAU,GAAG,UAAU,GAAG,GAAG,CAAA,CAAC,kBAAkB;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAC9C,CAAC,EACD,UAAU,EACV,UAAU,CACb,CAAA;QAED,mBAAmB;QACnB,MAAM,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QACjD,MAAM,QAAQ,GAAG,WAAW,CAAC,iBAAiB,GAAG,CAAC,CAAA,CAAC,mCAAmC;QAEtF,OAAO;YACH,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,QAAQ;YACR,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;SACjD,CAAA;IACL,CAAC;IAED,MAAM;QACF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QAC1C,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;QAC5D,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjE,CAAC;CACJ","sourcesContent":["// src/WebRecorder.ts\nimport { buffer } from 'stream/consumers'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport { RecordingConfig } from './ExpoAudioStream.types'\nimport {\n EmitAudioAnalysisFunction,\n EmitAudioEventFunction,\n} from './ExpoAudioStream.web'\nimport { getLogger } from './logger'\nimport { convertPCMToFloat32 } from './utils/convertPCMToFloat32'\nimport { encodingToBitDepth } from './utils/encodingToBitDepth'\nimport { writeWavHeader } from './utils/writeWavHeader'\nimport { InlineFeaturesExtractor } from './workers/InlineFeaturesExtractor.web'\nimport { InlineAudioWebWorker } from './workers/inlineAudioWebWorker.web'\n\ninterface AudioWorkletEvent {\n data: {\n command: string\n recordedData?: Float32Array\n sampleRate?: number\n }\n}\n\ninterface AudioFeaturesEvent {\n data: {\n command: string\n result: AudioAnalysis\n }\n}\n\nconst DEFAULT_WEB_BITDEPTH = 32\nconst DEFAULT_WEB_POINTS_PER_SECOND = 10\nconst DEFAULT_WEB_INTERVAL = 500\nconst DEFAULT_WEB_NUMBER_OF_CHANNELS = 1\nconst DEFAULT_ALGORITHM = 'rms'\n\nconst TAG = 'WebRecorder'\nconst logger = getLogger(TAG)\n\nexport class WebRecorder {\n private audioContext: AudioContext\n private audioWorkletNode!: AudioWorkletNode\n private featureExtractorWorker?: Worker\n private source: MediaStreamAudioSourceNode\n private audioWorkletUrl: string\n private emitAudioEventCallback: EmitAudioEventFunction\n private emitAudioAnalysisCallback: EmitAudioAnalysisFunction\n private config: RecordingConfig\n private position: number // Track the cumulative position\n private numberOfChannels: number // Number of audio channels\n private bitDepth: number // Bit depth of the audio\n private exportBitDepth: number // Bit depth of the audio\n private audioBuffer: Float32Array // Single buffer to store the audio data\n private audioBufferSize: number // Keep track of the buffer size\n private audioAnalysisData: AudioAnalysis // Keep updating the full audio analysis data with latest events\n private packetCount: number = 0\n\n constructor({\n audioContext,\n source,\n recordingConfig,\n audioWorkletUrl,\n emitAudioEventCallback,\n emitAudioAnalysisCallback,\n }: {\n audioContext: AudioContext\n source: MediaStreamAudioSourceNode\n recordingConfig: RecordingConfig\n audioWorkletUrl: string\n emitAudioEventCallback: EmitAudioEventFunction\n emitAudioAnalysisCallback: EmitAudioAnalysisFunction\n }) {\n this.audioContext = audioContext\n this.source = source\n this.audioWorkletUrl = audioWorkletUrl\n this.emitAudioEventCallback = emitAudioEventCallback\n this.emitAudioAnalysisCallback = emitAudioAnalysisCallback\n this.config = recordingConfig\n this.position = 0\n\n const audioContextFormat = this.checkAudioContextFormat({\n sampleRate: this.audioContext.sampleRate,\n })\n logger.debug('Initialized WebRecorder with config:', {\n sampleRate: audioContextFormat.sampleRate,\n bitDepth: audioContextFormat.bitDepth,\n numberOfChannels: audioContextFormat.numberOfChannels,\n })\n\n this.bitDepth = audioContextFormat.bitDepth\n this.numberOfChannels =\n audioContextFormat.numberOfChannels ||\n DEFAULT_WEB_NUMBER_OF_CHANNELS // Default to 1 if not available\n this.exportBitDepth =\n encodingToBitDepth({\n encoding: recordingConfig.encoding ?? 'pcm_32bit',\n }) ||\n audioContextFormat.bitDepth ||\n DEFAULT_WEB_BITDEPTH\n\n // Initialize the audio buffer separately\n this.audioBuffer = new Float32Array(0)\n this.audioBufferSize = 0\n\n this.audioAnalysisData = {\n amplitudeRange: { min: 0, max: 0 },\n dataPoints: [],\n durationMs: 0,\n samples: 0,\n amplitudeAlgorithm: recordingConfig.algorithm || DEFAULT_ALGORITHM,\n bitDepth: this.bitDepth,\n numberOfChannels: this.numberOfChannels,\n sampleRate: this.config.sampleRate || this.audioContext.sampleRate,\n pointsPerSecond:\n this.config.pointsPerSecond || DEFAULT_WEB_POINTS_PER_SECOND,\n speakerChanges: [],\n }\n\n if (recordingConfig.enableProcessing) {\n this.initFeatureExtractorWorker()\n }\n }\n\n async init() {\n try {\n if (!this.audioWorkletUrl) {\n const blob = new Blob([InlineAudioWebWorker], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n await this.audioContext.audioWorklet.addModule(url)\n } else {\n await this.audioContext.audioWorklet.addModule(\n this.audioWorkletUrl\n )\n }\n this.audioWorkletNode = new AudioWorkletNode(\n this.audioContext,\n 'recorder-processor'\n )\n\n this.audioWorkletNode.port.onmessage = async (\n event: AudioWorkletEvent\n ) => {\n const command = event.data.command\n if (command !== 'newData') {\n return\n }\n const pcmBufferFloat = event.data.recordedData\n\n if (!pcmBufferFloat) {\n logger.warn('Received empty audio buffer', event)\n return\n }\n\n // Handle the audio blob (e.g., send it to the server or process it further)\n logger.debug(\n `Received audio blob from processor len:${pcmBufferFloat?.length}`,\n event\n )\n // Concatenate the incoming Float32Array to the existing buffer\n const newBuffer = new Float32Array(\n this.audioBufferSize + pcmBufferFloat.length\n )\n newBuffer.set(this.audioBuffer, 0)\n newBuffer.set(pcmBufferFloat, this.audioBufferSize)\n this.audioBuffer = newBuffer\n this.audioBufferSize += pcmBufferFloat.length\n\n const sampleRate =\n event.data.sampleRate ?? this.audioContext.sampleRate\n const duration = pcmBufferFloat.length / sampleRate // Calculate duration of the current buffer\n\n let data: Float32Array\n if (this.packetCount === 0) {\n // Initialize WAV header\n const wavHeaderBuffer = writeWavHeader({\n sampleRate: this.audioContext.sampleRate,\n numChannels: this.numberOfChannels,\n bitDepth: this.exportBitDepth,\n })\n\n // For the first packet, combine WAV header with audio data\n const headerFloatArray = new Float32Array(wavHeaderBuffer)\n data = new Float32Array(\n headerFloatArray.length + this.audioBuffer.length\n )\n data.set(headerFloatArray, 0)\n data.set(this.audioBuffer, headerFloatArray.length)\n } else {\n // For subsequent packets, just send the new audio data\n data = pcmBufferFloat\n }\n\n // Track the number of packets\n this.packetCount += 1\n\n this.emitAudioEventCallback({\n data,\n position: this.position,\n })\n this.position += duration // Update position\n\n this.featureExtractorWorker?.postMessage(\n {\n command: 'process',\n channelData: pcmBufferFloat,\n sampleRate,\n pointsPerSecond:\n this.config.pointsPerSecond ||\n DEFAULT_WEB_POINTS_PER_SECOND,\n algorithm: this.config.algorithm || 'rms',\n bitDepth: this.bitDepth,\n fullAudioDurationMs: this.position * 1000,\n numberOfChannels: this.numberOfChannels,\n features: this.config.features,\n },\n []\n )\n }\n\n logger.debug(\n `WebRecorder initialized -- recordSampleRate=${this.audioContext.sampleRate}`,\n this.config\n )\n this.audioWorkletNode.port.postMessage({\n command: 'init',\n recordSampleRate: this.audioContext.sampleRate, // Pass the original sample rate\n exportSampleRate:\n this.config.sampleRate ?? this.audioContext.sampleRate,\n bitDepth: this.bitDepth,\n exportBitDepth: this.exportBitDepth,\n channels: this.numberOfChannels,\n interval: this.config.interval ?? DEFAULT_WEB_INTERVAL,\n })\n\n // Connect the source to the AudioWorkletNode and start recording\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n } catch (error) {\n console.error(`[${TAG}] Failed to initialize WebRecorder`, error)\n }\n }\n\n initFeatureExtractorWorker(featuresExtratorUrl?: string) {\n try {\n if (featuresExtratorUrl) {\n // Initialize the feature extractor worker\n //TODO: create audio feature extractor from a Blob instead of url since we cannot include the url directly in the library\n // We keep the url during dev and use the blob in production.\n this.featureExtractorWorker = new Worker(\n new URL(featuresExtratorUrl, window.location.href)\n )\n this.featureExtractorWorker.onmessage =\n this.handleFeatureExtractorMessage.bind(this)\n this.featureExtractorWorker.onerror =\n this.handleWorkerError.bind(this)\n } else {\n // Fallback to the inline worker if the URL is not provided\n this.initFallbackWorker()\n }\n } catch (error) {\n console.error(\n `[${TAG}] Failed to initialize feature extractor worker`,\n error\n )\n this.initFallbackWorker()\n }\n }\n\n initFallbackWorker() {\n try {\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n this.featureExtractorWorker = new Worker(url)\n this.featureExtractorWorker.onmessage =\n this.handleFeatureExtractorMessage.bind(this)\n this.featureExtractorWorker.onerror = (error) => {\n console.error(`[${TAG}] Default Inline worker failed`, error)\n }\n logger.log('Inline worker initialized successfully')\n } catch (error) {\n console.error(\n `[${TAG}] Failed to initialize Inline Feature Extractor worker`,\n error\n )\n }\n }\n\n handleWorkerError(error: ErrorEvent) {\n console.error(`[${TAG}] Feature extractor worker error:`, error)\n }\n\n handleFeatureExtractorMessage(event: AudioFeaturesEvent) {\n if (event.data.command === 'features') {\n const segmentResult = event.data.result\n\n // Merge the segment result with the full audio analysis data\n this.audioAnalysisData.dataPoints.push(...segmentResult.dataPoints)\n this.audioAnalysisData.speakerChanges?.push(\n ...(segmentResult.speakerChanges ?? [])\n )\n this.audioAnalysisData.durationMs = segmentResult.durationMs\n if (segmentResult.amplitudeRange) {\n this.audioAnalysisData.amplitudeRange = {\n min: Math.min(\n this.audioAnalysisData.amplitudeRange.min,\n segmentResult.amplitudeRange.min\n ),\n max: Math.max(\n this.audioAnalysisData.amplitudeRange.max,\n segmentResult.amplitudeRange.max\n ),\n }\n }\n // Handle the extracted features (e.g., emit an event or log them)\n logger.debug('features event segmentResult', segmentResult)\n logger.debug(\n 'features event audioAnalysisData',\n this.audioAnalysisData\n )\n this.emitAudioAnalysisCallback(segmentResult)\n }\n }\n\n start() {\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n this.packetCount = 0\n }\n\n stop(): Promise<Float32Array> {\n return new Promise((resolve, reject) => {\n try {\n if (this.audioWorkletNode) {\n // this.source.disconnect(this.audioWorkletNode);\n // this.audioWorkletNode.disconnect(this.audioContext.destination);\n this.audioWorkletNode.port.postMessage({ command: 'stop' })\n\n // Set a timeout to reject the promise if no message is received within 5 seconds\n const timeout = setTimeout(() => {\n this.audioWorkletNode.port.removeEventListener(\n 'message',\n onMessage\n )\n reject(\n new Error(\n \"Timeout error, audioWorkletNode didn't complete.\"\n )\n )\n }, 5000)\n\n // Listen for the recordedData message to confirm stopping\n const onMessage = async (event: AudioWorkletEvent) => {\n const command = event.data.command\n if (command === 'recordedData') {\n clearTimeout(timeout) // Clear the timeout\n\n const rawPCMDataFull =\n event.data.recordedData?.slice(0)\n\n if (!rawPCMDataFull) {\n reject(new Error('Failed to get recorded data'))\n return\n }\n\n // Compute duration of the recorded data\n const duration =\n rawPCMDataFull.byteLength /\n (this.audioContext.sampleRate *\n (this.exportBitDepth /\n this.numberOfChannels))\n logger.debug(\n `Received recorded data -- Duration: ${duration} vs ${rawPCMDataFull.byteLength / this.audioContext.sampleRate} seconds`\n )\n logger.debug(\n `recordedData.length=${rawPCMDataFull.byteLength} vs transmittedData.length=${this.audioBufferSize}`\n )\n\n // Remove the event listener after receiving the final data\n this.audioWorkletNode.port.removeEventListener(\n 'message',\n onMessage\n )\n\n // Add wav header to the raw PCM data\n const wavHeaderBuffer = writeWavHeader({\n buffer: rawPCMDataFull.buffer,\n sampleRate: this.audioContext.sampleRate,\n numChannels: this.numberOfChannels,\n bitDepth: this.exportBitDepth,\n })\n const convertedPCM = await convertPCMToFloat32({\n buffer: wavHeaderBuffer,\n bitDepth: this.exportBitDepth,\n })\n\n resolve(convertedPCM.pcmValues) // Resolve the promise with the collected buffers\n }\n }\n this.audioWorkletNode.port.addEventListener(\n 'message',\n onMessage\n )\n }\n\n // Stop all media stream tracks to stop the browser recording\n this.stopMediaStreamTracks()\n } catch (error) {\n reject(error)\n }\n })\n }\n\n pause() {\n this.source.disconnect(this.audioWorkletNode) // Disconnect the source from the AudioWorkletNode\n this.audioWorkletNode.disconnect(this.audioContext.destination) // Disconnect the AudioWorkletNode from the destination\n this.audioWorkletNode.port.postMessage({ command: 'pause' })\n }\n\n stopMediaStreamTracks() {\n // Stop all audio tracks to stop the recording icon\n const tracks = this.source.mediaStream.getTracks()\n tracks.forEach((track) => track.stop())\n }\n\n async playRecordedData({\n recordedData,\n }: {\n recordedData: ArrayBuffer\n mimeType?: string\n }) {\n try {\n const blob = new Blob([recordedData])\n const url = URL.createObjectURL(blob)\n const response = await fetch(url)\n const arrayBuffer = await response.arrayBuffer()\n\n // Decode the audio data\n const audioBuffer =\n await this.audioContext.decodeAudioData(arrayBuffer)\n\n // Create a buffer source node and play the audio\n const bufferSource = this.audioContext.createBufferSource()\n bufferSource.buffer = audioBuffer\n bufferSource.connect(this.audioContext.destination)\n bufferSource.start()\n logger.debug('Playing recorded data', recordedData)\n } catch (error) {\n console.error(`[${TAG}] Failed to play recorded data:`, error)\n }\n }\n\n private checkAudioContextFormat({ sampleRate }: { sampleRate: number }) {\n // Create a silent AudioBuffer\n const frameCount = sampleRate * 1.0 // 1 second buffer\n const audioBuffer = this.audioContext.createBuffer(\n 1,\n frameCount,\n sampleRate\n )\n\n // Check the format\n const channelData = audioBuffer.getChannelData(0)\n const bitDepth = channelData.BYTES_PER_ELEMENT * 8 // 4 bytes per element means 32-bit\n\n return {\n sampleRate: audioBuffer.sampleRate,\n bitDepth,\n numberOfChannels: audioBuffer.numberOfChannels,\n }\n }\n\n resume() {\n this.source.connect(this.audioWorkletNode)\n this.audioWorkletNode.connect(this.audioContext.destination)\n this.audioWorkletNode.port.postMessage({ command: 'resume' })\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siteed/expo-audio-stream",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.11",
|
|
4
4
|
"description": "stream audio crossplatform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
"release": "./publish.sh"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@expo/config-plugins": "
|
|
40
|
+
"@expo/config-plugins": "~8.0.0",
|
|
41
41
|
"@siteed/react-native-logger": "^0.10.0",
|
|
42
42
|
"@size-limit/preset-big-lib": "^11.1.4",
|
|
43
43
|
"@types/jest": "^29.5.12",
|
|
44
44
|
"@types/node": "^20.12.7",
|
|
45
|
-
"@types/react": "
|
|
45
|
+
"@types/react": "~18.2.79",
|
|
46
46
|
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
|
47
47
|
"@typescript-eslint/parser": "^7.7.0",
|
|
48
48
|
"bundle-size": "^1.1.5",
|
|
@@ -53,15 +53,16 @@
|
|
|
53
53
|
"eslint-plugin-prettier": "^5.1.3",
|
|
54
54
|
"eslint-plugin-promise": "^6.1.1",
|
|
55
55
|
"eslint-plugin-react": "^7.34.1",
|
|
56
|
+
"expo": "^51.0.38",
|
|
56
57
|
"expo-module-scripts": "^3.5.2",
|
|
57
|
-
"expo-modules-core": "
|
|
58
|
+
"expo-modules-core": "~1.12.23",
|
|
58
59
|
"jest": "^29.7.0",
|
|
59
60
|
"prettier": "^3.2.5",
|
|
60
|
-
"react-native": "
|
|
61
|
+
"react-native": "0.74.5",
|
|
61
62
|
"size-limit": "^11.1.4",
|
|
62
63
|
"typedoc": "^0.26.5",
|
|
63
64
|
"typedoc-plugin-markdown": "^4.2.3",
|
|
64
|
-
"typescript": "
|
|
65
|
+
"typescript": "~5.3.3"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
68
|
"@siteed/react-native-logger": "*",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/index.ts"],"version":"5.6.3"}
|
package/publish.sh
CHANGED
|
@@ -4,8 +4,7 @@ set -e
|
|
|
4
4
|
yarn version patch
|
|
5
5
|
version=$(node -p "require('./package.json').version")
|
|
6
6
|
git add .
|
|
7
|
-
git commit -m "feat: bump version to $version"
|
|
8
7
|
echo "Generated updated documentation for version $version"
|
|
9
8
|
yarn docgen
|
|
10
9
|
yarn clean && yarn prepare && yarn npm publish
|
|
11
|
-
|
|
10
|
+
git commit -m "feat: bump version to $version"
|
package/src/WebRecorder.web.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// src/WebRecorder.ts
|
|
2
|
+
import { buffer } from 'stream/consumers'
|
|
3
|
+
|
|
2
4
|
import { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'
|
|
3
5
|
import { RecordingConfig } from './ExpoAudioStream.types'
|
|
4
6
|
import {
|
|
@@ -6,6 +8,7 @@ import {
|
|
|
6
8
|
EmitAudioEventFunction,
|
|
7
9
|
} from './ExpoAudioStream.web'
|
|
8
10
|
import { getLogger } from './logger'
|
|
11
|
+
import { convertPCMToFloat32 } from './utils/convertPCMToFloat32'
|
|
9
12
|
import { encodingToBitDepth } from './utils/encodingToBitDepth'
|
|
10
13
|
import { writeWavHeader } from './utils/writeWavHeader'
|
|
11
14
|
import { InlineFeaturesExtractor } from './workers/InlineFeaturesExtractor.web'
|
|
@@ -382,7 +385,20 @@ export class WebRecorder {
|
|
|
382
385
|
'message',
|
|
383
386
|
onMessage
|
|
384
387
|
)
|
|
385
|
-
|
|
388
|
+
|
|
389
|
+
// Add wav header to the raw PCM data
|
|
390
|
+
const wavHeaderBuffer = writeWavHeader({
|
|
391
|
+
buffer: rawPCMDataFull.buffer,
|
|
392
|
+
sampleRate: this.audioContext.sampleRate,
|
|
393
|
+
numChannels: this.numberOfChannels,
|
|
394
|
+
bitDepth: this.exportBitDepth,
|
|
395
|
+
})
|
|
396
|
+
const convertedPCM = await convertPCMToFloat32({
|
|
397
|
+
buffer: wavHeaderBuffer,
|
|
398
|
+
bitDepth: this.exportBitDepth,
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
resolve(convertedPCM.pcmValues) // Resolve the promise with the collected buffers
|
|
386
402
|
}
|
|
387
403
|
}
|
|
388
404
|
this.audioWorkletNode.port.addEventListener(
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values
DELETED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
�w�g�f
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|