@fugood/node-whisper-wasm 1.0.19
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/README.md +40 -0
- package/index.d.ts +183 -0
- package/index.js +1250 -0
- package/package.json +46 -0
- package/whisper-node.js +2 -0
- package/whisper-node.wasm +0 -0
- package/worker.js +255 -0
package/worker.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
(function (root) {
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
var api = null
|
|
5
|
+
var nextContextId = 1
|
|
6
|
+
var contexts = Object.create(null)
|
|
7
|
+
var activeStops = Object.create(null)
|
|
8
|
+
var cancelledRequests = Object.create(null)
|
|
9
|
+
|
|
10
|
+
function resolveUrl(value, base) {
|
|
11
|
+
return new URL(value, base || root.location.href).href
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function serializeError(error) {
|
|
15
|
+
return {
|
|
16
|
+
message: error && error.message ? error.message : String(error),
|
|
17
|
+
stack: error && error.stack ? error.stack : undefined,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function postResponse(id, result) {
|
|
22
|
+
root.postMessage({
|
|
23
|
+
type: 'response',
|
|
24
|
+
id: id,
|
|
25
|
+
result: result,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function postError(id, error) {
|
|
30
|
+
root.postMessage({
|
|
31
|
+
type: 'response',
|
|
32
|
+
id: id,
|
|
33
|
+
error: serializeError(error),
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function postCallback(id, name, value) {
|
|
38
|
+
root.postMessage({
|
|
39
|
+
type: 'callback',
|
|
40
|
+
id: id,
|
|
41
|
+
name: name,
|
|
42
|
+
value: value,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getContext(id, type) {
|
|
47
|
+
var entry = contexts[id]
|
|
48
|
+
if (!entry || entry.type !== type) {
|
|
49
|
+
throw new Error('Invalid ' + type + ' context')
|
|
50
|
+
}
|
|
51
|
+
return entry.context
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function abortedResult() {
|
|
55
|
+
return {
|
|
56
|
+
result: '',
|
|
57
|
+
segments: [],
|
|
58
|
+
isAborted: true,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function inflateTranscribeOptions(requestId, options) {
|
|
63
|
+
var inflated = Object.assign({}, options || {})
|
|
64
|
+
|
|
65
|
+
if (inflated.onProgress) {
|
|
66
|
+
inflated.onProgress = function (progress) {
|
|
67
|
+
if (!cancelledRequests[requestId]) {
|
|
68
|
+
postCallback(requestId, 'onProgress', progress)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (inflated.onNewSegments) {
|
|
74
|
+
inflated.onNewSegments = function (result) {
|
|
75
|
+
if (!cancelledRequests[requestId]) {
|
|
76
|
+
postCallback(requestId, 'onNewSegments', result)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return inflated
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function ensureApi(config) {
|
|
85
|
+
if (api) {
|
|
86
|
+
return api
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
config = config || {}
|
|
90
|
+
var indexScriptUrl = resolveUrl(config.indexScriptUrl || 'index.js')
|
|
91
|
+
var runtimeScriptUrl = resolveUrl(
|
|
92
|
+
config.runtimeScriptUrl || 'whisper-node.js',
|
|
93
|
+
indexScriptUrl,
|
|
94
|
+
)
|
|
95
|
+
var locateFileBaseUrl =
|
|
96
|
+
config.locateFileBaseUrl || resolveUrl('.', runtimeScriptUrl)
|
|
97
|
+
|
|
98
|
+
root.importScripts(runtimeScriptUrl)
|
|
99
|
+
root.importScripts(indexScriptUrl)
|
|
100
|
+
|
|
101
|
+
api = root.WhisperNodeWasm
|
|
102
|
+
if (!api) {
|
|
103
|
+
throw new Error('Failed to load WhisperNodeWasm in worker')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
var runtimeOptions = Object.assign({}, config.runtimeOptions || {})
|
|
107
|
+
runtimeOptions.mainScriptUrlOrBlob = runtimeScriptUrl
|
|
108
|
+
runtimeOptions.locateFile = function (path, prefix) {
|
|
109
|
+
return resolveUrl(path, locateFileBaseUrl || prefix)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
api.configureWasm(runtimeOptions)
|
|
113
|
+
api.addNativeLogListener(function (level, text) {
|
|
114
|
+
root.postMessage({
|
|
115
|
+
type: 'log',
|
|
116
|
+
level: level,
|
|
117
|
+
text: text,
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
await api.toggleNativeLog(true)
|
|
121
|
+
|
|
122
|
+
return api
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function runTranscribeOperation(requestId, operation) {
|
|
126
|
+
activeStops[requestId] = operation.stop
|
|
127
|
+
try {
|
|
128
|
+
var result = await operation.promise
|
|
129
|
+
if (cancelledRequests[requestId]) {
|
|
130
|
+
result.isAborted = true
|
|
131
|
+
}
|
|
132
|
+
return result
|
|
133
|
+
} finally {
|
|
134
|
+
delete activeStops[requestId]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function dispatch(message) {
|
|
139
|
+
var args = message.args || []
|
|
140
|
+
|
|
141
|
+
switch (message.method) {
|
|
142
|
+
case '__init':
|
|
143
|
+
await ensureApi(args[0])
|
|
144
|
+
return { ok: true }
|
|
145
|
+
|
|
146
|
+
case 'initWhisper': {
|
|
147
|
+
var whisper = await api.initWhisper(args[0] || {})
|
|
148
|
+
var whisperId = nextContextId++
|
|
149
|
+
contexts[whisperId] = {
|
|
150
|
+
type: 'whisper',
|
|
151
|
+
context: whisper,
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
id: whisperId,
|
|
155
|
+
meta: whisper.getModelInfo(),
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
case 'transcribeData': {
|
|
160
|
+
if (cancelledRequests[message.id]) {
|
|
161
|
+
return abortedResult()
|
|
162
|
+
}
|
|
163
|
+
var whisperDataContext = getContext(args[0], 'whisper')
|
|
164
|
+
var transcribeDataOptions = inflateTranscribeOptions(message.id, args[2])
|
|
165
|
+
return runTranscribeOperation(
|
|
166
|
+
message.id,
|
|
167
|
+
whisperDataContext.transcribeData(args[1], transcribeDataOptions),
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
case 'transcribeFile': {
|
|
172
|
+
if (cancelledRequests[message.id]) {
|
|
173
|
+
return abortedResult()
|
|
174
|
+
}
|
|
175
|
+
var whisperFileContext = getContext(args[0], 'whisper')
|
|
176
|
+
var transcribeFileOptions = inflateTranscribeOptions(message.id, args[2])
|
|
177
|
+
return runTranscribeOperation(
|
|
178
|
+
message.id,
|
|
179
|
+
whisperFileContext.transcribeFile(args[1], transcribeFileOptions),
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
case 'benchWhisper':
|
|
184
|
+
return getContext(args[0], 'whisper').bench(args[1] || 1)
|
|
185
|
+
|
|
186
|
+
case 'releaseWhisper':
|
|
187
|
+
await getContext(args[0], 'whisper').release()
|
|
188
|
+
delete contexts[args[0]]
|
|
189
|
+
return { ok: true }
|
|
190
|
+
|
|
191
|
+
case 'initWhisperVad': {
|
|
192
|
+
var vad = await api.initWhisperVad(args[0] || {})
|
|
193
|
+
var vadId = nextContextId++
|
|
194
|
+
contexts[vadId] = {
|
|
195
|
+
type: 'vad',
|
|
196
|
+
context: vad,
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
id: vadId,
|
|
200
|
+
meta: vad.getModelInfo(),
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
case 'detectSpeechData':
|
|
205
|
+
return getContext(args[0], 'vad').detectSpeechData(args[1], args[2] || {})
|
|
206
|
+
|
|
207
|
+
case 'detectSpeechFile':
|
|
208
|
+
return getContext(args[0], 'vad').detectSpeechFile(args[1], args[2] || {})
|
|
209
|
+
|
|
210
|
+
case 'releaseVad':
|
|
211
|
+
await getContext(args[0], 'vad').release()
|
|
212
|
+
delete contexts[args[0]]
|
|
213
|
+
return { ok: true }
|
|
214
|
+
|
|
215
|
+
default:
|
|
216
|
+
throw new Error('Unknown WASM worker method: ' + message.method)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
root.onmessage = function (event) {
|
|
221
|
+
var message = event.data || {}
|
|
222
|
+
|
|
223
|
+
if (message.type === 'cancel') {
|
|
224
|
+
cancelledRequests[message.id] = true
|
|
225
|
+
if (activeStops[message.id]) {
|
|
226
|
+
Promise.resolve(activeStops[message.id]()).catch(function () {})
|
|
227
|
+
}
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (message.type !== 'request') {
|
|
232
|
+
return
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
Promise.resolve()
|
|
236
|
+
.then(function () {
|
|
237
|
+
return dispatch(message)
|
|
238
|
+
})
|
|
239
|
+
.then(function (result) {
|
|
240
|
+
postResponse(message.id, result)
|
|
241
|
+
})
|
|
242
|
+
.catch(function (error) {
|
|
243
|
+
postError(message.id, error)
|
|
244
|
+
})
|
|
245
|
+
.finally(function () {
|
|
246
|
+
delete cancelledRequests[message.id]
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
})(
|
|
250
|
+
typeof self !== 'undefined'
|
|
251
|
+
? self
|
|
252
|
+
: typeof globalThis !== 'undefined'
|
|
253
|
+
? globalThis
|
|
254
|
+
: this,
|
|
255
|
+
)
|