whisper.rn 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +43 -4
- package/android/build.gradle +2 -4
- package/android/src/main/java/com/rnwhisper/RNWhisperModule.java +47 -7
- package/android/src/main/java/com/rnwhisper/WhisperContext.java +196 -7
- package/android/src/main/jni/whisper/Whisper.mk +1 -1
- package/android/src/main/jni/whisper/jni.cpp +33 -9
- package/cpp/rn-whisper.cpp +26 -0
- package/cpp/rn-whisper.h +5 -0
- package/cpp/whisper.cpp +603 -412
- package/cpp/whisper.h +120 -40
- package/ios/RNWhisper.h +2 -2
- package/ios/RNWhisper.mm +78 -111
- package/ios/RNWhisperContext.h +53 -0
- package/ios/RNWhisperContext.mm +303 -0
- package/jest/mock.js +38 -2
- package/lib/commonjs/index.js +63 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +64 -3
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +61 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/index.tsx +121 -4
- package/whisper-rn.podspec +15 -8
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
#import "RNWhisperContext.h"
|
|
2
|
+
|
|
3
|
+
#define NUM_BYTES_PER_BUFFER 16 * 1024
|
|
4
|
+
|
|
5
|
+
@implementation RNWhisperContext
|
|
6
|
+
|
|
7
|
+
+ (instancetype)initWithModelPath:(NSString *)modelPath {
|
|
8
|
+
RNWhisperContext *context = [[RNWhisperContext alloc] init];
|
|
9
|
+
context->ctx = whisper_init_from_file([modelPath UTF8String]);
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
- (struct whisper_context *)getContext {
|
|
14
|
+
return self->ctx;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
- (void)prepareRealtime:(NSDictionary *)options {
|
|
18
|
+
self->recordState.options = options;
|
|
19
|
+
|
|
20
|
+
self->recordState.dataFormat.mSampleRate = WHISPER_SAMPLE_RATE; // 16000
|
|
21
|
+
self->recordState.dataFormat.mFormatID = kAudioFormatLinearPCM;
|
|
22
|
+
self->recordState.dataFormat.mFramesPerPacket = 1;
|
|
23
|
+
self->recordState.dataFormat.mChannelsPerFrame = 1; // mono
|
|
24
|
+
self->recordState.dataFormat.mBytesPerFrame = 2;
|
|
25
|
+
self->recordState.dataFormat.mBytesPerPacket = 2;
|
|
26
|
+
self->recordState.dataFormat.mBitsPerChannel = 16;
|
|
27
|
+
self->recordState.dataFormat.mReserved = 0;
|
|
28
|
+
self->recordState.dataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
|
29
|
+
|
|
30
|
+
self->recordState.nSamples = 0;
|
|
31
|
+
|
|
32
|
+
int maxAudioSecOpt = options[@"realtimeAudioSec"] != nil ? [options[@"realtimeAudioSec"] intValue] : 0;
|
|
33
|
+
int maxAudioSec = maxAudioSecOpt > 0 ? maxAudioSecOpt : DEFAULT_MAX_AUDIO_SEC;
|
|
34
|
+
self->recordState.maxAudioSec = maxAudioSec;
|
|
35
|
+
self->recordState.audioBufferI16 = (int16_t *) malloc(maxAudioSec * WHISPER_SAMPLE_RATE * sizeof(int16_t));
|
|
36
|
+
self->recordState.audioBufferF32 = (float *) malloc(maxAudioSec * WHISPER_SAMPLE_RATE * sizeof(float));
|
|
37
|
+
|
|
38
|
+
self->recordState.isRealtime = true;
|
|
39
|
+
self->recordState.isTranscribing = false;
|
|
40
|
+
self->recordState.isCapturing = false;
|
|
41
|
+
|
|
42
|
+
self->recordState.mSelf = self;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void AudioInputCallback(void * inUserData,
|
|
46
|
+
AudioQueueRef inAQ,
|
|
47
|
+
AudioQueueBufferRef inBuffer,
|
|
48
|
+
const AudioTimeStamp * inStartTime,
|
|
49
|
+
UInt32 inNumberPacketDescriptions,
|
|
50
|
+
const AudioStreamPacketDescription * inPacketDescs)
|
|
51
|
+
{
|
|
52
|
+
RNWhisperContextRecordState *state = (RNWhisperContextRecordState *)inUserData;
|
|
53
|
+
|
|
54
|
+
if (!state->isCapturing) {
|
|
55
|
+
NSLog(@"[RNWhisper] Not capturing, ignoring audio");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const int n = inBuffer->mAudioDataByteSize / 2;
|
|
60
|
+
NSLog(@"[RNWhisper] Captured %d new samples", n);
|
|
61
|
+
|
|
62
|
+
if (state->nSamples + n > state->maxAudioSec * WHISPER_SAMPLE_RATE) {
|
|
63
|
+
NSLog(@"[RNWhisper] Audio buffer is full, ignoring audio");
|
|
64
|
+
state->isCapturing = false;
|
|
65
|
+
if (!state->isTranscribing) {
|
|
66
|
+
state->transcribeHandler(state->jobId, @"end", @{});
|
|
67
|
+
}
|
|
68
|
+
[state->mSelf stopAudio];
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (int i = 0; i < n; i++) {
|
|
73
|
+
state->audioBufferI16[state->nSamples + i] = ((short*)inBuffer->mAudioData)[i];
|
|
74
|
+
}
|
|
75
|
+
state->nSamples += n;
|
|
76
|
+
|
|
77
|
+
AudioQueueEnqueueBuffer(state->queue, inBuffer, 0, NULL);
|
|
78
|
+
|
|
79
|
+
if (!state->isTranscribing) {
|
|
80
|
+
state->isTranscribing = true;
|
|
81
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
82
|
+
NSLog(@"[RNWhisper] Transcribing %d samples", state->nSamples);
|
|
83
|
+
// convert I16 to F32
|
|
84
|
+
for (int i = 0; i < state->nSamples; i++) {
|
|
85
|
+
state->audioBufferF32[i] = (float)state->audioBufferI16[i] / 32768.0f;
|
|
86
|
+
}
|
|
87
|
+
CFTimeInterval timeStart = CACurrentMediaTime();
|
|
88
|
+
|
|
89
|
+
int code = [state->mSelf fullTranscribe:state->jobId audioData:state->audioBufferF32 audioDataCount:state->nSamples options:state->options];
|
|
90
|
+
|
|
91
|
+
CFTimeInterval timeEnd = CACurrentMediaTime();
|
|
92
|
+
const float timeRecording = (float) state->nSamples / (float) state->dataFormat.mSampleRate;
|
|
93
|
+
if (code == 0) {
|
|
94
|
+
state->transcribeHandler(state->jobId, @"transcribe", @{
|
|
95
|
+
@"isCapturing": @(state->isCapturing),
|
|
96
|
+
@"code": [NSNumber numberWithInt:code],
|
|
97
|
+
@"data": [state->mSelf getTextSegments],
|
|
98
|
+
@"processTime": [NSNumber numberWithInt:(timeEnd - timeStart) * 1E3],
|
|
99
|
+
@"recordingTime": [NSNumber numberWithInt:timeRecording * 1E3],
|
|
100
|
+
});
|
|
101
|
+
state->isTranscribing = false;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
state->transcribeHandler(state->jobId, @"transcribe", @{
|
|
105
|
+
@"isCapturing": @(state->isCapturing),
|
|
106
|
+
@"code": [NSNumber numberWithInt:code],
|
|
107
|
+
@"error": [NSString stringWithFormat:@"Transcribe failed with code %d", code],
|
|
108
|
+
@"processTime": [NSNumber numberWithDouble:timeEnd - timeStart],
|
|
109
|
+
@"recordingTime": [NSNumber numberWithFloat:timeRecording],
|
|
110
|
+
});
|
|
111
|
+
if (!state->isCapturing) {
|
|
112
|
+
NSLog(@"[RNWhisper] Transcribe end");
|
|
113
|
+
state->transcribeHandler(state->jobId, @"end", @{});
|
|
114
|
+
}
|
|
115
|
+
state->isTranscribing = false;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
- (bool)isCapturing {
|
|
121
|
+
return self->recordState.isCapturing;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
- (bool)isTranscribing {
|
|
125
|
+
return self->recordState.isTranscribing;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
- (OSStatus)transcribeRealtime:(int)jobId
|
|
129
|
+
options:(NSDictionary *)options
|
|
130
|
+
onTranscribe:(void (^)(int, NSString *, NSDictionary *))onTranscribe
|
|
131
|
+
{
|
|
132
|
+
self->recordState.transcribeHandler = onTranscribe;
|
|
133
|
+
self->recordState.jobId = jobId;
|
|
134
|
+
[self prepareRealtime:options];
|
|
135
|
+
self->recordState.nSamples = 0;
|
|
136
|
+
|
|
137
|
+
OSStatus status = AudioQueueNewInput(
|
|
138
|
+
&self->recordState.dataFormat,
|
|
139
|
+
AudioInputCallback,
|
|
140
|
+
&self->recordState,
|
|
141
|
+
NULL,
|
|
142
|
+
kCFRunLoopCommonModes,
|
|
143
|
+
0,
|
|
144
|
+
&self->recordState.queue
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
if (status == 0) {
|
|
148
|
+
for (int i = 0; i < NUM_BUFFERS; i++) {
|
|
149
|
+
AudioQueueAllocateBuffer(self->recordState.queue, NUM_BYTES_PER_BUFFER, &self->recordState.buffers[i]);
|
|
150
|
+
AudioQueueEnqueueBuffer(self->recordState.queue, self->recordState.buffers[i], 0, NULL);
|
|
151
|
+
}
|
|
152
|
+
status = AudioQueueStart(self->recordState.queue, NULL);
|
|
153
|
+
if (status == 0) {
|
|
154
|
+
self->recordState.isCapturing = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return status;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
- (int)transcribeFile:(int)jobId
|
|
161
|
+
audioData:(float *)audioData
|
|
162
|
+
audioDataCount:(int)audioDataCount
|
|
163
|
+
options:(NSDictionary *)options
|
|
164
|
+
{
|
|
165
|
+
self->recordState.isTranscribing = true;
|
|
166
|
+
self->recordState.jobId = jobId;
|
|
167
|
+
int code = [self fullTranscribe:jobId audioData:audioData audioDataCount:audioDataCount options:options];
|
|
168
|
+
self->recordState.jobId = -1;
|
|
169
|
+
self->recordState.isTranscribing = false;
|
|
170
|
+
return code;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
- (void)stopAudio {
|
|
174
|
+
AudioQueueStop(self->recordState.queue, true);
|
|
175
|
+
for (int i = 0; i < NUM_BUFFERS; i++) {
|
|
176
|
+
AudioQueueFreeBuffer(self->recordState.queue, self->recordState.buffers[i]);
|
|
177
|
+
}
|
|
178
|
+
AudioQueueDispose(self->recordState.queue, true);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
- (void)stopTranscribe:(int)jobId {
|
|
182
|
+
rn_whisper_abort_transcribe(jobId);
|
|
183
|
+
if (!self->recordState.isRealtime || !self->recordState.isCapturing) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
self->recordState.isCapturing = false;
|
|
187
|
+
[self stopAudio];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
- (void)stopCurrentTranscribe {
|
|
191
|
+
if (!self->recordState.jobId) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
[self stopTranscribe:self->recordState.jobId];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
- (int)fullTranscribe:(int)jobId audioData:(float *)audioData audioDataCount:(int)audioDataCount options:(NSDictionary *)options {
|
|
198
|
+
struct whisper_full_params params = whisper_full_default_params(WHISPER_SAMPLING_GREEDY);
|
|
199
|
+
|
|
200
|
+
const int max_threads = options[@"maxThreads"] != nil ?
|
|
201
|
+
[options[@"maxThreads"] intValue] :
|
|
202
|
+
MIN(4, (int)[[NSProcessInfo processInfo] processorCount]);
|
|
203
|
+
|
|
204
|
+
if (options[@"beamSize"] != nil) {
|
|
205
|
+
params.strategy = WHISPER_SAMPLING_BEAM_SEARCH;
|
|
206
|
+
params.beam_search.beam_size = [options[@"beamSize"] intValue];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
params.print_realtime = false;
|
|
210
|
+
params.print_progress = false;
|
|
211
|
+
params.print_timestamps = false;
|
|
212
|
+
params.print_special = false;
|
|
213
|
+
params.speed_up = options[@"speedUp"] != nil ? [options[@"speedUp"] boolValue] : false;
|
|
214
|
+
params.translate = options[@"translate"] != nil ? [options[@"translate"] boolValue] : false;
|
|
215
|
+
params.language = options[@"language"] != nil ? [options[@"language"] UTF8String] : "auto";
|
|
216
|
+
params.n_threads = max_threads;
|
|
217
|
+
params.offset_ms = 0;
|
|
218
|
+
params.no_context = true;
|
|
219
|
+
params.single_segment = self->recordState.isRealtime;
|
|
220
|
+
|
|
221
|
+
if (options[@"maxLen"] != nil) {
|
|
222
|
+
params.max_len = [options[@"maxLen"] intValue];
|
|
223
|
+
}
|
|
224
|
+
params.token_timestamps = options[@"tokenTimestamps"] != nil ? [options[@"tokenTimestamps"] boolValue] : false;
|
|
225
|
+
|
|
226
|
+
if (options[@"bestOf"] != nil) {
|
|
227
|
+
params.greedy.best_of = [options[@"bestOf"] intValue];
|
|
228
|
+
}
|
|
229
|
+
if (options[@"maxContext"] != nil) {
|
|
230
|
+
params.n_max_text_ctx = [options[@"maxContext"] intValue];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (options[@"offset"] != nil) {
|
|
234
|
+
params.offset_ms = [options[@"offset"] intValue];
|
|
235
|
+
}
|
|
236
|
+
if (options[@"duration"] != nil) {
|
|
237
|
+
params.duration_ms = [options[@"duration"] intValue];
|
|
238
|
+
}
|
|
239
|
+
if (options[@"wordThold"] != nil) {
|
|
240
|
+
params.thold_pt = [options[@"wordThold"] intValue];
|
|
241
|
+
}
|
|
242
|
+
if (options[@"temperature"] != nil) {
|
|
243
|
+
params.temperature = [options[@"temperature"] floatValue];
|
|
244
|
+
}
|
|
245
|
+
if (options[@"temperatureInc"] != nil) {
|
|
246
|
+
params.temperature_inc = [options[@"temperature_inc"] floatValue];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (options[@"prompt"] != nil) {
|
|
250
|
+
std::string *prompt = new std::string([options[@"prompt"] UTF8String]);
|
|
251
|
+
rn_whisper_convert_prompt(
|
|
252
|
+
self->ctx,
|
|
253
|
+
params,
|
|
254
|
+
prompt
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
params.encoder_begin_callback = [](struct whisper_context * /*ctx*/, struct whisper_state * /*state*/, void * user_data) {
|
|
259
|
+
bool is_aborted = *(bool*)user_data;
|
|
260
|
+
return !is_aborted;
|
|
261
|
+
};
|
|
262
|
+
params.encoder_begin_callback_user_data = rn_whisper_assign_abort_map(jobId);
|
|
263
|
+
|
|
264
|
+
whisper_reset_timings(self->ctx);
|
|
265
|
+
|
|
266
|
+
int code = whisper_full(self->ctx, params, audioData, audioDataCount);
|
|
267
|
+
rn_whisper_remove_abort_map(jobId);
|
|
268
|
+
// if (code == 0) {
|
|
269
|
+
// whisper_print_timings(self->ctx);
|
|
270
|
+
// }
|
|
271
|
+
return code;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (NSDictionary *)getTextSegments {
|
|
275
|
+
NSString *result = @"";
|
|
276
|
+
int n_segments = whisper_full_n_segments(self->ctx);
|
|
277
|
+
|
|
278
|
+
NSMutableArray *segments = [[NSMutableArray alloc] init];
|
|
279
|
+
for (int i = 0; i < n_segments; i++) {
|
|
280
|
+
const char * text_cur = whisper_full_get_segment_text(self->ctx, i);
|
|
281
|
+
result = [result stringByAppendingString:[NSString stringWithUTF8String:text_cur]];
|
|
282
|
+
|
|
283
|
+
const int64_t t0 = whisper_full_get_segment_t0(self->ctx, i);
|
|
284
|
+
const int64_t t1 = whisper_full_get_segment_t1(self->ctx, i);
|
|
285
|
+
NSDictionary *segment = @{
|
|
286
|
+
@"text": [NSString stringWithUTF8String:text_cur],
|
|
287
|
+
@"t0": [NSNumber numberWithLongLong:t0],
|
|
288
|
+
@"t1": [NSNumber numberWithLongLong:t1]
|
|
289
|
+
};
|
|
290
|
+
[segments addObject:segment];
|
|
291
|
+
}
|
|
292
|
+
return @{
|
|
293
|
+
@"result": result,
|
|
294
|
+
@"segments": segments
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
- (void)invalidate {
|
|
299
|
+
[self stopCurrentTranscribe];
|
|
300
|
+
whisper_free(self->ctx);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
@end
|
package/jest/mock.js
CHANGED
|
@@ -1,14 +1,50 @@
|
|
|
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
|
-
|
|
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
|
+
// End
|
|
27
|
+
DeviceEventEmitter.emit('@RNWhisper_onRealtimeTranscribe', {
|
|
28
|
+
contextId,
|
|
29
|
+
jobId,
|
|
30
|
+
payload: {
|
|
31
|
+
isCapturing: false,
|
|
32
|
+
data: {
|
|
33
|
+
result: ' Test',
|
|
34
|
+
segments: [{ text: ' Test', t0: 0, t1: 33 }],
|
|
35
|
+
},
|
|
36
|
+
processTime: 100,
|
|
37
|
+
recordingTime: 2000,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
}),
|
|
10
42
|
releaseContext: jest.fn(() => Promise.resolve()),
|
|
11
43
|
releaseAllContexts: jest.fn(() => Promise.resolve()),
|
|
44
|
+
|
|
45
|
+
// For NativeEventEmitter
|
|
46
|
+
addListener: jest.fn(),
|
|
47
|
+
removeListeners: jest.fn(),
|
|
12
48
|
}
|
|
13
49
|
}
|
|
14
50
|
|
package/lib/commonjs/index.js
CHANGED
|
@@ -15,13 +15,74 @@ 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
|
-
|
|
31
|
+
|
|
32
|
+
/** Transcribe audio file */
|
|
33
|
+
transcribe(path) {
|
|
23
34
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
24
|
-
|
|
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 removeTranscribe;
|
|
48
|
+
let removeEnd;
|
|
49
|
+
let lastTranscribePayload;
|
|
50
|
+
return {
|
|
51
|
+
stop: () => RNWhisper.abortTranscribe(this.id, jobId),
|
|
52
|
+
subscribe: callback => {
|
|
53
|
+
const transcribeListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE, evt => {
|
|
54
|
+
const {
|
|
55
|
+
contextId,
|
|
56
|
+
payload
|
|
57
|
+
} = evt;
|
|
58
|
+
if (contextId !== this.id || evt.jobId !== jobId) return;
|
|
59
|
+
lastTranscribePayload = payload;
|
|
60
|
+
callback({
|
|
61
|
+
contextId,
|
|
62
|
+
jobId: evt.jobId,
|
|
63
|
+
...payload
|
|
64
|
+
});
|
|
65
|
+
if (!payload.isCapturing) removeTranscribe();
|
|
66
|
+
});
|
|
67
|
+
removeTranscribe = transcribeListener.remove;
|
|
68
|
+
const endListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE_END, evt => {
|
|
69
|
+
var _removeTranscribe;
|
|
70
|
+
const {
|
|
71
|
+
contextId
|
|
72
|
+
} = evt;
|
|
73
|
+
if (contextId !== this.id || evt.jobId !== jobId) return;
|
|
74
|
+
callback({
|
|
75
|
+
contextId,
|
|
76
|
+
jobId: evt.jobId,
|
|
77
|
+
...lastTranscribePayload,
|
|
78
|
+
isCapturing: false
|
|
79
|
+
});
|
|
80
|
+
(_removeTranscribe = removeTranscribe) === null || _removeTranscribe === void 0 ? void 0 : _removeTranscribe();
|
|
81
|
+
removeEnd();
|
|
82
|
+
});
|
|
83
|
+
removeEnd = endListener.remove;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
25
86
|
}
|
|
26
87
|
async release() {
|
|
27
88
|
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;
|
|
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","removeTranscribe","removeEnd","lastTranscribePayload","subscribe","callback","transcribeListener","addListener","evt","contextId","payload","isCapturing","remove","endListener","_removeTranscribe","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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"}
|
package/lib/module/index.js
CHANGED
|
@@ -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,74 @@ 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
|
-
|
|
24
|
+
|
|
25
|
+
/** Transcribe audio file */
|
|
26
|
+
transcribe(path) {
|
|
16
27
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17
|
-
|
|
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 removeTranscribe;
|
|
41
|
+
let removeEnd;
|
|
42
|
+
let lastTranscribePayload;
|
|
43
|
+
return {
|
|
44
|
+
stop: () => RNWhisper.abortTranscribe(this.id, jobId),
|
|
45
|
+
subscribe: callback => {
|
|
46
|
+
const transcribeListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE, evt => {
|
|
47
|
+
const {
|
|
48
|
+
contextId,
|
|
49
|
+
payload
|
|
50
|
+
} = evt;
|
|
51
|
+
if (contextId !== this.id || evt.jobId !== jobId) return;
|
|
52
|
+
lastTranscribePayload = payload;
|
|
53
|
+
callback({
|
|
54
|
+
contextId,
|
|
55
|
+
jobId: evt.jobId,
|
|
56
|
+
...payload
|
|
57
|
+
});
|
|
58
|
+
if (!payload.isCapturing) removeTranscribe();
|
|
59
|
+
});
|
|
60
|
+
removeTranscribe = transcribeListener.remove;
|
|
61
|
+
const endListener = EventEmitter.addListener(EVENT_ON_REALTIME_TRANSCRIBE_END, evt => {
|
|
62
|
+
var _removeTranscribe;
|
|
63
|
+
const {
|
|
64
|
+
contextId
|
|
65
|
+
} = evt;
|
|
66
|
+
if (contextId !== this.id || evt.jobId !== jobId) return;
|
|
67
|
+
callback({
|
|
68
|
+
contextId,
|
|
69
|
+
jobId: evt.jobId,
|
|
70
|
+
...lastTranscribePayload,
|
|
71
|
+
isCapturing: false
|
|
72
|
+
});
|
|
73
|
+
(_removeTranscribe = removeTranscribe) === null || _removeTranscribe === void 0 ? void 0 : _removeTranscribe();
|
|
74
|
+
removeEnd();
|
|
75
|
+
});
|
|
76
|
+
removeEnd = endListener.remove;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
18
79
|
}
|
|
19
80
|
async release() {
|
|
20
81
|
return RNWhisper.releaseContext(this.id);
|
package/lib/module/index.js.map
CHANGED
|
@@ -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,
|
|
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","removeTranscribe","removeEnd","lastTranscribePayload","subscribe","callback","transcribeListener","addListener","evt","contextId","payload","isCapturing","remove","endListener","_removeTranscribe","release","releaseContext","initWhisper","filePath","initContext","releaseAllWhisper","releaseAllContexts"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SACEA,kBAAkB,EAClBC,kBAAkB,EAClBC,aAAa,EACbC,QAAQ,QAEH,cAAc;AAErB,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;AAEH,IAAIQ,YAA2D;AAC/D,IAAIT,QAAQ,CAACU,EAAE,KAAK,KAAK,EAAE;EACzBD,YAAY,GAAG,IAAIZ,kBAAkB,CAACQ,SAAS,CAAC;AAClD;AACA,IAAIL,QAAQ,CAACU,EAAE,KAAK,SAAS,EAAE;EAC7BD,YAAY,GAAGX,kBAAkB;AACnC;AAEA,MAAMa,4BAA4B,GAAG,iCAAiC;AACtE,MAAMC,gCAAgC,GAAG,oCAAoC;AA8E7E,MAAMC,cAAc,CAAC;EAGnBC,WAAWA,CAACC,EAAU,EAAE;IACtB,IAAI,CAACA,EAAE,GAAGA,EAAE;EACd;;EAEA;EACAC,UAAUA,CAACC,IAAY,EAKrB;IAAA,IALuBC,OAA0B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;IAMtD,MAAMG,KAAa,GAAGC,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,EAAE,GAAG,KAAK,CAAC;IACvD,OAAO;MACLC,IAAI,EAAEA,CAAA,KAAMrB,SAAS,CAACsB,eAAe,CAAC,IAAI,CAACZ,EAAE,EAAEO,KAAK,CAAC;MACrDM,OAAO,EAAEvB,SAAS,CAACwB,cAAc,CAAC,IAAI,CAACd,EAAE,EAAEO,KAAK,EAAEL,IAAI,EAAEC,OAAO;IACjE,CAAC;EACH;;EAEA;EACA,MAAMY,kBAAkBA,CAAA,EAKrB;IAAA,IALsBZ,OAAkC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;IAM9D,MAAMG,KAAa,GAAGC,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,MAAM,EAAE,GAAG,KAAK,CAAC;IACvD,MAAMpB,SAAS,CAAC0B,uBAAuB,CAAC,IAAI,CAAChB,EAAE,EAAEO,KAAK,EAAEJ,OAAO,CAAC;IAChE,IAAIc,gBAA4B;IAChC,IAAIC,SAAqB;IACzB,IAAIC,qBAA+D;IACnE,OAAO;MACLR,IAAI,EAAEA,CAAA,KAAMrB,SAAS,CAACsB,eAAe,CAAC,IAAI,CAACZ,EAAE,EAAEO,KAAK,CAAC;MACrDa,SAAS,EAAGC,QAAkD,IAAK;QACjE,MAAMC,kBAAkB,GAAG5B,YAAY,CAAC6B,WAAW,CACjD3B,4BAA4B,EAC3B4B,GAAkC,IAAK;UACtC,MAAM;YAAEC,SAAS;YAAEC;UAAQ,CAAC,GAAGF,GAAG;UAClC,IAAIC,SAAS,KAAK,IAAI,CAACzB,EAAE,IAAIwB,GAAG,CAACjB,KAAK,KAAKA,KAAK,EAAE;UAClDY,qBAAqB,GAAGO,OAAO;UAC/BL,QAAQ,CAAC;YAAEI,SAAS;YAAElB,KAAK,EAAEiB,GAAG,CAACjB,KAAK;YAAE,GAAGmB;UAAQ,CAAC,CAAC;UACrD,IAAI,CAACA,OAAO,CAACC,WAAW,EAAEV,gBAAgB,EAAE;QAC9C,CAAC,CACF;QACDA,gBAAgB,GAAGK,kBAAkB,CAACM,MAAM;QAC5C,MAAMC,WAAW,GAAGnC,YAAY,CAAC6B,WAAW,CAC1C1B,gCAAgC,EAC/B2B,GAAkC,IAAK;UAAA,IAAAM,iBAAA;UACtC,MAAM;YAAEL;UAAU,CAAC,GAAGD,GAAG;UACzB,IAAIC,SAAS,KAAK,IAAI,CAACzB,EAAE,IAAIwB,GAAG,CAACjB,KAAK,KAAKA,KAAK,EAAE;UAClDc,QAAQ,CAAC;YAAEI,SAAS;YAAElB,KAAK,EAAEiB,GAAG,CAACjB,KAAK;YAAE,GAAGY,qBAAqB;YAAEQ,WAAW,EAAE;UAAM,CAAC,CAAC;UACvF,CAAAG,iBAAA,GAAAb,gBAAgB,cAAAa,iBAAA,uBAAhBA,iBAAA,EAAoB;UACpBZ,SAAS,EAAE;QACb,CAAC,CACF;QACDA,SAAS,GAAGW,WAAW,CAACD,MAAM;MAChC;IACF,CAAC;EACH;EAEA,MAAMG,OAAOA,CAAA,EAAG;IACd,OAAOzC,SAAS,CAAC0C,cAAc,CAAC,IAAI,CAAChC,EAAE,CAAC;EAC1C;AACF;AAEA,OAAO,eAAeiC,WAAWA,CAAA,EAEN;EAAA,IADzB;IAAEC;EAAgC,CAAC,GAAA9B,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAExC,MAAMJ,EAAE,GAAG,MAAMV,SAAS,CAAC6C,WAAW,CAACD,QAAQ,CAAC;EAChD,OAAO,IAAIpC,cAAc,CAACE,EAAE,CAAC;AAC/B;AAEA,OAAO,eAAeoC,iBAAiBA,CAAA,EAAkB;EACvD,OAAO9C,SAAS,CAAC+C,kBAAkB,EAAE;AACvC"}
|
|
@@ -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
|
-
|
|
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,47 @@ 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
|
+
code: number;
|
|
54
|
+
processTime: number;
|
|
55
|
+
recordingTime: number;
|
|
56
|
+
data?: TranscribeResult;
|
|
57
|
+
error?: string;
|
|
58
|
+
};
|
|
59
|
+
export type TranscribeRealtimeNativeEvent = {
|
|
60
|
+
contextId: number;
|
|
61
|
+
jobId: number;
|
|
62
|
+
payload: {
|
|
63
|
+
/** Is capturing audio, when false, the event is the final result */
|
|
64
|
+
isCapturing: boolean;
|
|
65
|
+
code: number;
|
|
66
|
+
processTime: number;
|
|
67
|
+
recordingTime: number;
|
|
68
|
+
data?: TranscribeResult;
|
|
69
|
+
error?: string;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
26
72
|
declare class WhisperContext {
|
|
27
73
|
id: number;
|
|
28
74
|
constructor(id: number);
|
|
29
|
-
|
|
75
|
+
/** Transcribe audio file */
|
|
76
|
+
transcribe(path: string, options?: TranscribeOptions): {
|
|
77
|
+
/** Stop the transcribe */
|
|
78
|
+
stop: () => void;
|
|
79
|
+
/** Transcribe result promise */
|
|
80
|
+
promise: Promise<TranscribeResult>;
|
|
81
|
+
};
|
|
82
|
+
/** Transcribe the microphone audio stream, the microphone user permission is required */
|
|
83
|
+
transcribeRealtime(options?: TranscribeRealtimeOptions): Promise<{
|
|
84
|
+
/** Stop the realtime transcribe */
|
|
85
|
+
stop: () => void;
|
|
86
|
+
/** Subscribe to realtime transcribe events */
|
|
87
|
+
subscribe: (callback: (event: TranscribeRealtimeEvent) => void) => void;
|
|
88
|
+
}>;
|
|
30
89
|
release(): Promise<any>;
|
|
31
90
|
}
|
|
32
91
|
export declare function initWhisper({ filePath }?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"
|
|
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.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React Native binding of whisper.cpp",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"speech recognition"
|
|
48
48
|
],
|
|
49
49
|
"repository": "https://github.com/mybigday/whisper.rn",
|
|
50
|
-
"author": "Jhen <developer@jhen.me>
|
|
50
|
+
"author": "Jhen-Jie Hong <developer@jhen.me>",
|
|
51
51
|
"license": "MIT",
|
|
52
52
|
"bugs": {
|
|
53
53
|
"url": "https://github.com/mybigday/whisper.rn/issues"
|