whisper.rn 0.5.0-rc.1 → 0.5.0-rc.10

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 (116) hide show
  1. package/README.md +128 -50
  2. package/android/src/main/CMakeLists.txt +1 -0
  3. package/android/src/main/java/com/rnwhisper/RNWhisper.java +35 -0
  4. package/android/src/main/java/com/rnwhisper/WhisperContext.java +33 -0
  5. package/android/src/main/jni.cpp +81 -0
  6. package/android/src/newarch/java/com/rnwhisper/RNWhisperModule.java +5 -0
  7. package/android/src/oldarch/java/com/rnwhisper/RNWhisperModule.java +5 -0
  8. package/cpp/jsi/RNWhisperJSI.cpp +42 -6
  9. package/ios/RNWhisper.mm +11 -0
  10. package/ios/RNWhisperContext.h +1 -0
  11. package/ios/RNWhisperContext.mm +46 -0
  12. package/ios/rnwhisper.xcframework/ios-arm64/rnwhisper.framework/Info.plist +0 -0
  13. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/Info.plist +0 -0
  14. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/_CodeSignature/CodeResources +1 -1
  15. package/ios/rnwhisper.xcframework/ios-arm64_x86_64-simulator/rnwhisper.framework/rnwhisper +0 -0
  16. package/ios/rnwhisper.xcframework/tvos-arm64/rnwhisper.framework/Info.plist +0 -0
  17. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/Info.plist +0 -0
  18. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/_CodeSignature/CodeResources +1 -1
  19. package/ios/rnwhisper.xcframework/tvos-arm64_x86_64-simulator/rnwhisper.framework/rnwhisper +0 -0
  20. package/lib/commonjs/AudioSessionIos.js +2 -1
  21. package/lib/commonjs/AudioSessionIos.js.map +1 -1
  22. package/lib/commonjs/NativeRNWhisper.js.map +1 -1
  23. package/lib/commonjs/index.js +50 -10
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/jest-mock.js +126 -0
  26. package/lib/commonjs/jest-mock.js.map +1 -0
  27. package/lib/commonjs/realtime-transcription/RealtimeTranscriber.js +857 -0
  28. package/lib/commonjs/realtime-transcription/RealtimeTranscriber.js.map +1 -0
  29. package/lib/commonjs/realtime-transcription/SliceManager.js +233 -0
  30. package/lib/commonjs/realtime-transcription/SliceManager.js.map +1 -0
  31. package/lib/commonjs/realtime-transcription/adapters/AudioPcmStreamAdapter.js +133 -0
  32. package/lib/commonjs/realtime-transcription/adapters/AudioPcmStreamAdapter.js.map +1 -0
  33. package/lib/commonjs/realtime-transcription/adapters/JestAudioStreamAdapter.js +201 -0
  34. package/lib/commonjs/realtime-transcription/adapters/JestAudioStreamAdapter.js.map +1 -0
  35. package/lib/commonjs/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.js +309 -0
  36. package/lib/commonjs/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.js.map +1 -0
  37. package/lib/commonjs/realtime-transcription/index.js +27 -0
  38. package/lib/commonjs/realtime-transcription/index.js.map +1 -0
  39. package/lib/commonjs/realtime-transcription/types.js +114 -0
  40. package/lib/commonjs/realtime-transcription/types.js.map +1 -0
  41. package/lib/commonjs/utils/WavFileReader.js +158 -0
  42. package/lib/commonjs/utils/WavFileReader.js.map +1 -0
  43. package/lib/commonjs/utils/WavFileWriter.js +181 -0
  44. package/lib/commonjs/utils/WavFileWriter.js.map +1 -0
  45. package/lib/commonjs/utils/common.js +25 -0
  46. package/lib/commonjs/utils/common.js.map +1 -0
  47. package/lib/module/AudioSessionIos.js +2 -1
  48. package/lib/module/AudioSessionIos.js.map +1 -1
  49. package/lib/module/NativeRNWhisper.js.map +1 -1
  50. package/lib/module/index.js +48 -10
  51. package/lib/module/index.js.map +1 -1
  52. package/lib/module/jest-mock.js +124 -0
  53. package/lib/module/jest-mock.js.map +1 -0
  54. package/lib/module/realtime-transcription/RealtimeTranscriber.js +851 -0
  55. package/lib/module/realtime-transcription/RealtimeTranscriber.js.map +1 -0
  56. package/lib/module/realtime-transcription/SliceManager.js +226 -0
  57. package/lib/module/realtime-transcription/SliceManager.js.map +1 -0
  58. package/lib/module/realtime-transcription/adapters/AudioPcmStreamAdapter.js +124 -0
  59. package/lib/module/realtime-transcription/adapters/AudioPcmStreamAdapter.js.map +1 -0
  60. package/lib/module/realtime-transcription/adapters/JestAudioStreamAdapter.js +194 -0
  61. package/lib/module/realtime-transcription/adapters/JestAudioStreamAdapter.js.map +1 -0
  62. package/lib/module/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.js +302 -0
  63. package/lib/module/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.js.map +1 -0
  64. package/lib/module/realtime-transcription/index.js +8 -0
  65. package/lib/module/realtime-transcription/index.js.map +1 -0
  66. package/lib/module/realtime-transcription/types.js +107 -0
  67. package/lib/module/realtime-transcription/types.js.map +1 -0
  68. package/lib/module/utils/WavFileReader.js +151 -0
  69. package/lib/module/utils/WavFileReader.js.map +1 -0
  70. package/lib/module/utils/WavFileWriter.js +174 -0
  71. package/lib/module/utils/WavFileWriter.js.map +1 -0
  72. package/lib/module/utils/common.js +18 -0
  73. package/lib/module/utils/common.js.map +1 -0
  74. package/lib/typescript/AudioSessionIos.d.ts +1 -1
  75. package/lib/typescript/AudioSessionIos.d.ts.map +1 -1
  76. package/lib/typescript/NativeRNWhisper.d.ts +1 -0
  77. package/lib/typescript/NativeRNWhisper.d.ts.map +1 -1
  78. package/lib/typescript/index.d.ts +8 -4
  79. package/lib/typescript/index.d.ts.map +1 -1
  80. package/lib/typescript/jest-mock.d.ts +2 -0
  81. package/lib/typescript/jest-mock.d.ts.map +1 -0
  82. package/lib/typescript/realtime-transcription/RealtimeTranscriber.d.ts +166 -0
  83. package/lib/typescript/realtime-transcription/RealtimeTranscriber.d.ts.map +1 -0
  84. package/lib/typescript/realtime-transcription/SliceManager.d.ts +72 -0
  85. package/lib/typescript/realtime-transcription/SliceManager.d.ts.map +1 -0
  86. package/lib/typescript/realtime-transcription/adapters/AudioPcmStreamAdapter.d.ts +22 -0
  87. package/lib/typescript/realtime-transcription/adapters/AudioPcmStreamAdapter.d.ts.map +1 -0
  88. package/lib/typescript/realtime-transcription/adapters/JestAudioStreamAdapter.d.ts +44 -0
  89. package/lib/typescript/realtime-transcription/adapters/JestAudioStreamAdapter.d.ts.map +1 -0
  90. package/lib/typescript/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.d.ts +75 -0
  91. package/lib/typescript/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.d.ts.map +1 -0
  92. package/lib/typescript/realtime-transcription/index.d.ts +6 -0
  93. package/lib/typescript/realtime-transcription/index.d.ts.map +1 -0
  94. package/lib/typescript/realtime-transcription/types.d.ts +222 -0
  95. package/lib/typescript/realtime-transcription/types.d.ts.map +1 -0
  96. package/lib/typescript/utils/WavFileReader.d.ts +61 -0
  97. package/lib/typescript/utils/WavFileReader.d.ts.map +1 -0
  98. package/lib/typescript/utils/WavFileWriter.d.ts +57 -0
  99. package/lib/typescript/utils/WavFileWriter.d.ts.map +1 -0
  100. package/lib/typescript/utils/common.d.ts +9 -0
  101. package/lib/typescript/utils/common.d.ts.map +1 -0
  102. package/package.json +18 -6
  103. package/src/AudioSessionIos.ts +3 -2
  104. package/src/NativeRNWhisper.ts +2 -0
  105. package/src/index.ts +74 -22
  106. package/{jest/mock.js → src/jest-mock.ts} +2 -2
  107. package/src/realtime-transcription/RealtimeTranscriber.ts +1015 -0
  108. package/src/realtime-transcription/SliceManager.ts +252 -0
  109. package/src/realtime-transcription/adapters/AudioPcmStreamAdapter.ts +143 -0
  110. package/src/realtime-transcription/adapters/JestAudioStreamAdapter.ts +251 -0
  111. package/src/realtime-transcription/adapters/SimulateFileAudioStreamAdapter.ts +378 -0
  112. package/src/realtime-transcription/index.ts +34 -0
  113. package/src/realtime-transcription/types.ts +283 -0
  114. package/src/utils/WavFileReader.ts +202 -0
  115. package/src/utils/WavFileWriter.ts +206 -0
  116. package/src/utils/common.ts +17 -0
package/src/index.ts CHANGED
@@ -29,37 +29,43 @@ declare global {
29
29
  var whisperTranscribeData: (
30
30
  contextId: number,
31
31
  options: TranscribeOptions,
32
- data: ArrayBuffer | SharedArrayBuffer,
32
+ data: ArrayBuffer,
33
33
  ) => Promise<TranscribeResult>
34
34
  // eslint-disable-next-line no-var
35
35
  var whisperVadDetectSpeech: (
36
36
  contextId: number,
37
37
  options: VadOptions,
38
- audioData: ArrayBuffer | SharedArrayBuffer,
38
+ audioData: ArrayBuffer,
39
39
  ) => Promise<{ hasSpeech: boolean; segments: VadSegment[] }>
40
40
  }
41
41
 
42
42
  let jsiWhisperTranscribeData: (
43
43
  contextId: number,
44
44
  options: TranscribeOptions,
45
- data: ArrayBuffer | SharedArrayBuffer,
45
+ data: ArrayBuffer,
46
46
  ) => Promise<TranscribeResult>
47
47
  let jsiWhisperVadDetectSpeech: (
48
48
  contextId: number,
49
49
  options: VadOptions,
50
- audioData: ArrayBuffer | SharedArrayBuffer,
50
+ audioData: ArrayBuffer,
51
51
  ) => Promise<{ hasSpeech: boolean; segments: VadSegment[] }>
52
52
 
53
- RNWhisper.installJSIBindings()
54
- .then(() => {
55
- jsiWhisperTranscribeData = global.whisperTranscribeData
56
- delete (global as any).whisperTranscribeData
57
- jsiWhisperVadDetectSpeech = global.whisperVadDetectSpeech
58
- delete (global as any).whisperVadDetectSpeech
59
- })
60
- .catch((e) => {
61
- console.warn('Failed to install JSI bindings', e)
62
- })
53
+ let jsiInstalled = false
54
+
55
+ const installJSIBindingsIfNeeded = async () => {
56
+ if (jsiInstalled) return
57
+ jsiInstalled = true
58
+ return RNWhisper.installJSIBindings()
59
+ .then(() => {
60
+ jsiWhisperTranscribeData = global.whisperTranscribeData
61
+ delete (global as any).whisperTranscribeData
62
+ jsiWhisperVadDetectSpeech = global.whisperVadDetectSpeech
63
+ delete (global as any).whisperVadDetectSpeech
64
+ })
65
+ .catch((e) => {
66
+ console.warn('Failed to install JSI bindings', e)
67
+ })
68
+ }
63
69
 
64
70
  let EventEmitter: NativeEventEmitter | DeviceEventEmitterStatic
65
71
  if (Platform.OS === 'ios') {
@@ -82,10 +88,25 @@ export type {
82
88
 
83
89
  const EVENT_ON_TRANSCRIBE_PROGRESS = '@RNWhisper_onTranscribeProgress'
84
90
  const EVENT_ON_TRANSCRIBE_NEW_SEGMENTS = '@RNWhisper_onTranscribeNewSegments'
91
+ const EVENT_ON_NATIVE_LOG = '@RNWhisper_onNativeLog'
85
92
 
86
93
  const EVENT_ON_REALTIME_TRANSCRIBE = '@RNWhisper_onRealtimeTranscribe'
87
94
  const EVENT_ON_REALTIME_TRANSCRIBE_END = '@RNWhisper_onRealtimeTranscribeEnd'
88
95
 
96
+ const logListeners: Array<(level: string, text: string) => void> = []
97
+
98
+ // @ts-ignore
99
+ if (EventEmitter) {
100
+ EventEmitter.addListener(
101
+ EVENT_ON_NATIVE_LOG,
102
+ (evt: { level: string; text: string }) => {
103
+ logListeners.forEach((listener) => listener(evt.level, evt.text))
104
+ },
105
+ )
106
+ // Trigger unset to use default log callback
107
+ RNWhisper?.toggleNativeLog?.(false)?.catch?.(() => {})
108
+ }
109
+
89
110
  export type TranscribeNewSegmentsResult = {
90
111
  nNew: number
91
112
  totalNNew: number
@@ -370,13 +391,13 @@ export class WhisperContext {
370
391
  * Transcribe audio data (base64 encoded float32 PCM data or ArrayBuffer)
371
392
  */
372
393
  transcribeData(
373
- data: string | ArrayBuffer | SharedArrayBuffer,
394
+ data: string | ArrayBuffer,
374
395
  options: TranscribeFileOptions = {},
375
396
  ): {
376
397
  stop: () => Promise<void>
377
398
  promise: Promise<TranscribeResult>
378
399
  } {
379
- if (data instanceof ArrayBuffer || data instanceof SharedArrayBuffer) {
400
+ if (data instanceof ArrayBuffer) {
380
401
  // Use JSI function for ArrayBuffer
381
402
  if (!jsiWhisperTranscribeData) {
382
403
  throw new Error('JSI binding `whisperTranscribeData` not installed')
@@ -390,7 +411,7 @@ export class WhisperContext {
390
411
  * Transcribe audio data from ArrayBuffer (16-bit PCM, mono, 16kHz)
391
412
  */
392
413
  private transcribeDataArrayBuffer(
393
- data: ArrayBuffer | SharedArrayBuffer,
414
+ data: ArrayBuffer,
394
415
  options: TranscribeFileOptions = {},
395
416
  ): {
396
417
  stop: () => Promise<void>
@@ -444,6 +465,10 @@ export class WhisperContext {
444
465
  /** Subscribe to realtime transcribe events */
445
466
  subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void
446
467
  }> {
468
+ console.warn(
469
+ '`transcribeRealtime` is deprecated, use `RealtimeTranscriber` instead',
470
+ )
471
+
447
472
  let lastTranscribePayload: TranscribeRealtimeNativePayload
448
473
 
449
474
  const slices: TranscribeRealtimeNativePayload[] = []
@@ -630,6 +655,8 @@ export async function initWhisper({
630
655
  useCoreMLIos = true,
631
656
  useFlashAttn = false,
632
657
  }: ContextOptions): Promise<WhisperContext> {
658
+ await installJSIBindingsIfNeeded()
659
+
633
660
  let path = ''
634
661
  let coreMLAssets: CoreMLAsset[] | undefined
635
662
  if (coreMLModelAsset) {
@@ -689,6 +716,8 @@ export async function initWhisper({
689
716
  }
690
717
 
691
718
  export async function releaseAllWhisper(): Promise<void> {
719
+ await installJSIBindingsIfNeeded()
720
+
692
721
  return RNWhisper.releaseAllContexts()
693
722
  }
694
723
 
@@ -771,13 +800,10 @@ export class WhisperVadContext {
771
800
  * Detect speech segments in raw audio data (base64 encoded float32 PCM data or ArrayBuffer)
772
801
  */
773
802
  async detectSpeechData(
774
- audioData: string | ArrayBuffer | SharedArrayBuffer,
803
+ audioData: string | ArrayBuffer,
775
804
  options: VadOptions = {},
776
805
  ): Promise<VadSegment[]> {
777
- if (
778
- audioData instanceof ArrayBuffer ||
779
- audioData instanceof SharedArrayBuffer
780
- ) {
806
+ if (audioData instanceof ArrayBuffer) {
781
807
  // Use JSI function for ArrayBuffer
782
808
  if (!jsiWhisperVadDetectSpeech) {
783
809
  throw new Error('JSI binding `whisperVadDetectSpeech` not installed')
@@ -808,6 +834,8 @@ export async function initWhisperVad({
808
834
  useGpu = true,
809
835
  nThreads,
810
836
  }: VadContextOptions): Promise<WhisperVadContext> {
837
+ await installJSIBindingsIfNeeded()
838
+
811
839
  let path = ''
812
840
  if (typeof filePath === 'number') {
813
841
  try {
@@ -840,5 +868,29 @@ export async function initWhisperVad({
840
868
  * @returns Promise resolving when all contexts are released
841
869
  */
842
870
  export async function releaseAllWhisperVad(): Promise<void> {
871
+ await installJSIBindingsIfNeeded()
872
+
843
873
  return RNWhisper.releaseAllVadContexts()
844
874
  }
875
+
876
+ let logInitialized = false
877
+
878
+ export async function toggleNativeLog(enabled: boolean): Promise<void> {
879
+ if (!enabled && !logInitialized) return // If first call is false, skip
880
+
881
+ logInitialized = true
882
+ await installJSIBindingsIfNeeded()
883
+
884
+ return RNWhisper.toggleNativeLog(enabled)
885
+ }
886
+
887
+ export function addNativeLogListener(
888
+ listener: (level: string, text: string) => void,
889
+ ): { remove: () => void } {
890
+ logListeners.push(listener)
891
+ return {
892
+ remove: () => {
893
+ logListeners.splice(logListeners.indexOf(listener), 1)
894
+ },
895
+ }
896
+ }
@@ -1,4 +1,4 @@
1
- const { NativeModules, DeviceEventEmitter } = require('react-native')
1
+ import { NativeModules, DeviceEventEmitter } from 'react-native'
2
2
 
3
3
  if (!NativeModules.RNWhisper) {
4
4
  NativeModules.RNWhisper = {
@@ -97,4 +97,4 @@ if (!NativeModules.RNWhisper) {
97
97
  }
98
98
  }
99
99
 
100
- module.exports = jest.requireActual('whisper.rn')
100
+ module.exports = jest.requireActual('whisper.rn/index')