whisper.rn 0.1.5 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jest/mock.js CHANGED
@@ -1,14 +1,55 @@
1
- const { NativeModules } = require('react-native')
1
+ const { NativeModules, DeviceEventEmitter } = require('react-native')
2
2
 
3
3
  if (!NativeModules.RNWhisper) {
4
4
  NativeModules.RNWhisper = {
5
5
  initContext: jest.fn(() => Promise.resolve(1)),
6
- transcribe: jest.fn(() => Promise.resolve({
6
+ transcribeFile: jest.fn(() => Promise.resolve({
7
7
  result: ' Test',
8
8
  segments: [{ text: ' Test', t0: 0, t1: 33 }],
9
9
  })),
10
+ startRealtimeTranscribe: jest.fn((contextId, jobId) => {
11
+ setTimeout(() => {
12
+ // Start
13
+ DeviceEventEmitter.emit('@RNWhisper_onRealtimeTranscribe', {
14
+ contextId,
15
+ jobId,
16
+ payload: {
17
+ isCapturing: true,
18
+ data: {
19
+ result: ' Test',
20
+ segments: [{ text: ' Test', t0: 0, t1: 33 }],
21
+ },
22
+ processTime: 100,
23
+ recordingTime: 1000,
24
+ },
25
+ })
26
+ DeviceEventEmitter.emit('@RNWhisper_onRealtimeTranscribe', {
27
+ contextId,
28
+ jobId,
29
+ payload: {
30
+ isCapturing: false,
31
+ data: {
32
+ result: ' Test',
33
+ segments: [{ text: ' Test', t0: 0, t1: 33 }],
34
+ },
35
+ processTime: 100,
36
+ recordingTime: 2000,
37
+ },
38
+ })
39
+ // End event
40
+ DeviceEventEmitter.emit('@RNWhisper_onRealtimeTranscribeEnd', {
41
+ contextId,
42
+ jobId,
43
+ payload: {},
44
+ })
45
+ })
46
+ }),
10
47
  releaseContext: jest.fn(() => Promise.resolve()),
11
48
  releaseAllContexts: jest.fn(() => Promise.resolve()),
49
+
50
+ // For NativeEventEmitter
51
+ addListener: jest.fn(),
52
+ removeListeners: jest.fn(),
12
53
  }
13
54
  }
14
55
 
@@ -15,13 +15,70 @@ const RNWhisper = _reactNative.NativeModules.RNWhisper ? _reactNative.NativeModu
15
15
  throw new Error(LINKING_ERROR);
16
16
  }
17
17
  });
18
+ let EventEmitter;
19
+ if (_reactNative.Platform.OS === 'ios') {
20
+ EventEmitter = new _reactNative.NativeEventEmitter(RNWhisper);
21
+ }
22
+ if (_reactNative.Platform.OS === 'android') {
23
+ EventEmitter = _reactNative.DeviceEventEmitter;
24
+ }
25
+ const EVENT_ON_REALTIME_TRANSCRIBE = '@RNWhisper_onRealtimeTranscribe';
26
+ const EVENT_ON_REALTIME_TRANSCRIBE_END = '@RNWhisper_onRealtimeTranscribeEnd';
18
27
  class WhisperContext {
19
28
  constructor(id) {
20
29
  this.id = id;
21
30
  }
22
- async transcribe(path) {
31
+
32
+ /** Transcribe audio file */
33
+ transcribe(path) {
23
34
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
24
- return RNWhisper.transcribe(this.id, path, options);
35
+ const jobId = Math.floor(Math.random() * 10000);
36
+ return {
37
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
38
+ promise: RNWhisper.transcribeFile(this.id, jobId, path, options)
39
+ };
40
+ }
41
+
42
+ /** Transcribe the microphone audio stream, the microphone user permission is required */
43
+ async transcribeRealtime() {
44
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
45
+ const jobId = Math.floor(Math.random() * 10000);
46
+ await RNWhisper.startRealtimeTranscribe(this.id, jobId, options);
47
+ let lastTranscribePayload;
48
+ return {
49
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
50
+ subscribe: callback => {
51
+ const transcribeListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE, evt => {
52
+ const {
53
+ contextId,
54
+ payload
55
+ } = evt;
56
+ if (contextId !== this.id || evt.jobId !== jobId) return;
57
+ lastTranscribePayload = payload;
58
+ callback({
59
+ contextId,
60
+ jobId: evt.jobId,
61
+ ...payload
62
+ });
63
+ });
64
+ const endListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE_END, evt => {
65
+ const {
66
+ contextId,
67
+ payload
68
+ } = evt;
69
+ if (contextId !== this.id || evt.jobId !== jobId) return;
70
+ callback({
71
+ contextId,
72
+ jobId: evt.jobId,
73
+ ...lastTranscribePayload,
74
+ ...payload,
75
+ isCapturing: false
76
+ });
77
+ transcribeListener.remove();
78
+ endListener.remove();
79
+ });
80
+ }
81
+ };
25
82
  }
26
83
  async release() {
27
84
  return RNWhisper.releaseContext(this.id);
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","RNWhisper","NativeModules","Proxy","get","Error","WhisperContext","constructor","id","transcribe","path","options","arguments","length","undefined","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GAChB,sEAAqEC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAC3I,oDAAmD;AAEtD,MAAMC,SAAS,GAAGC,0BAAa,CAACD,SAAS,GACrCC,0BAAa,CAACD,SAAS,GACvB,IAAIE,KAAK,CACT,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CAAC,CACF;AA6BH,MAAMU,cAAc,CAAC;EAGnBC,WAAWA,CAACC,EAAU,EAAE;IACtB,IAAI,CAACA,EAAE,GAAGA,EAAE;EACd;EAEA,MAAMC,UAAUA,CAACC,IAAY,EAA8D;IAAA,IAA5DC,OAA0B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;IAC5D,OAAOX,SAAS,CAACQ,UAAU,CAAC,IAAI,CAACD,EAAE,EAAEE,IAAI,EAAEC,OAAO,CAAC;EACrD;EAEA,MAAMI,OAAOA,CAAA,EAAG;IACd,OAAOd,SAAS,CAACe,cAAc,CAAC,IAAI,CAACR,EAAE,CAAC;EAC1C;AACF;AAEO,eAAeS,WAAWA,CAAA,EAEN;EAAA,IADzB;IAAEC;EAAgC,CAAC,GAAAN,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAExC,MAAMJ,EAAE,GAAG,MAAMP,SAAS,CAACkB,WAAW,CAACD,QAAQ,CAAC;EAChD,OAAO,IAAIZ,cAAc,CAACE,EAAE,CAAC;AAC/B;AAEO,eAAeY,iBAAiBA,CAAA,EAAkB;EACvD,OAAOnB,SAAS,CAACoB,kBAAkB,EAAE;AACvC"}
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","RNWhisper","NativeModules","Proxy","get","Error","EventEmitter","OS","NativeEventEmitter","DeviceEventEmitter","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","path","options","arguments","length","undefined","jobId","Math","floor","random","stop","abortTranscribe","promise","transcribeFile","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","subscribe","callback","transcribeListener","addListener","evt","contextId","payload","endListener","isCapturing","remove","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { NativeModules, Platform } from 'react-native';
1
+ import { NativeEventEmitter, DeviceEventEmitter, NativeModules, Platform } from 'react-native';
2
2
  const LINKING_ERROR = `The package 'whisper.rn' doesn't seem to be linked. Make sure: \n\n${Platform.select({
3
3
  ios: "- You have run 'pod install'\n",
4
4
  default: ''
@@ -8,13 +8,70 @@ const RNWhisper = NativeModules.RNWhisper ? NativeModules.RNWhisper : new Proxy(
8
8
  throw new Error(LINKING_ERROR);
9
9
  }
10
10
  });
11
+ let EventEmitter;
12
+ if (Platform.OS === 'ios') {
13
+ EventEmitter = new NativeEventEmitter(RNWhisper);
14
+ }
15
+ if (Platform.OS === 'android') {
16
+ EventEmitter = DeviceEventEmitter;
17
+ }
18
+ const EVENT_ON_REALTIME_TRANSCRIBE = '@RNWhisper_onRealtimeTranscribe';
19
+ const EVENT_ON_REALTIME_TRANSCRIBE_END = '@RNWhisper_onRealtimeTranscribeEnd';
11
20
  class WhisperContext {
12
21
  constructor(id) {
13
22
  this.id = id;
14
23
  }
15
- async transcribe(path) {
24
+
25
+ /** Transcribe audio file */
26
+ transcribe(path) {
16
27
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
17
- return RNWhisper.transcribe(this.id, path, options);
28
+ const jobId = Math.floor(Math.random() * 10000);
29
+ return {
30
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
31
+ promise: RNWhisper.transcribeFile(this.id, jobId, path, options)
32
+ };
33
+ }
34
+
35
+ /** Transcribe the microphone audio stream, the microphone user permission is required */
36
+ async transcribeRealtime() {
37
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
38
+ const jobId = Math.floor(Math.random() * 10000);
39
+ await RNWhisper.startRealtimeTranscribe(this.id, jobId, options);
40
+ let lastTranscribePayload;
41
+ return {
42
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
43
+ subscribe: callback => {
44
+ const transcribeListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE, evt => {
45
+ const {
46
+ contextId,
47
+ payload
48
+ } = evt;
49
+ if (contextId !== this.id || evt.jobId !== jobId) return;
50
+ lastTranscribePayload = payload;
51
+ callback({
52
+ contextId,
53
+ jobId: evt.jobId,
54
+ ...payload
55
+ });
56
+ });
57
+ const endListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE_END, evt => {
58
+ const {
59
+ contextId,
60
+ payload
61
+ } = evt;
62
+ if (contextId !== this.id || evt.jobId !== jobId) return;
63
+ callback({
64
+ contextId,
65
+ jobId: evt.jobId,
66
+ ...lastTranscribePayload,
67
+ ...payload,
68
+ isCapturing: false
69
+ });
70
+ transcribeListener.remove();
71
+ endListener.remove();
72
+ });
73
+ }
74
+ };
18
75
  }
19
76
  async release() {
20
77
  return RNWhisper.releaseContext(this.id);
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","RNWhisper","Proxy","get","Error","WhisperContext","constructor","id","transcribe","path","options","arguments","length","undefined","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,MAAMC,aAAa,GAChB,sEAAqED,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAC3I,oDAAmD;AAEtD,MAAMC,SAAS,GAAGN,aAAa,CAACM,SAAS,GACrCN,aAAa,CAACM,SAAS,GACvB,IAAIC,KAAK,CACT,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CAAC,CACF;AA6BH,MAAMQ,cAAc,CAAC;EAGnBC,WAAWA,CAACC,EAAU,EAAE;IACtB,IAAI,CAACA,EAAE,GAAGA,EAAE;EACd;EAEA,MAAMC,UAAUA,CAACC,IAAY,EAA8D;IAAA,IAA5DC,OAA0B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;IAC5D,OAAOV,SAAS,CAACO,UAAU,CAAC,IAAI,CAACD,EAAE,EAAEE,IAAI,EAAEC,OAAO,CAAC;EACrD;EAEA,MAAMI,OAAOA,CAAA,EAAG;IACd,OAAOb,SAAS,CAACc,cAAc,CAAC,IAAI,CAACR,EAAE,CAAC;EAC1C;AACF;AAEA,OAAO,eAAeS,WAAWA,CAAA,EAEN;EAAA,IADzB;IAAEC;EAAgC,CAAC,GAAAN,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAExC,MAAMJ,EAAE,GAAG,MAAMN,SAAS,CAACiB,WAAW,CAACD,QAAQ,CAAC;EAChD,OAAO,IAAIZ,cAAc,CAACE,EAAE,CAAC;AAC/B;AAEA,OAAO,eAAeY,iBAAiBA,CAAA,EAAkB;EACvD,OAAOlB,SAAS,CAACmB,kBAAkB,EAAE;AACvC"}
1
+ {"version":3,"names":["NativeEventEmitter","DeviceEventEmitter","NativeModules","Platform","LINKING_ERROR","select","ios","default","RNWhisper","Proxy","get","Error","EventEmitter","OS","EVENT_ON_REALTIME_TRANSCRIBE","EVENT_ON_REALTIME_TRANSCRIBE_END","WhisperContext","constructor","id","transcribe","path","options","arguments","length","undefined","jobId","Math","floor","random","stop","abortTranscribe","promise","transcribeFile","transcribeRealtime","startRealtimeTranscribe","lastTranscribePayload","subscribe","callback","transcribeListener","addListener","evt","contextId","payload","endListener","isCapturing","remove","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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"}
@@ -1,20 +1,42 @@
1
1
  export type TranscribeOptions = {
2
+ /** Spoken language (Default: 'auto' for auto-detect) */
2
3
  language?: string;
4
+ /** Translate from source language to english (Default: false) */
3
5
  translate?: boolean;
6
+ /** Number of threads to use during computation (Default: 4) */
4
7
  maxThreads?: number;
8
+ /** Maximum number of text context tokens to store */
5
9
  maxContext?: number;
10
+ /** Maximum segment length in characters */
6
11
  maxLen?: number;
12
+ /** Enable token-level timestamps */
7
13
  tokenTimestamps?: boolean;
14
+ /** Word timestamp probability threshold */
15
+ wordThold?: number;
16
+ /** Time offset in milliseconds */
8
17
  offset?: number;
18
+ /** Duration of audio to process in milliseconds */
9
19
  duration?: number;
10
- wordThold?: number;
20
+ /** Tnitial decoding temperature */
11
21
  temperature?: number;
12
22
  temperatureInc?: number;
23
+ /** Beam size for beam search */
13
24
  beamSize?: number;
25
+ /** Number of best candidates to keep */
14
26
  bestOf?: number;
27
+ /** Speed up audio by x2 (reduced accuracy) */
15
28
  speedUp?: boolean;
29
+ /** Initial Prompt */
16
30
  prompt?: string;
17
31
  };
32
+ export type TranscribeRealtimeOptions = TranscribeOptions & {
33
+ /**
34
+ * Realtime record max duration in seconds.
35
+ * Due to the whisper.cpp hard constraint - processes the audio in chunks of 30 seconds,
36
+ * the recommended value will be <= 30 seconds. (Default: 30)
37
+ */
38
+ realtimeAudioSec?: number;
39
+ };
18
40
  export type TranscribeResult = {
19
41
  result: string;
20
42
  segments: Array<{
@@ -23,10 +45,49 @@ export type TranscribeResult = {
23
45
  t1: number;
24
46
  }>;
25
47
  };
48
+ export type TranscribeRealtimeEvent = {
49
+ contextId: number;
50
+ jobId: number;
51
+ /** Is capturing audio, when false, the event is the final result */
52
+ isCapturing: boolean;
53
+ isStoppedByAction?: boolean;
54
+ code: number;
55
+ processTime: number;
56
+ recordingTime: number;
57
+ data?: TranscribeResult;
58
+ error?: string;
59
+ };
60
+ export type TranscribeRealtimeNativeEvent = {
61
+ contextId: number;
62
+ jobId: number;
63
+ payload: {
64
+ /** Is capturing audio, when false, the event is the final result */
65
+ isCapturing: boolean;
66
+ isStoppedByAction?: boolean;
67
+ code: number;
68
+ processTime: number;
69
+ recordingTime: number;
70
+ data?: TranscribeResult;
71
+ error?: string;
72
+ };
73
+ };
26
74
  declare class WhisperContext {
27
75
  id: number;
28
76
  constructor(id: number);
29
- transcribe(path: string, options?: TranscribeOptions): Promise<TranscribeResult>;
77
+ /** Transcribe audio file */
78
+ transcribe(path: string, options?: TranscribeOptions): {
79
+ /** Stop the transcribe */
80
+ stop: () => void;
81
+ /** Transcribe result promise */
82
+ promise: Promise<TranscribeResult>;
83
+ };
84
+ /** Transcribe the microphone audio stream, the microphone user permission is required */
85
+ transcribeRealtime(options?: TranscribeRealtimeOptions): Promise<{
86
+ /** Stop the realtime transcribe */
87
+ stop: () => void;
88
+ /** Subscribe to realtime transcribe events */
89
+ subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void;
90
+ }>;
30
91
  release(): Promise<any>;
31
92
  }
32
93
  export declare function initWhisper({ filePath }?: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC,CAAC;CACJ,CAAA;AAED,cAAM,cAAc;IAClB,EAAE,EAAE,MAAM,CAAA;gBAEE,EAAE,EAAE,MAAM;IAIhB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpF,OAAO;CAGd;AAED,wBAAsB,WAAW,CAC/B,EAAE,QAAQ,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC,cAAc,CAAC,CAGzB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whisper.rn",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "React Native binding of whisper.cpp",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.tsx CHANGED
@@ -1,4 +1,10 @@
1
- import { NativeModules, Platform } from 'react-native'
1
+ import {
2
+ NativeEventEmitter,
3
+ DeviceEventEmitter,
4
+ NativeModules,
5
+ Platform,
6
+ DeviceEventEmitterStatic,
7
+ } from 'react-native'
2
8
 
3
9
  const LINKING_ERROR =
4
10
  `The package 'whisper.rn' doesn't seem to be linked. Make sure: \n\n${Platform.select({ ios: "- You have run 'pod install'\n", default: '' })
@@ -15,24 +21,58 @@ const RNWhisper = NativeModules.RNWhisper
15
21
  },
16
22
  )
17
23
 
24
+ let EventEmitter: NativeEventEmitter | DeviceEventEmitterStatic
25
+ if (Platform.OS === 'ios') {
26
+ EventEmitter = new NativeEventEmitter(RNWhisper)
27
+ }
28
+ if (Platform.OS === 'android') {
29
+ EventEmitter = DeviceEventEmitter
30
+ }
31
+
32
+ const EVENT_ON_REALTIME_TRANSCRIBE = '@RNWhisper_onRealtimeTranscribe'
33
+ const EVENT_ON_REALTIME_TRANSCRIBE_END = '@RNWhisper_onRealtimeTranscribeEnd'
34
+
18
35
  export type TranscribeOptions = {
36
+ /** Spoken language (Default: 'auto' for auto-detect) */
19
37
  language?: string,
38
+ /** Translate from source language to english (Default: false) */
20
39
  translate?: boolean,
40
+ /** Number of threads to use during computation (Default: 4) */
21
41
  maxThreads?: number,
42
+ /** Maximum number of text context tokens to store */
22
43
  maxContext?: number,
44
+ /** Maximum segment length in characters */
23
45
  maxLen?: number,
46
+ /** Enable token-level timestamps */
24
47
  tokenTimestamps?: boolean,
48
+ /** Word timestamp probability threshold */
49
+ wordThold?: number,
50
+ /** Time offset in milliseconds */
25
51
  offset?: number,
52
+ /** Duration of audio to process in milliseconds */
26
53
  duration?: number,
27
- wordThold?: number,
54
+ /** Tnitial decoding temperature */
28
55
  temperature?: number,
29
56
  temperatureInc?: number,
57
+ /** Beam size for beam search */
30
58
  beamSize?: number,
59
+ /** Number of best candidates to keep */
31
60
  bestOf?: number,
61
+ /** Speed up audio by x2 (reduced accuracy) */
32
62
  speedUp?: boolean,
63
+ /** Initial Prompt */
33
64
  prompt?: string,
34
65
  }
35
66
 
67
+ export type TranscribeRealtimeOptions = TranscribeOptions & {
68
+ /**
69
+ * Realtime record max duration in seconds.
70
+ * Due to the whisper.cpp hard constraint - processes the audio in chunks of 30 seconds,
71
+ * the recommended value will be <= 30 seconds. (Default: 30)
72
+ */
73
+ realtimeAudioSec?: number,
74
+ }
75
+
36
76
  export type TranscribeResult = {
37
77
  result: string,
38
78
  segments: Array<{
@@ -42,6 +82,34 @@ export type TranscribeResult = {
42
82
  }>,
43
83
  }
44
84
 
85
+ export type TranscribeRealtimeEvent = {
86
+ contextId: number,
87
+ jobId: number,
88
+ /** Is capturing audio, when false, the event is the final result */
89
+ isCapturing: boolean,
90
+ isStoppedByAction?: boolean,
91
+ code: number,
92
+ processTime: number,
93
+ recordingTime: number,
94
+ data?: TranscribeResult,
95
+ error?: string,
96
+ }
97
+
98
+ export type TranscribeRealtimeNativeEvent = {
99
+ contextId: number,
100
+ jobId: number,
101
+ payload: {
102
+ /** Is capturing audio, when false, the event is the final result */
103
+ isCapturing: boolean,
104
+ isStoppedByAction?: boolean,
105
+ code: number,
106
+ processTime: number,
107
+ recordingTime: number,
108
+ data?: TranscribeResult,
109
+ error?: string,
110
+ },
111
+ }
112
+
45
113
  class WhisperContext {
46
114
  id: number
47
115
 
@@ -49,8 +117,60 @@ class WhisperContext {
49
117
  this.id = id
50
118
  }
51
119
 
52
- async transcribe(path: string, options: TranscribeOptions = {}): Promise<TranscribeResult> {
53
- return RNWhisper.transcribe(this.id, path, options)
120
+ /** Transcribe audio file */
121
+ transcribe(path: string, options: TranscribeOptions = {}): {
122
+ /** Stop the transcribe */
123
+ stop: () => void,
124
+ /** Transcribe result promise */
125
+ promise: Promise<TranscribeResult>,
126
+ } {
127
+ const jobId: number = Math.floor(Math.random() * 10000)
128
+ return {
129
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
130
+ promise: RNWhisper.transcribeFile(this.id, jobId, path, options),
131
+ }
132
+ }
133
+
134
+ /** Transcribe the microphone audio stream, the microphone user permission is required */
135
+ async transcribeRealtime(options: TranscribeRealtimeOptions = {}): Promise<{
136
+ /** Stop the realtime transcribe */
137
+ stop: () => void,
138
+ /** Subscribe to realtime transcribe events */
139
+ subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void,
140
+ }> {
141
+ const jobId: number = Math.floor(Math.random() * 10000)
142
+ await RNWhisper.startRealtimeTranscribe(this.id, jobId, options)
143
+ let lastTranscribePayload: TranscribeRealtimeNativeEvent['payload']
144
+ return {
145
+ stop: () => RNWhisper.abortTranscribe(this.id, jobId),
146
+ subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => {
147
+ const transcribeListener = EventEmitter.addListener(
148
+ EVENT_ON_REALTIME_TRANSCRIBE,
149
+ (evt: TranscribeRealtimeNativeEvent) => {
150
+ const { contextId, payload } = evt
151
+ if (contextId !== this.id || evt.jobId !== jobId) return
152
+ lastTranscribePayload = payload
153
+ callback({ contextId, jobId: evt.jobId, ...payload })
154
+ }
155
+ )
156
+ const endListener = EventEmitter.addListener(
157
+ EVENT_ON_REALTIME_TRANSCRIBE_END,
158
+ (evt: TranscribeRealtimeNativeEvent) => {
159
+ const { contextId, payload } = evt
160
+ if (contextId !== this.id || evt.jobId !== jobId) return
161
+ callback({
162
+ contextId,
163
+ jobId: evt.jobId,
164
+ ...lastTranscribePayload,
165
+ ...payload,
166
+ isCapturing: false
167
+ })
168
+ transcribeListener.remove()
169
+ endListener.remove()
170
+ }
171
+ )
172
+ },
173
+ }
54
174
  }
55
175
 
56
176
  async release() {