@fugood/node-whisper-wasm 1.0.19 → 1.0.21
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 -19
- package/index.d.ts +26 -0
- package/index.js +332 -75
- package/package.json +7 -4
- package/wasm/whisper-node.js +2 -0
- package/wasm/whisper-node.threads.js +2 -0
- package/{whisper-node.wasm → wasm/whisper-node.threads.wasm} +0 -0
- package/wasm/whisper-node.wasm +0 -0
- package/worker.js +13 -11
- package/whisper-node.js +0 -2
package/index.js
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory(function () {
|
|
4
|
-
return require('./whisper-node.js')
|
|
5
|
-
}, root)
|
|
6
|
-
} else {
|
|
7
|
-
root.WhisperNodeWasm = factory(function () {
|
|
8
|
-
return root.createWhisperNodeModule
|
|
9
|
-
}, root)
|
|
10
|
-
}
|
|
11
|
-
})(
|
|
1
|
+
const root =
|
|
12
2
|
typeof globalThis !== 'undefined'
|
|
13
3
|
? globalThis
|
|
14
4
|
: typeof self !== 'undefined'
|
|
15
5
|
? self
|
|
16
6
|
: typeof window !== 'undefined'
|
|
17
7
|
? window
|
|
18
|
-
:
|
|
19
|
-
|
|
8
|
+
: undefined
|
|
9
|
+
|
|
10
|
+
export const WASM_CONFIG_PATHS = {
|
|
11
|
+
index: new URL('./index.js', import.meta.url).href,
|
|
12
|
+
js: new URL('./wasm/whisper-node.js', import.meta.url).href,
|
|
13
|
+
wasm: new URL('./wasm/whisper-node.wasm', import.meta.url).href,
|
|
14
|
+
threadsJs: new URL('./wasm/whisper-node.threads.js', import.meta.url).href,
|
|
15
|
+
threadsWasm: new URL('./wasm/whisper-node.threads.wasm', import.meta.url).href,
|
|
16
|
+
worker: new URL('./worker.js', import.meta.url).href,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const createWhisperNodeApi = function (root) {
|
|
20
20
|
'use strict'
|
|
21
21
|
|
|
22
22
|
var SAMPLE_RATE = 16000
|
|
23
23
|
var MIB = 1024 * 1024
|
|
24
24
|
var FIREFOX_MODEL_LIMIT_BYTES = 256 * MIB
|
|
25
25
|
var MODEL_MEMORY_RATIO = 0.75
|
|
26
|
+
var MAX_WASM_THREADS = 8
|
|
27
|
+
var DEFAULT_MODEL_CACHE_NAME = 'whisper.node.wasm.models'
|
|
26
28
|
|
|
27
29
|
var runtimePromise = null
|
|
28
30
|
var runtimeOptions = {}
|
|
29
31
|
var workerProxyPromise = null
|
|
30
|
-
var capturedScriptUrl =
|
|
32
|
+
var capturedScriptUrl = WASM_CONFIG_PATHS.index
|
|
31
33
|
var modelCache = Object.create(null)
|
|
32
34
|
var logEnabled = false
|
|
33
35
|
var logListeners = []
|
|
@@ -40,19 +42,8 @@
|
|
|
40
42
|
runtimeOptions = Object.assign({}, runtimeOptions, options || {})
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
function getCurrentScriptUrl() {
|
|
44
|
-
if (
|
|
45
|
-
root.document &&
|
|
46
|
-
root.document.currentScript &&
|
|
47
|
-
root.document.currentScript.src
|
|
48
|
-
) {
|
|
49
|
-
return root.document.currentScript.src
|
|
50
|
-
}
|
|
51
|
-
return null
|
|
52
|
-
}
|
|
53
|
-
|
|
54
45
|
function isBrowserLike() {
|
|
55
|
-
return typeof root.window !== 'undefined' || typeof root.
|
|
46
|
+
return typeof root.window !== 'undefined' || typeof root.WorkerGlobalScope !== 'undefined'
|
|
56
47
|
}
|
|
57
48
|
|
|
58
49
|
function isMainBrowserThread() {
|
|
@@ -79,20 +70,47 @@
|
|
|
79
70
|
return capturedScriptUrl
|
|
80
71
|
}
|
|
81
72
|
|
|
82
|
-
function
|
|
83
|
-
|
|
73
|
+
function isWasmThreadsSupported() {
|
|
74
|
+
if (!isBrowserLike()) {
|
|
75
|
+
return true
|
|
76
|
+
}
|
|
77
|
+
return (
|
|
78
|
+
typeof root.SharedArrayBuffer !== 'undefined' &&
|
|
79
|
+
typeof root.Atomics !== 'undefined' &&
|
|
80
|
+
typeof root.crossOriginIsolated !== 'undefined' &&
|
|
81
|
+
root.crossOriginIsolated === true
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function shouldUseThreadedRuntime() {
|
|
86
|
+
if (typeof runtimeOptions.__resolvedThreads === 'boolean') {
|
|
87
|
+
return runtimeOptions.__resolvedThreads
|
|
88
|
+
}
|
|
89
|
+
return runtimeOptions.threads !== false && isWasmThreadsSupported()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getRuntimeScriptUrl(indexScriptUrl, useThreads) {
|
|
93
|
+
var configured = runtimeOptions.jsPath || runtimeOptions.runtimeScriptUrl
|
|
84
94
|
if (configured) {
|
|
85
95
|
return resolveUrl(configured, indexScriptUrl)
|
|
86
96
|
}
|
|
87
|
-
return
|
|
97
|
+
return useThreads ? WASM_CONFIG_PATHS.threadsJs : WASM_CONFIG_PATHS.js
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getWasmBinaryUrl(runtimeScriptUrl, useThreads) {
|
|
101
|
+
var configured = runtimeOptions.wasmPath
|
|
102
|
+
if (configured) {
|
|
103
|
+
return resolveUrl(configured, runtimeScriptUrl)
|
|
104
|
+
}
|
|
105
|
+
return useThreads ? WASM_CONFIG_PATHS.threadsWasm : WASM_CONFIG_PATHS.wasm
|
|
88
106
|
}
|
|
89
107
|
|
|
90
108
|
function getWorkerScriptUrl(indexScriptUrl) {
|
|
91
|
-
var configured = runtimeOptions.workerUrl
|
|
109
|
+
var configured = runtimeOptions.workerPath || runtimeOptions.workerUrl
|
|
92
110
|
if (configured) {
|
|
93
111
|
return resolveUrl(configured, indexScriptUrl)
|
|
94
112
|
}
|
|
95
|
-
return
|
|
113
|
+
return WASM_CONFIG_PATHS.worker
|
|
96
114
|
}
|
|
97
115
|
|
|
98
116
|
function shouldUseWorker(options) {
|
|
@@ -108,11 +126,18 @@
|
|
|
108
126
|
var blocked = {
|
|
109
127
|
worker: true,
|
|
110
128
|
workerUrl: true,
|
|
129
|
+
workerPath: true,
|
|
111
130
|
indexScriptUrl: true,
|
|
112
131
|
scriptUrl: true,
|
|
113
132
|
runtimeScriptUrl: true,
|
|
133
|
+
jsPath: true,
|
|
134
|
+
wasmPath: true,
|
|
135
|
+
threads: true,
|
|
136
|
+
__resolvedThreads: true,
|
|
114
137
|
locateFileBaseUrl: true,
|
|
115
138
|
locateFile: true,
|
|
139
|
+
moduleFactory: true,
|
|
140
|
+
moduleOptions: true,
|
|
116
141
|
print: true,
|
|
117
142
|
printErr: true,
|
|
118
143
|
mainScriptUrlOrBlob: true,
|
|
@@ -127,14 +152,6 @@
|
|
|
127
152
|
return options
|
|
128
153
|
}
|
|
129
154
|
|
|
130
|
-
function assertThreadSupport() {
|
|
131
|
-
if (isBrowserLike() && typeof root.SharedArrayBuffer === 'undefined') {
|
|
132
|
-
throw new Error(
|
|
133
|
-
'whisper.node WASM is built with pthreads and requires SharedArrayBuffer. Serve the page with COOP/COEP headers so the browser is cross-origin isolated.',
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
155
|
function emitLog(level, text) {
|
|
139
156
|
if (!logEnabled) {
|
|
140
157
|
return
|
|
@@ -149,37 +166,79 @@
|
|
|
149
166
|
|
|
150
167
|
function loadRuntime() {
|
|
151
168
|
if (!runtimePromise) {
|
|
152
|
-
|
|
169
|
+
runtimePromise = (async function () {
|
|
170
|
+
var indexScriptUrl = getIndexScriptUrl()
|
|
171
|
+
var useThreads = shouldUseThreadedRuntime()
|
|
172
|
+
var runtimeScriptUrl = getRuntimeScriptUrl(indexScriptUrl, useThreads)
|
|
173
|
+
var wasmUrl = getWasmBinaryUrl(runtimeScriptUrl, useThreads)
|
|
174
|
+
var moduleFactory = runtimeOptions.moduleFactory
|
|
175
|
+
|
|
176
|
+
if (!moduleFactory) {
|
|
177
|
+
var runtimeModule = await import(runtimeScriptUrl)
|
|
178
|
+
moduleFactory =
|
|
179
|
+
runtimeModule.default ||
|
|
180
|
+
runtimeModule.createWhisperNodeModule ||
|
|
181
|
+
runtimeModule
|
|
182
|
+
}
|
|
183
|
+
if (typeof moduleFactory !== 'function') {
|
|
184
|
+
throw new Error(
|
|
185
|
+
'Failed to load whisper.node WASM runtime. Make sure the selected wasm/whisper-node*.js artifact is built and included in the package.',
|
|
186
|
+
)
|
|
187
|
+
}
|
|
153
188
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (typeof moduleFactory !== 'function') {
|
|
159
|
-
throw new Error(
|
|
160
|
-
'Failed to load whisper.node WASM runtime. Make sure whisper-node.js is built and loaded before index.js.',
|
|
189
|
+
var options = Object.assign(
|
|
190
|
+
{},
|
|
191
|
+
runtimeOptions.moduleOptions || {},
|
|
192
|
+
runtimeOptions,
|
|
161
193
|
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
194
|
+
var userPrint = options.print
|
|
195
|
+
var userPrintErr = options.printErr
|
|
196
|
+
var userLocateFile = options.locateFile
|
|
197
|
+
var locateFileBaseUrl =
|
|
198
|
+
options.locateFileBaseUrl || resolveUrl('.', runtimeScriptUrl)
|
|
199
|
+
|
|
200
|
+
delete options.moduleFactory
|
|
201
|
+
delete options.moduleOptions
|
|
202
|
+
delete options.worker
|
|
203
|
+
delete options.workerUrl
|
|
204
|
+
delete options.workerPath
|
|
205
|
+
delete options.indexScriptUrl
|
|
206
|
+
delete options.scriptUrl
|
|
207
|
+
delete options.runtimeScriptUrl
|
|
208
|
+
delete options.jsPath
|
|
209
|
+
delete options.wasmPath
|
|
210
|
+
delete options.threads
|
|
211
|
+
delete options.__resolvedThreads
|
|
212
|
+
delete options.locateFileBaseUrl
|
|
213
|
+
|
|
214
|
+
options.noInitialRun = true
|
|
215
|
+
options.mainScriptUrlOrBlob = options.mainScriptUrlOrBlob || runtimeScriptUrl
|
|
216
|
+
options.locateFile = function (path, prefix) {
|
|
217
|
+
if (path === 'whisper-node.wasm' || path.slice(-5) === '.wasm') {
|
|
218
|
+
return wasmUrl
|
|
219
|
+
}
|
|
220
|
+
if (typeof userLocateFile === 'function') {
|
|
221
|
+
return userLocateFile(path, prefix)
|
|
222
|
+
}
|
|
223
|
+
return resolveUrl(path, locateFileBaseUrl || prefix)
|
|
173
224
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
225
|
+
options.print = function (text) {
|
|
226
|
+
emitLog('INFO', String(text))
|
|
227
|
+
if (typeof userPrint === 'function') {
|
|
228
|
+
userPrint(text)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
options.printErr = function (text) {
|
|
232
|
+
emitLog('ERROR', String(text))
|
|
233
|
+
if (typeof userPrintErr === 'function') {
|
|
234
|
+
userPrintErr(text)
|
|
235
|
+
}
|
|
179
236
|
}
|
|
180
|
-
}
|
|
181
237
|
|
|
182
|
-
|
|
238
|
+
var runtime = await moduleFactory(options)
|
|
239
|
+
runtime.__whisperNodeWasmThreads = useThreads
|
|
240
|
+
return runtime
|
|
241
|
+
})()
|
|
183
242
|
}
|
|
184
243
|
|
|
185
244
|
return runtimePromise
|
|
@@ -212,7 +271,9 @@
|
|
|
212
271
|
|
|
213
272
|
function createWorkerProxy() {
|
|
214
273
|
var indexScriptUrl = getIndexScriptUrl()
|
|
215
|
-
var
|
|
274
|
+
var useThreads = shouldUseThreadedRuntime()
|
|
275
|
+
var runtimeScriptUrl = getRuntimeScriptUrl(indexScriptUrl, useThreads)
|
|
276
|
+
var wasmUrl = getWasmBinaryUrl(runtimeScriptUrl, useThreads)
|
|
216
277
|
var workerScriptUrl = getWorkerScriptUrl(indexScriptUrl)
|
|
217
278
|
|
|
218
279
|
if (!indexScriptUrl || !runtimeScriptUrl || !workerScriptUrl) {
|
|
@@ -220,6 +281,7 @@
|
|
|
220
281
|
}
|
|
221
282
|
|
|
222
283
|
var worker = new root.Worker(workerScriptUrl, {
|
|
284
|
+
type: 'module',
|
|
223
285
|
name: 'whisper.node.wasm',
|
|
224
286
|
})
|
|
225
287
|
var proxy = {
|
|
@@ -323,6 +385,8 @@
|
|
|
323
385
|
{
|
|
324
386
|
indexScriptUrl: indexScriptUrl,
|
|
325
387
|
runtimeScriptUrl: runtimeScriptUrl,
|
|
388
|
+
wasmPath: wasmUrl,
|
|
389
|
+
threads: useThreads,
|
|
326
390
|
runtimeOptions: getWorkerRuntimeOptions(),
|
|
327
391
|
locateFileBaseUrl:
|
|
328
392
|
runtimeOptions.locateFileBaseUrl || resolveUrl('.', runtimeScriptUrl),
|
|
@@ -366,6 +430,39 @@
|
|
|
366
430
|
throw new Error('fetch is required to load models or audio by URL')
|
|
367
431
|
}
|
|
368
432
|
|
|
433
|
+
function getCacheStorage() {
|
|
434
|
+
return root.caches || null
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function isModelCacheEnabled(options) {
|
|
438
|
+
return !options || options.cacheModel !== false
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function getModelCacheName(options) {
|
|
442
|
+
return (
|
|
443
|
+
(options && options.modelCacheName) ||
|
|
444
|
+
runtimeOptions.modelCacheName ||
|
|
445
|
+
DEFAULT_MODEL_CACHE_NAME
|
|
446
|
+
)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function getModelCacheKey(source, options) {
|
|
450
|
+
var key = (options && options.modelCacheKey) || source
|
|
451
|
+
try {
|
|
452
|
+
return new URL(key, root.location && root.location.href).href
|
|
453
|
+
} catch (_) {
|
|
454
|
+
return key
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function canUseModelCache(options) {
|
|
459
|
+
return (
|
|
460
|
+
isModelCacheEnabled(options) &&
|
|
461
|
+
!!getCacheStorage() &&
|
|
462
|
+
typeof root.Response === 'function'
|
|
463
|
+
)
|
|
464
|
+
}
|
|
465
|
+
|
|
369
466
|
function formatBytes(bytes) {
|
|
370
467
|
if (bytes >= 1024 * MIB) {
|
|
371
468
|
return (bytes / (1024 * MIB)).toFixed(2) + ' GiB'
|
|
@@ -497,6 +594,106 @@
|
|
|
497
594
|
return buffer
|
|
498
595
|
}
|
|
499
596
|
|
|
597
|
+
async function readCachedModel(source, limit, options) {
|
|
598
|
+
if (!canUseModelCache(options)) {
|
|
599
|
+
return null
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
var cacheName = getModelCacheName(options)
|
|
603
|
+
var cacheKey = getModelCacheKey(source, options)
|
|
604
|
+
|
|
605
|
+
try {
|
|
606
|
+
var cache = await getCacheStorage().open(cacheName)
|
|
607
|
+
var response = await cache.match(cacheKey)
|
|
608
|
+
if (!response) {
|
|
609
|
+
return null
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
var buffer = await response.arrayBuffer()
|
|
613
|
+
if (limit) {
|
|
614
|
+
assertModelSize(buffer.byteLength, limit, source)
|
|
615
|
+
}
|
|
616
|
+
emitLog('INFO', 'Loaded cached WASM model: ' + source)
|
|
617
|
+
return {
|
|
618
|
+
buffer: buffer,
|
|
619
|
+
cacheHit: true,
|
|
620
|
+
cacheStored: false,
|
|
621
|
+
cacheName: cacheName,
|
|
622
|
+
cacheKey: cacheKey,
|
|
623
|
+
}
|
|
624
|
+
} catch (error) {
|
|
625
|
+
emitLog(
|
|
626
|
+
'WARN',
|
|
627
|
+
'Failed to read cached WASM model ' +
|
|
628
|
+
source +
|
|
629
|
+
': ' +
|
|
630
|
+
(error && error.message ? error.message : String(error)),
|
|
631
|
+
)
|
|
632
|
+
return null
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
async function writeCachedModel(source, buffer, options) {
|
|
637
|
+
if (!canUseModelCache(options)) {
|
|
638
|
+
return {
|
|
639
|
+
cacheStored: false,
|
|
640
|
+
cacheName: null,
|
|
641
|
+
cacheKey: null,
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
var cacheName = getModelCacheName(options)
|
|
646
|
+
var cacheKey = getModelCacheKey(source, options)
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
var cache = await getCacheStorage().open(cacheName)
|
|
650
|
+
await cache.put(
|
|
651
|
+
cacheKey,
|
|
652
|
+
new root.Response(buffer.slice(0), {
|
|
653
|
+
headers: {
|
|
654
|
+
'content-type': 'application/octet-stream',
|
|
655
|
+
},
|
|
656
|
+
}),
|
|
657
|
+
)
|
|
658
|
+
emitLog('INFO', 'Cached WASM model download: ' + source)
|
|
659
|
+
return {
|
|
660
|
+
cacheStored: true,
|
|
661
|
+
cacheName: cacheName,
|
|
662
|
+
cacheKey: cacheKey,
|
|
663
|
+
}
|
|
664
|
+
} catch (error) {
|
|
665
|
+
emitLog(
|
|
666
|
+
'WARN',
|
|
667
|
+
'Failed to cache WASM model ' +
|
|
668
|
+
source +
|
|
669
|
+
': ' +
|
|
670
|
+
(error && error.message ? error.message : String(error)),
|
|
671
|
+
)
|
|
672
|
+
return {
|
|
673
|
+
cacheStored: false,
|
|
674
|
+
cacheName: cacheName,
|
|
675
|
+
cacheKey: cacheKey,
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
async function fetchModelArrayBuffer(source, limit, options) {
|
|
681
|
+
var cached = await readCachedModel(source, limit, options)
|
|
682
|
+
if (cached) {
|
|
683
|
+
return cached
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
var buffer = await fetchArrayBuffer(source, limit)
|
|
687
|
+
var cache = await writeCachedModel(source, buffer, options)
|
|
688
|
+
return {
|
|
689
|
+
buffer: buffer,
|
|
690
|
+
cacheHit: false,
|
|
691
|
+
cacheStored: cache.cacheStored,
|
|
692
|
+
cacheName: cache.cacheName,
|
|
693
|
+
cacheKey: cache.cacheKey,
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
500
697
|
async function ensureModel(runtime, source, kind, options) {
|
|
501
698
|
if (!source) {
|
|
502
699
|
throw new Error('Model path is required')
|
|
@@ -510,8 +707,8 @@
|
|
|
510
707
|
if (!modelCache[cacheKey]) {
|
|
511
708
|
modelCache[cacheKey] = (async function () {
|
|
512
709
|
var limit = getModelSizeLimit(runtime, options)
|
|
513
|
-
var
|
|
514
|
-
var bytes = new Uint8Array(buffer)
|
|
710
|
+
var loaded = await fetchModelArrayBuffer(source, limit, options)
|
|
711
|
+
var bytes = new Uint8Array(loaded.buffer)
|
|
515
712
|
var virtualPath =
|
|
516
713
|
'/models/' + kind + '-' + hashString(source) + '-' + basenameFromUrl(source)
|
|
517
714
|
|
|
@@ -521,6 +718,10 @@
|
|
|
521
718
|
return {
|
|
522
719
|
virtualPath: virtualPath,
|
|
523
720
|
bytes: bytes.byteLength,
|
|
721
|
+
cacheHit: loaded.cacheHit,
|
|
722
|
+
cacheStored: loaded.cacheStored,
|
|
723
|
+
cacheName: loaded.cacheName,
|
|
724
|
+
cacheKey: loaded.cacheKey,
|
|
524
725
|
}
|
|
525
726
|
})()
|
|
526
727
|
}
|
|
@@ -562,8 +763,31 @@
|
|
|
562
763
|
return value
|
|
563
764
|
}
|
|
564
765
|
|
|
565
|
-
function
|
|
766
|
+
function normalizeMaxThreads(value, runtime) {
|
|
767
|
+
var maxThreads =
|
|
768
|
+
runtime && runtime.__whisperNodeWasmThreads !== true
|
|
769
|
+
? 1
|
|
770
|
+
: MAX_WASM_THREADS
|
|
771
|
+
var nThreads = Number(value)
|
|
772
|
+
if (!Number.isFinite(nThreads) || nThreads <= 0) {
|
|
773
|
+
return null
|
|
774
|
+
}
|
|
775
|
+
return Math.max(1, Math.min(maxThreads, Math.floor(nThreads)))
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
function normalizeThreadOptions(options, runtime) {
|
|
566
779
|
var normalized = Object.assign({}, options || {})
|
|
780
|
+
var maxThreads = normalizeMaxThreads(normalized.maxThreads, runtime)
|
|
781
|
+
if (maxThreads) {
|
|
782
|
+
normalized.maxThreads = maxThreads
|
|
783
|
+
} else {
|
|
784
|
+
delete normalized.maxThreads
|
|
785
|
+
}
|
|
786
|
+
return normalized
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
function normalizeTranscribeOptions(options, runtime) {
|
|
790
|
+
var normalized = normalizeThreadOptions(options, runtime)
|
|
567
791
|
if (typeof normalized.onProgress !== 'function') {
|
|
568
792
|
delete normalized.onProgress
|
|
569
793
|
}
|
|
@@ -574,7 +798,7 @@
|
|
|
574
798
|
}
|
|
575
799
|
|
|
576
800
|
function splitTranscribeOptions(options) {
|
|
577
|
-
var normalized =
|
|
801
|
+
var normalized = normalizeThreadOptions(options)
|
|
578
802
|
var callbacks = {}
|
|
579
803
|
|
|
580
804
|
if (typeof normalized.onProgress === 'function') {
|
|
@@ -966,6 +1190,10 @@
|
|
|
966
1190
|
useGpu: useGpu,
|
|
967
1191
|
useFlashAttn: options.useFlashAttn === true,
|
|
968
1192
|
bytes: model.bytes,
|
|
1193
|
+
cacheHit: model.cacheHit,
|
|
1194
|
+
cacheStored: model.cacheStored,
|
|
1195
|
+
cacheName: model.cacheName,
|
|
1196
|
+
cacheKey: model.cacheKey,
|
|
969
1197
|
wasm: true,
|
|
970
1198
|
})
|
|
971
1199
|
}
|
|
@@ -1005,7 +1233,7 @@
|
|
|
1005
1233
|
await runtime.__wasm_transcribe(
|
|
1006
1234
|
id,
|
|
1007
1235
|
audio,
|
|
1008
|
-
normalizeTranscribeOptions(options),
|
|
1236
|
+
normalizeTranscribeOptions(options, runtime),
|
|
1009
1237
|
),
|
|
1010
1238
|
)
|
|
1011
1239
|
if (isCancelled && isCancelled()) {
|
|
@@ -1054,7 +1282,8 @@
|
|
|
1054
1282
|
|
|
1055
1283
|
WhisperContextInstance.prototype.bench = async function (nThreads) {
|
|
1056
1284
|
this._assertValid()
|
|
1057
|
-
|
|
1285
|
+
var threads = normalizeMaxThreads(nThreads || 1, this._runtime) || 1
|
|
1286
|
+
return unwrapWasmResult(await this._runtime.__wasm_bench(this._id, threads))
|
|
1058
1287
|
}
|
|
1059
1288
|
|
|
1060
1289
|
WhisperContextInstance.prototype.release = function () {
|
|
@@ -1148,7 +1377,7 @@
|
|
|
1148
1377
|
var modelSource = options.filePath || options.modelUrl
|
|
1149
1378
|
var runtime = await loadRuntime()
|
|
1150
1379
|
var useGpu = false
|
|
1151
|
-
var nThreads = options.nThreads || 1
|
|
1380
|
+
var nThreads = normalizeMaxThreads(options.nThreads || 1, runtime) || 1
|
|
1152
1381
|
|
|
1153
1382
|
if (options.useGpu === true) {
|
|
1154
1383
|
emitLog(
|
|
@@ -1168,6 +1397,10 @@
|
|
|
1168
1397
|
useGpu: useGpu,
|
|
1169
1398
|
nThreads: init.nThreads,
|
|
1170
1399
|
bytes: model.bytes,
|
|
1400
|
+
cacheHit: model.cacheHit,
|
|
1401
|
+
cacheStored: model.cacheStored,
|
|
1402
|
+
cacheName: model.cacheName,
|
|
1403
|
+
cacheKey: model.cacheKey,
|
|
1171
1404
|
wasm: true,
|
|
1172
1405
|
})
|
|
1173
1406
|
}
|
|
@@ -1240,11 +1473,35 @@
|
|
|
1240
1473
|
initWhisperVad: initWhisperVad,
|
|
1241
1474
|
toggleNativeLog: toggleNativeLog,
|
|
1242
1475
|
addNativeLogListener: addNativeLogListener,
|
|
1476
|
+
isWasmThreadsSupported: isWasmThreadsSupported,
|
|
1243
1477
|
DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES: 1500 * MIB,
|
|
1478
|
+
MAX_WASM_THREADS: MAX_WASM_THREADS,
|
|
1479
|
+
WASM_CONFIG_PATHS: WASM_CONFIG_PATHS,
|
|
1244
1480
|
}
|
|
1245
1481
|
|
|
1246
1482
|
api.default = api
|
|
1247
1483
|
|
|
1248
1484
|
return api
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
const api = createWhisperNodeApi(root)
|
|
1488
|
+
|
|
1489
|
+
export const WhisperContext = api.WhisperContext
|
|
1490
|
+
export const WhisperVadContext = api.WhisperVadContext
|
|
1491
|
+
export const DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES =
|
|
1492
|
+
api.DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES
|
|
1493
|
+
export const MAX_WASM_THREADS = api.MAX_WASM_THREADS
|
|
1494
|
+
export const configureWasm = api.configureWasm
|
|
1495
|
+
export const loadWasmModule = api.loadWasmModule
|
|
1496
|
+
export const loadWhisperModule = api.loadWhisperModule
|
|
1497
|
+
export const initWhisper = api.initWhisper
|
|
1498
|
+
export const initWhisperVad = api.initWhisperVad
|
|
1499
|
+
export const toggleNativeLog = api.toggleNativeLog
|
|
1500
|
+
export const addNativeLogListener = api.addNativeLogListener
|
|
1501
|
+
export const isWasmThreadsSupported = api.isWasmThreadsSupported
|
|
1502
|
+
|
|
1503
|
+
if (root) {
|
|
1504
|
+
root.WhisperNodeWasm = api
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
export default api
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/node-whisper-wasm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "Browser WASM module for whisper.node",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "index.js",
|
|
6
7
|
"browser": "index.js",
|
|
7
8
|
"types": "index.d.ts",
|
|
@@ -39,8 +40,10 @@
|
|
|
39
40
|
"index.js",
|
|
40
41
|
"index.d.ts",
|
|
41
42
|
"README.md",
|
|
42
|
-
"whisper-node.js",
|
|
43
43
|
"worker.js",
|
|
44
|
-
"whisper-node.
|
|
44
|
+
"wasm/whisper-node.js",
|
|
45
|
+
"wasm/whisper-node.wasm",
|
|
46
|
+
"wasm/whisper-node.threads.js",
|
|
47
|
+
"wasm/whisper-node.threads.wasm"
|
|
45
48
|
]
|
|
46
|
-
}
|
|
49
|
+
}
|