@sridhar-mani/whisper-web-transcriber 0.1.0 → 0.3.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.
@@ -91,7 +91,16 @@ Current Status:
91
91
  return 'Cross-Origin Isolation is already enabled! No action needed.';
92
92
  }
93
93
  getScriptBasePath() {
94
- // Always use local src/ directory for all assets
94
+ var _a;
95
+ try {
96
+ const chromeRuntime = (_a = window.chrome) === null || _a === void 0 ? void 0 : _a.runtime;
97
+ if (chromeRuntime && typeof chromeRuntime.getURL === 'function') {
98
+ return chromeRuntime.getURL('whisper-assets/');
99
+ }
100
+ }
101
+ catch (e) {
102
+ // ignore and fall back to default
103
+ }
95
104
  return '/src/';
96
105
  }
97
106
  async createWorkerFromURL(url) {
@@ -132,7 +141,7 @@ Current Status:
132
141
  // Continue anyway, it might work with direct loading
133
142
  }
134
143
  }
135
- return new Promise((resolve, reject) => {
144
+ return new Promise(async (resolve, reject) => {
136
145
  // Configure Module before the script loads
137
146
  window.Module = {
138
147
  locateFile: (path) => {
@@ -184,11 +193,21 @@ Current Status:
184
193
  document.head.appendChild(script);
185
194
  }
186
195
  else {
187
- // Load the WASM module dynamically
188
- const script = document.createElement('script');
189
- script.src = this.getScriptBasePath() + 'libstream.js';
190
- script.onerror = () => reject(new Error('Failed to load WASM module'));
191
- document.head.appendChild(script);
196
+ try {
197
+ const basePath = this.getScriptBasePath();
198
+ const response = await fetch(basePath + 'libstream.js');
199
+ const code = await response.text();
200
+ // Force the correct MIME type via Blob
201
+ const blob = new Blob([code], { type: 'text/javascript' });
202
+ const blobUrl = URL.createObjectURL(blob);
203
+ const script = document.createElement('script');
204
+ script.src = blobUrl; // Load from memory, bypassing extension MIME headers
205
+ script.onerror = () => reject(new Error('Failed to load WASM module'));
206
+ document.head.appendChild(script);
207
+ }
208
+ catch (error) {
209
+ reject(new Error('Failed to fetch/blobify libstream.js: ' + error));
210
+ }
192
211
  }
193
212
  });
194
213
  }
@@ -1 +1 @@
1
- !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).WhisperTranscriber={})}(this,(function(e){"use strict";class i{constructor(e={}){this.instance=null,this.mediaRecorder=null,this.audioContext=null,this.isRecording=!1,this.audio=null,this.audio0=null,this.Module=null,this.modelLoaded=!1,this.initPromise=null,this.config={modelUrl:e.modelUrl||i.MODEL_URLS[e.modelSize||"base-en-q5_1"],modelSize:e.modelSize||"base-en-q5_1",sampleRate:e.sampleRate||16e3,audioIntervalMs:e.audioIntervalMs||5e3,onTranscription:e.onTranscription||(()=>{}),onProgress:e.onProgress||(()=>{}),onStatus:e.onStatus||(()=>{}),debug:e.debug||!1},this.registerServiceWorkerIfNeeded()}log(e){this.config.debug&&console.log("[WhisperTranscriber]",e)}async registerServiceWorkerIfNeeded(){window.crossOriginIsolated||window.COI_SERVICEWORKER_CODE&&console.warn("[WhisperTranscriber] SharedArrayBuffer is not available. To enable it, you need to serve your site with COOP/COEP headers or use a service worker.\nYou can get the service worker code by calling: transcriber.getServiceWorkerCode()")}getServiceWorkerCode(){return window.COI_SERVICEWORKER_CODE?window.COI_SERVICEWORKER_CODE:null}getCrossOriginIsolationInstructions(){const e=this.getServiceWorkerCode();return window.crossOriginIsolated?"Cross-Origin Isolation is already enabled! No action needed.":`\nCross-Origin Isolation Setup Required\n=====================================\n\nWhisperTranscriber requires SharedArrayBuffer, which needs Cross-Origin Isolation.\n\nOption 1: Server Headers (Recommended)\n--------------------------------------\nConfigure your server to send these headers:\n Cross-Origin-Embedder-Policy: require-corp\n Cross-Origin-Opener-Policy: same-origin\n\nOption 2: Service Worker\n------------------------\n1. Save the following code as 'coi-serviceworker.js' in your website root:\n\n${e?"--- START SERVICE WORKER CODE ---\n"+e+"\n--- END SERVICE WORKER CODE ---":"[Service worker code not available]"}\n\n2. Register the service worker by adding this to your HTML:\n <script src="/coi-serviceworker.js"><\/script>\n\n3. Reload the page after registration.\n\nCurrent Status:\n- crossOriginIsolated: ${window.crossOriginIsolated}\n- SharedArrayBuffer available: ${"undefined"!=typeof SharedArrayBuffer}\n `.trim()}getScriptBasePath(){return"/src/"}async createWorkerFromURL(e){const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);return new Worker(r)}async loadWasmModule(){if(window.LIBSTREAM_WORKER_CODE){this.log("Using inlined worker code");const e=new Blob([window.LIBSTREAM_WORKER_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e);window.__whisperWorkerBlobUrl=i,this.log("Worker blob URL created from inlined code")}else{const e=this.getScriptBasePath()+"libstream.worker.js";try{const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);window.__whisperWorkerBlobUrl=r,this.log("Worker script loaded and blob URL created")}catch(e){this.log("Failed to pre-fetch worker: "+e)}}return new Promise(((e,i)=>{if(window.Module={locateFile:e=>"libstream.worker.js"===e&&window.__whisperWorkerBlobUrl?window.__whisperWorkerBlobUrl:this.getScriptBasePath()+e,onRuntimeInitialized:()=>{this.log("WASM runtime initialized"),setTimeout((()=>{const t=window.Module;t?(this.Module=t,t.init||(t.init=t.cwrap("init","number",["string"])),t.set_audio||(t.set_audio=t.cwrap("set_audio","",["number","array"])),t.get_transcribed||(t.get_transcribed=t.cwrap("get_transcribed","string",[])),t.set_status||(t.set_status=t.cwrap("set_status","",["string"])),this.log("WASM module loaded and functions initialized"),e()):i(new Error("Module not available after runtime initialized"))}),100)}},window.LIBSTREAM_CODE){this.log("Using inlined libstream code");const e=new Blob([window.LIBSTREAM_CODE],{type:"application/javascript"}),t=URL.createObjectURL(e),o=document.createElement("script");o.src=t,o.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(o)}else{const e=document.createElement("script");e.src=this.getScriptBasePath()+"libstream.js",e.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(e)}}))}async loadHelpers(){if(window.HELPERS_CODE){this.log("Using inlined helpers code");const e=new Blob([window.HELPERS_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e),t=document.createElement("script");return t.src=i,new Promise(((e,i)=>{t.onload=()=>e(),t.onerror=()=>i(new Error("Failed to load helpers")),document.head.appendChild(t)}))}{const e=document.createElement("script");return e.src=this.getScriptBasePath()+"helpers.js",new Promise(((i,t)=>{e.onload=()=>i(),e.onerror=()=>t(new Error("Failed to load helpers")),document.head.appendChild(e)}))}}async loadCOIServiceWorker(){if("undefined"!=typeof SharedArrayBuffer)return void this.log("SharedArrayBuffer already available");const e=this.getScriptBasePath(),i=document.createElement("script");return i.src=e+"coi-serviceworker.js",new Promise((e=>{i.onload=()=>{this.log("COI service worker loaded"),e()},i.onerror=()=>{this.log("Failed to load COI service worker - SharedArrayBuffer may not be available"),e()},document.head.appendChild(i)}))}async initialize(){return this.initPromise||(this.initPromise=(async()=>{try{await this.loadCOIServiceWorker(),window.dbVersion=1,window.dbName="whisper.transcriber.models",await this.loadHelpers(),this.log("Helpers loaded"),await this.loadWasmModule(),this.log("WASM module initialized"),this.config.onStatus("Ready to load model")}catch(e){throw this.log("Failed to initialize: "+e),e}})()),this.initPromise}async loadModel(){if(!this.modelLoaded)return await this.initialize(),new Promise(((e,t)=>{const o=this.config.modelUrl,r=i.MODEL_SIZES[this.config.modelSize];this.config.onStatus("Loading model...");window.loadRemote(o,"whisper.bin",r,(e=>{this.config.onProgress(Math.round(100*e))}),((i,t)=>{try{this.Module.FS_unlink(i)}catch(e){}this.Module.FS_createDataFile("/",i,t,!0,!0),this.log(`Model stored: ${i}, size: ${t.length}`),this.modelLoaded=!0,this.config.onStatus("Model loaded successfully"),e()}),(()=>{this.config.onStatus("Model loading cancelled"),t(new Error("Model loading cancelled"))}),(e=>{this.log(e)}))}));this.log("Model already loaded")}async startRecording(){if(!this.modelLoaded)throw new Error("Model not loaded. Call loadModel() first.");if(this.isRecording)return void this.log("Already recording");if(!this.instance){const e=this.Module.init||this.Module.cwrap("init","number",["string"]);if(this.instance=e("whisper.bin"),!this.instance)throw new Error("Failed to initialize Whisper");this.log("Whisper instance initialized")}this.audioContext=new AudioContext({sampleRate:this.config.sampleRate,channelCount:1,echoCancellation:!1,autoGainControl:!0,noiseSuppression:!0});(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))(""),this.isRecording=!0,this.config.onStatus("Recording...");const e=[];try{const i=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});this.mediaRecorder=new MediaRecorder(i),this.mediaRecorder.ondataavailable=i=>{e.push(i.data);const t=new Blob(e,{type:"audio/ogg; codecs=opus"}),o=new FileReader;o.onload=e=>{const i=new Uint8Array(e.target.result);this.audioContext&&this.audioContext.decodeAudioData(i.buffer,(e=>{const i=new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate),t=i.createBufferSource();t.buffer=e,t.connect(i.destination),t.start(0),i.startRendering().then((e=>{this.audio=e.getChannelData(0);const i=new Float32Array(null==this.audio0?this.audio.length:this.audio0.length+this.audio.length);if(null!=this.audio0&&i.set(this.audio0,0),i.set(this.audio,null==this.audio0?0:this.audio0.length),this.instance){(this.Module.set_audio||this.Module.cwrap("set_audio","",["number","array"]))(this.instance,i)}}))}))},o.readAsArrayBuffer(t)},this.mediaRecorder.onstop=()=>{this.isRecording&&setTimeout((()=>this.startRecording()),0)},this.mediaRecorder.start(this.config.audioIntervalMs),this.startTranscriptionPolling()}catch(e){throw this.isRecording=!1,this.config.onStatus("Error: "+e.message),e}}startTranscriptionPolling(){const e=setInterval((()=>{if(!this.isRecording)return void clearInterval(e);const i=(this.Module.get_transcribed||this.Module.cwrap("get_transcribed","string",[]))();null!=i&&i.length>1&&this.config.onTranscription(i)}),100)}stopRecording(){if(!this.isRecording)return void this.log("Not recording");(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))("paused"),this.isRecording=!1,this.audio0=null,this.audio=null,this.mediaRecorder&&(this.mediaRecorder.stop(),this.mediaRecorder=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null),this.config.onStatus("Stopped")}destroy(){this.stopRecording(),this.instance=null,this.Module=null,this.modelLoaded=!1}}i.MODEL_URLS={"tiny.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin","base.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin","tiny-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q5_1.bin","base-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en-q5_1.bin"},i.MODEL_SIZES={"tiny.en":75,"base.en":142,"tiny-en-q5_1":31,"base-en-q5_1":57},e.WhisperTranscriber=i}));
1
+ !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).WhisperTranscriber={})}(this,(function(e){"use strict";class i{constructor(e={}){this.instance=null,this.mediaRecorder=null,this.audioContext=null,this.isRecording=!1,this.audio=null,this.audio0=null,this.Module=null,this.modelLoaded=!1,this.initPromise=null,this.config={modelUrl:e.modelUrl||i.MODEL_URLS[e.modelSize||"base-en-q5_1"],modelSize:e.modelSize||"base-en-q5_1",sampleRate:e.sampleRate||16e3,audioIntervalMs:e.audioIntervalMs||5e3,onTranscription:e.onTranscription||(()=>{}),onProgress:e.onProgress||(()=>{}),onStatus:e.onStatus||(()=>{}),debug:e.debug||!1},this.registerServiceWorkerIfNeeded()}log(e){this.config.debug&&console.log("[WhisperTranscriber]",e)}async registerServiceWorkerIfNeeded(){window.crossOriginIsolated||window.COI_SERVICEWORKER_CODE&&console.warn("[WhisperTranscriber] SharedArrayBuffer is not available. To enable it, you need to serve your site with COOP/COEP headers or use a service worker.\nYou can get the service worker code by calling: transcriber.getServiceWorkerCode()")}getServiceWorkerCode(){return window.COI_SERVICEWORKER_CODE?window.COI_SERVICEWORKER_CODE:null}getCrossOriginIsolationInstructions(){const e=this.getServiceWorkerCode();return window.crossOriginIsolated?"Cross-Origin Isolation is already enabled! No action needed.":`\nCross-Origin Isolation Setup Required\n=====================================\n\nWhisperTranscriber requires SharedArrayBuffer, which needs Cross-Origin Isolation.\n\nOption 1: Server Headers (Recommended)\n--------------------------------------\nConfigure your server to send these headers:\n Cross-Origin-Embedder-Policy: require-corp\n Cross-Origin-Opener-Policy: same-origin\n\nOption 2: Service Worker\n------------------------\n1. Save the following code as 'coi-serviceworker.js' in your website root:\n\n${e?"--- START SERVICE WORKER CODE ---\n"+e+"\n--- END SERVICE WORKER CODE ---":"[Service worker code not available]"}\n\n2. Register the service worker by adding this to your HTML:\n <script src="/coi-serviceworker.js"><\/script>\n\n3. Reload the page after registration.\n\nCurrent Status:\n- crossOriginIsolated: ${window.crossOriginIsolated}\n- SharedArrayBuffer available: ${"undefined"!=typeof SharedArrayBuffer}\n `.trim()}getScriptBasePath(){var e;try{const i=null===(e=window.chrome)||void 0===e?void 0:e.runtime;if(i&&"function"==typeof i.getURL)return i.getURL("whisper-assets/")}catch(e){}return"/src/"}async createWorkerFromURL(e){const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);return new Worker(r)}async loadWasmModule(){if(window.LIBSTREAM_WORKER_CODE){this.log("Using inlined worker code");const e=new Blob([window.LIBSTREAM_WORKER_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e);window.__whisperWorkerBlobUrl=i,this.log("Worker blob URL created from inlined code")}else{const e=this.getScriptBasePath()+"libstream.worker.js";try{const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);window.__whisperWorkerBlobUrl=r,this.log("Worker script loaded and blob URL created")}catch(e){this.log("Failed to pre-fetch worker: "+e)}}return new Promise((async(e,i)=>{if(window.Module={locateFile:e=>"libstream.worker.js"===e&&window.__whisperWorkerBlobUrl?window.__whisperWorkerBlobUrl:this.getScriptBasePath()+e,onRuntimeInitialized:()=>{this.log("WASM runtime initialized"),setTimeout((()=>{const t=window.Module;t?(this.Module=t,t.init||(t.init=t.cwrap("init","number",["string"])),t.set_audio||(t.set_audio=t.cwrap("set_audio","",["number","array"])),t.get_transcribed||(t.get_transcribed=t.cwrap("get_transcribed","string",[])),t.set_status||(t.set_status=t.cwrap("set_status","",["string"])),this.log("WASM module loaded and functions initialized"),e()):i(new Error("Module not available after runtime initialized"))}),100)}},window.LIBSTREAM_CODE){this.log("Using inlined libstream code");const e=new Blob([window.LIBSTREAM_CODE],{type:"application/javascript"}),t=URL.createObjectURL(e),o=document.createElement("script");o.src=t,o.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(o)}else try{const e=this.getScriptBasePath(),t=await fetch(e+"libstream.js"),o=await t.text(),r=new Blob([o],{type:"text/javascript"}),n=URL.createObjectURL(r),s=document.createElement("script");s.src=n,s.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(s)}catch(e){i(new Error("Failed to fetch/blobify libstream.js: "+e))}}))}async loadHelpers(){if(window.HELPERS_CODE){this.log("Using inlined helpers code");const e=new Blob([window.HELPERS_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e),t=document.createElement("script");return t.src=i,new Promise(((e,i)=>{t.onload=()=>e(),t.onerror=()=>i(new Error("Failed to load helpers")),document.head.appendChild(t)}))}{const e=document.createElement("script");return e.src=this.getScriptBasePath()+"helpers.js",new Promise(((i,t)=>{e.onload=()=>i(),e.onerror=()=>t(new Error("Failed to load helpers")),document.head.appendChild(e)}))}}async loadCOIServiceWorker(){if("undefined"!=typeof SharedArrayBuffer)return void this.log("SharedArrayBuffer already available");const e=this.getScriptBasePath(),i=document.createElement("script");return i.src=e+"coi-serviceworker.js",new Promise((e=>{i.onload=()=>{this.log("COI service worker loaded"),e()},i.onerror=()=>{this.log("Failed to load COI service worker - SharedArrayBuffer may not be available"),e()},document.head.appendChild(i)}))}async initialize(){return this.initPromise||(this.initPromise=(async()=>{try{await this.loadCOIServiceWorker(),window.dbVersion=1,window.dbName="whisper.transcriber.models",await this.loadHelpers(),this.log("Helpers loaded"),await this.loadWasmModule(),this.log("WASM module initialized"),this.config.onStatus("Ready to load model")}catch(e){throw this.log("Failed to initialize: "+e),e}})()),this.initPromise}async loadModel(){if(!this.modelLoaded)return await this.initialize(),new Promise(((e,t)=>{const o=this.config.modelUrl,r=i.MODEL_SIZES[this.config.modelSize];this.config.onStatus("Loading model...");window.loadRemote(o,"whisper.bin",r,(e=>{this.config.onProgress(Math.round(100*e))}),((i,t)=>{try{this.Module.FS_unlink(i)}catch(e){}this.Module.FS_createDataFile("/",i,t,!0,!0),this.log(`Model stored: ${i}, size: ${t.length}`),this.modelLoaded=!0,this.config.onStatus("Model loaded successfully"),e()}),(()=>{this.config.onStatus("Model loading cancelled"),t(new Error("Model loading cancelled"))}),(e=>{this.log(e)}))}));this.log("Model already loaded")}async startRecording(){if(!this.modelLoaded)throw new Error("Model not loaded. Call loadModel() first.");if(this.isRecording)return void this.log("Already recording");if(!this.instance){const e=this.Module.init||this.Module.cwrap("init","number",["string"]);if(this.instance=e("whisper.bin"),!this.instance)throw new Error("Failed to initialize Whisper");this.log("Whisper instance initialized")}this.audioContext=new AudioContext({sampleRate:this.config.sampleRate,channelCount:1,echoCancellation:!1,autoGainControl:!0,noiseSuppression:!0});(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))(""),this.isRecording=!0,this.config.onStatus("Recording...");const e=[];try{const i=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});this.mediaRecorder=new MediaRecorder(i),this.mediaRecorder.ondataavailable=i=>{e.push(i.data);const t=new Blob(e,{type:"audio/ogg; codecs=opus"}),o=new FileReader;o.onload=e=>{const i=new Uint8Array(e.target.result);this.audioContext&&this.audioContext.decodeAudioData(i.buffer,(e=>{const i=new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate),t=i.createBufferSource();t.buffer=e,t.connect(i.destination),t.start(0),i.startRendering().then((e=>{this.audio=e.getChannelData(0);const i=new Float32Array(null==this.audio0?this.audio.length:this.audio0.length+this.audio.length);if(null!=this.audio0&&i.set(this.audio0,0),i.set(this.audio,null==this.audio0?0:this.audio0.length),this.instance){(this.Module.set_audio||this.Module.cwrap("set_audio","",["number","array"]))(this.instance,i)}}))}))},o.readAsArrayBuffer(t)},this.mediaRecorder.onstop=()=>{this.isRecording&&setTimeout((()=>this.startRecording()),0)},this.mediaRecorder.start(this.config.audioIntervalMs),this.startTranscriptionPolling()}catch(e){throw this.isRecording=!1,this.config.onStatus("Error: "+e.message),e}}startTranscriptionPolling(){const e=setInterval((()=>{if(!this.isRecording)return void clearInterval(e);const i=(this.Module.get_transcribed||this.Module.cwrap("get_transcribed","string",[]))();null!=i&&i.length>1&&this.config.onTranscription(i)}),100)}stopRecording(){if(!this.isRecording)return void this.log("Not recording");(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))("paused"),this.isRecording=!1,this.audio0=null,this.audio=null,this.mediaRecorder&&(this.mediaRecorder.stop(),this.mediaRecorder=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null),this.config.onStatus("Stopped")}destroy(){this.stopRecording(),this.instance=null,this.Module=null,this.modelLoaded=!1}}i.MODEL_URLS={"tiny.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin","base.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin","tiny-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q5_1.bin","base-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en-q5_1.bin"},i.MODEL_SIZES={"tiny.en":75,"base.en":142,"tiny-en-q5_1":31,"base-en-q5_1":57},e.WhisperTranscriber=i}));
package/dist/index.esm.js CHANGED
@@ -85,7 +85,16 @@ Current Status:
85
85
  return 'Cross-Origin Isolation is already enabled! No action needed.';
86
86
  }
87
87
  getScriptBasePath() {
88
- // Always use local src/ directory for all assets
88
+ var _a;
89
+ try {
90
+ const chromeRuntime = (_a = window.chrome) === null || _a === void 0 ? void 0 : _a.runtime;
91
+ if (chromeRuntime && typeof chromeRuntime.getURL === 'function') {
92
+ return chromeRuntime.getURL('whisper-assets/');
93
+ }
94
+ }
95
+ catch (e) {
96
+ // ignore and fall back to default
97
+ }
89
98
  return '/src/';
90
99
  }
91
100
  async createWorkerFromURL(url) {
@@ -126,7 +135,7 @@ Current Status:
126
135
  // Continue anyway, it might work with direct loading
127
136
  }
128
137
  }
129
- return new Promise((resolve, reject) => {
138
+ return new Promise(async (resolve, reject) => {
130
139
  // Configure Module before the script loads
131
140
  window.Module = {
132
141
  locateFile: (path) => {
@@ -178,11 +187,21 @@ Current Status:
178
187
  document.head.appendChild(script);
179
188
  }
180
189
  else {
181
- // Load the WASM module dynamically
182
- const script = document.createElement('script');
183
- script.src = this.getScriptBasePath() + 'libstream.js';
184
- script.onerror = () => reject(new Error('Failed to load WASM module'));
185
- document.head.appendChild(script);
190
+ try {
191
+ const basePath = this.getScriptBasePath();
192
+ const response = await fetch(basePath + 'libstream.js');
193
+ const code = await response.text();
194
+ // Force the correct MIME type via Blob
195
+ const blob = new Blob([code], { type: 'text/javascript' });
196
+ const blobUrl = URL.createObjectURL(blob);
197
+ const script = document.createElement('script');
198
+ script.src = blobUrl; // Load from memory, bypassing extension MIME headers
199
+ script.onerror = () => reject(new Error('Failed to load WASM module'));
200
+ document.head.appendChild(script);
201
+ }
202
+ catch (error) {
203
+ reject(new Error('Failed to fetch/blobify libstream.js: ' + error));
204
+ }
186
205
  }
187
206
  });
188
207
  }
package/dist/index.js CHANGED
@@ -91,7 +91,16 @@ Current Status:
91
91
  return 'Cross-Origin Isolation is already enabled! No action needed.';
92
92
  }
93
93
  getScriptBasePath() {
94
- // Always use local src/ directory for all assets
94
+ var _a;
95
+ try {
96
+ const chromeRuntime = (_a = window.chrome) === null || _a === void 0 ? void 0 : _a.runtime;
97
+ if (chromeRuntime && typeof chromeRuntime.getURL === 'function') {
98
+ return chromeRuntime.getURL('whisper-assets/');
99
+ }
100
+ }
101
+ catch (e) {
102
+ // ignore and fall back to default
103
+ }
95
104
  return '/src/';
96
105
  }
97
106
  async createWorkerFromURL(url) {
@@ -132,7 +141,7 @@ Current Status:
132
141
  // Continue anyway, it might work with direct loading
133
142
  }
134
143
  }
135
- return new Promise((resolve, reject) => {
144
+ return new Promise(async (resolve, reject) => {
136
145
  // Configure Module before the script loads
137
146
  window.Module = {
138
147
  locateFile: (path) => {
@@ -184,11 +193,21 @@ Current Status:
184
193
  document.head.appendChild(script);
185
194
  }
186
195
  else {
187
- // Load the WASM module dynamically
188
- const script = document.createElement('script');
189
- script.src = this.getScriptBasePath() + 'libstream.js';
190
- script.onerror = () => reject(new Error('Failed to load WASM module'));
191
- document.head.appendChild(script);
196
+ try {
197
+ const basePath = this.getScriptBasePath();
198
+ const response = await fetch(basePath + 'libstream.js');
199
+ const code = await response.text();
200
+ // Force the correct MIME type via Blob
201
+ const blob = new Blob([code], { type: 'text/javascript' });
202
+ const blobUrl = URL.createObjectURL(blob);
203
+ const script = document.createElement('script');
204
+ script.src = blobUrl; // Load from memory, bypassing extension MIME headers
205
+ script.onerror = () => reject(new Error('Failed to load WASM module'));
206
+ document.head.appendChild(script);
207
+ }
208
+ catch (error) {
209
+ reject(new Error('Failed to fetch/blobify libstream.js: ' + error));
210
+ }
192
211
  }
193
212
  });
194
213
  }
package/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).WhisperTranscriber={})}(this,(function(e){"use strict";class i{constructor(e={}){this.instance=null,this.mediaRecorder=null,this.audioContext=null,this.isRecording=!1,this.audio=null,this.audio0=null,this.Module=null,this.modelLoaded=!1,this.initPromise=null,this.config={modelUrl:e.modelUrl||i.MODEL_URLS[e.modelSize||"base-en-q5_1"],modelSize:e.modelSize||"base-en-q5_1",sampleRate:e.sampleRate||16e3,audioIntervalMs:e.audioIntervalMs||5e3,onTranscription:e.onTranscription||(()=>{}),onProgress:e.onProgress||(()=>{}),onStatus:e.onStatus||(()=>{}),debug:e.debug||!1},this.registerServiceWorkerIfNeeded()}log(e){this.config.debug&&console.log("[WhisperTranscriber]",e)}async registerServiceWorkerIfNeeded(){window.crossOriginIsolated||window.COI_SERVICEWORKER_CODE&&console.warn("[WhisperTranscriber] SharedArrayBuffer is not available. To enable it, you need to serve your site with COOP/COEP headers or use a service worker.\nYou can get the service worker code by calling: transcriber.getServiceWorkerCode()")}getServiceWorkerCode(){return window.COI_SERVICEWORKER_CODE?window.COI_SERVICEWORKER_CODE:null}getCrossOriginIsolationInstructions(){const e=this.getServiceWorkerCode();return window.crossOriginIsolated?"Cross-Origin Isolation is already enabled! No action needed.":`\nCross-Origin Isolation Setup Required\n=====================================\n\nWhisperTranscriber requires SharedArrayBuffer, which needs Cross-Origin Isolation.\n\nOption 1: Server Headers (Recommended)\n--------------------------------------\nConfigure your server to send these headers:\n Cross-Origin-Embedder-Policy: require-corp\n Cross-Origin-Opener-Policy: same-origin\n\nOption 2: Service Worker\n------------------------\n1. Save the following code as 'coi-serviceworker.js' in your website root:\n\n${e?"--- START SERVICE WORKER CODE ---\n"+e+"\n--- END SERVICE WORKER CODE ---":"[Service worker code not available]"}\n\n2. Register the service worker by adding this to your HTML:\n <script src="/coi-serviceworker.js"><\/script>\n\n3. Reload the page after registration.\n\nCurrent Status:\n- crossOriginIsolated: ${window.crossOriginIsolated}\n- SharedArrayBuffer available: ${"undefined"!=typeof SharedArrayBuffer}\n `.trim()}getScriptBasePath(){return"/src/"}async createWorkerFromURL(e){const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);return new Worker(r)}async loadWasmModule(){if(window.LIBSTREAM_WORKER_CODE){this.log("Using inlined worker code");const e=new Blob([window.LIBSTREAM_WORKER_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e);window.__whisperWorkerBlobUrl=i,this.log("Worker blob URL created from inlined code")}else{const e=this.getScriptBasePath()+"libstream.worker.js";try{const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);window.__whisperWorkerBlobUrl=r,this.log("Worker script loaded and blob URL created")}catch(e){this.log("Failed to pre-fetch worker: "+e)}}return new Promise(((e,i)=>{if(window.Module={locateFile:e=>"libstream.worker.js"===e&&window.__whisperWorkerBlobUrl?window.__whisperWorkerBlobUrl:this.getScriptBasePath()+e,onRuntimeInitialized:()=>{this.log("WASM runtime initialized"),setTimeout((()=>{const t=window.Module;t?(this.Module=t,t.init||(t.init=t.cwrap("init","number",["string"])),t.set_audio||(t.set_audio=t.cwrap("set_audio","",["number","array"])),t.get_transcribed||(t.get_transcribed=t.cwrap("get_transcribed","string",[])),t.set_status||(t.set_status=t.cwrap("set_status","",["string"])),this.log("WASM module loaded and functions initialized"),e()):i(new Error("Module not available after runtime initialized"))}),100)}},window.LIBSTREAM_CODE){this.log("Using inlined libstream code");const e=new Blob([window.LIBSTREAM_CODE],{type:"application/javascript"}),t=URL.createObjectURL(e),o=document.createElement("script");o.src=t,o.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(o)}else{const e=document.createElement("script");e.src=this.getScriptBasePath()+"libstream.js",e.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(e)}}))}async loadHelpers(){if(window.HELPERS_CODE){this.log("Using inlined helpers code");const e=new Blob([window.HELPERS_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e),t=document.createElement("script");return t.src=i,new Promise(((e,i)=>{t.onload=()=>e(),t.onerror=()=>i(new Error("Failed to load helpers")),document.head.appendChild(t)}))}{const e=document.createElement("script");return e.src=this.getScriptBasePath()+"helpers.js",new Promise(((i,t)=>{e.onload=()=>i(),e.onerror=()=>t(new Error("Failed to load helpers")),document.head.appendChild(e)}))}}async loadCOIServiceWorker(){if("undefined"!=typeof SharedArrayBuffer)return void this.log("SharedArrayBuffer already available");const e=this.getScriptBasePath(),i=document.createElement("script");return i.src=e+"coi-serviceworker.js",new Promise((e=>{i.onload=()=>{this.log("COI service worker loaded"),e()},i.onerror=()=>{this.log("Failed to load COI service worker - SharedArrayBuffer may not be available"),e()},document.head.appendChild(i)}))}async initialize(){return this.initPromise||(this.initPromise=(async()=>{try{await this.loadCOIServiceWorker(),window.dbVersion=1,window.dbName="whisper.transcriber.models",await this.loadHelpers(),this.log("Helpers loaded"),await this.loadWasmModule(),this.log("WASM module initialized"),this.config.onStatus("Ready to load model")}catch(e){throw this.log("Failed to initialize: "+e),e}})()),this.initPromise}async loadModel(){if(!this.modelLoaded)return await this.initialize(),new Promise(((e,t)=>{const o=this.config.modelUrl,r=i.MODEL_SIZES[this.config.modelSize];this.config.onStatus("Loading model...");window.loadRemote(o,"whisper.bin",r,(e=>{this.config.onProgress(Math.round(100*e))}),((i,t)=>{try{this.Module.FS_unlink(i)}catch(e){}this.Module.FS_createDataFile("/",i,t,!0,!0),this.log(`Model stored: ${i}, size: ${t.length}`),this.modelLoaded=!0,this.config.onStatus("Model loaded successfully"),e()}),(()=>{this.config.onStatus("Model loading cancelled"),t(new Error("Model loading cancelled"))}),(e=>{this.log(e)}))}));this.log("Model already loaded")}async startRecording(){if(!this.modelLoaded)throw new Error("Model not loaded. Call loadModel() first.");if(this.isRecording)return void this.log("Already recording");if(!this.instance){const e=this.Module.init||this.Module.cwrap("init","number",["string"]);if(this.instance=e("whisper.bin"),!this.instance)throw new Error("Failed to initialize Whisper");this.log("Whisper instance initialized")}this.audioContext=new AudioContext({sampleRate:this.config.sampleRate,channelCount:1,echoCancellation:!1,autoGainControl:!0,noiseSuppression:!0});(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))(""),this.isRecording=!0,this.config.onStatus("Recording...");const e=[];try{const i=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});this.mediaRecorder=new MediaRecorder(i),this.mediaRecorder.ondataavailable=i=>{e.push(i.data);const t=new Blob(e,{type:"audio/ogg; codecs=opus"}),o=new FileReader;o.onload=e=>{const i=new Uint8Array(e.target.result);this.audioContext&&this.audioContext.decodeAudioData(i.buffer,(e=>{const i=new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate),t=i.createBufferSource();t.buffer=e,t.connect(i.destination),t.start(0),i.startRendering().then((e=>{this.audio=e.getChannelData(0);const i=new Float32Array(null==this.audio0?this.audio.length:this.audio0.length+this.audio.length);if(null!=this.audio0&&i.set(this.audio0,0),i.set(this.audio,null==this.audio0?0:this.audio0.length),this.instance){(this.Module.set_audio||this.Module.cwrap("set_audio","",["number","array"]))(this.instance,i)}}))}))},o.readAsArrayBuffer(t)},this.mediaRecorder.onstop=()=>{this.isRecording&&setTimeout((()=>this.startRecording()),0)},this.mediaRecorder.start(this.config.audioIntervalMs),this.startTranscriptionPolling()}catch(e){throw this.isRecording=!1,this.config.onStatus("Error: "+e.message),e}}startTranscriptionPolling(){const e=setInterval((()=>{if(!this.isRecording)return void clearInterval(e);const i=(this.Module.get_transcribed||this.Module.cwrap("get_transcribed","string",[]))();null!=i&&i.length>1&&this.config.onTranscription(i)}),100)}stopRecording(){if(!this.isRecording)return void this.log("Not recording");(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))("paused"),this.isRecording=!1,this.audio0=null,this.audio=null,this.mediaRecorder&&(this.mediaRecorder.stop(),this.mediaRecorder=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null),this.config.onStatus("Stopped")}destroy(){this.stopRecording(),this.instance=null,this.Module=null,this.modelLoaded=!1}}i.MODEL_URLS={"tiny.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin","base.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin","tiny-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q5_1.bin","base-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en-q5_1.bin"},i.MODEL_SIZES={"tiny.en":75,"base.en":142,"tiny-en-q5_1":31,"base-en-q5_1":57},e.WhisperTranscriber=i}));
1
+ !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).WhisperTranscriber={})}(this,(function(e){"use strict";class i{constructor(e={}){this.instance=null,this.mediaRecorder=null,this.audioContext=null,this.isRecording=!1,this.audio=null,this.audio0=null,this.Module=null,this.modelLoaded=!1,this.initPromise=null,this.config={modelUrl:e.modelUrl||i.MODEL_URLS[e.modelSize||"base-en-q5_1"],modelSize:e.modelSize||"base-en-q5_1",sampleRate:e.sampleRate||16e3,audioIntervalMs:e.audioIntervalMs||5e3,onTranscription:e.onTranscription||(()=>{}),onProgress:e.onProgress||(()=>{}),onStatus:e.onStatus||(()=>{}),debug:e.debug||!1},this.registerServiceWorkerIfNeeded()}log(e){this.config.debug&&console.log("[WhisperTranscriber]",e)}async registerServiceWorkerIfNeeded(){window.crossOriginIsolated||window.COI_SERVICEWORKER_CODE&&console.warn("[WhisperTranscriber] SharedArrayBuffer is not available. To enable it, you need to serve your site with COOP/COEP headers or use a service worker.\nYou can get the service worker code by calling: transcriber.getServiceWorkerCode()")}getServiceWorkerCode(){return window.COI_SERVICEWORKER_CODE?window.COI_SERVICEWORKER_CODE:null}getCrossOriginIsolationInstructions(){const e=this.getServiceWorkerCode();return window.crossOriginIsolated?"Cross-Origin Isolation is already enabled! No action needed.":`\nCross-Origin Isolation Setup Required\n=====================================\n\nWhisperTranscriber requires SharedArrayBuffer, which needs Cross-Origin Isolation.\n\nOption 1: Server Headers (Recommended)\n--------------------------------------\nConfigure your server to send these headers:\n Cross-Origin-Embedder-Policy: require-corp\n Cross-Origin-Opener-Policy: same-origin\n\nOption 2: Service Worker\n------------------------\n1. Save the following code as 'coi-serviceworker.js' in your website root:\n\n${e?"--- START SERVICE WORKER CODE ---\n"+e+"\n--- END SERVICE WORKER CODE ---":"[Service worker code not available]"}\n\n2. Register the service worker by adding this to your HTML:\n <script src="/coi-serviceworker.js"><\/script>\n\n3. Reload the page after registration.\n\nCurrent Status:\n- crossOriginIsolated: ${window.crossOriginIsolated}\n- SharedArrayBuffer available: ${"undefined"!=typeof SharedArrayBuffer}\n `.trim()}getScriptBasePath(){var e;try{const i=null===(e=window.chrome)||void 0===e?void 0:e.runtime;if(i&&"function"==typeof i.getURL)return i.getURL("whisper-assets/")}catch(e){}return"/src/"}async createWorkerFromURL(e){const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);return new Worker(r)}async loadWasmModule(){if(window.LIBSTREAM_WORKER_CODE){this.log("Using inlined worker code");const e=new Blob([window.LIBSTREAM_WORKER_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e);window.__whisperWorkerBlobUrl=i,this.log("Worker blob URL created from inlined code")}else{const e=this.getScriptBasePath()+"libstream.worker.js";try{const i=await fetch(e),t=await i.text(),o=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(o);window.__whisperWorkerBlobUrl=r,this.log("Worker script loaded and blob URL created")}catch(e){this.log("Failed to pre-fetch worker: "+e)}}return new Promise((async(e,i)=>{if(window.Module={locateFile:e=>"libstream.worker.js"===e&&window.__whisperWorkerBlobUrl?window.__whisperWorkerBlobUrl:this.getScriptBasePath()+e,onRuntimeInitialized:()=>{this.log("WASM runtime initialized"),setTimeout((()=>{const t=window.Module;t?(this.Module=t,t.init||(t.init=t.cwrap("init","number",["string"])),t.set_audio||(t.set_audio=t.cwrap("set_audio","",["number","array"])),t.get_transcribed||(t.get_transcribed=t.cwrap("get_transcribed","string",[])),t.set_status||(t.set_status=t.cwrap("set_status","",["string"])),this.log("WASM module loaded and functions initialized"),e()):i(new Error("Module not available after runtime initialized"))}),100)}},window.LIBSTREAM_CODE){this.log("Using inlined libstream code");const e=new Blob([window.LIBSTREAM_CODE],{type:"application/javascript"}),t=URL.createObjectURL(e),o=document.createElement("script");o.src=t,o.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(o)}else try{const e=this.getScriptBasePath(),t=await fetch(e+"libstream.js"),o=await t.text(),r=new Blob([o],{type:"text/javascript"}),n=URL.createObjectURL(r),s=document.createElement("script");s.src=n,s.onerror=()=>i(new Error("Failed to load WASM module")),document.head.appendChild(s)}catch(e){i(new Error("Failed to fetch/blobify libstream.js: "+e))}}))}async loadHelpers(){if(window.HELPERS_CODE){this.log("Using inlined helpers code");const e=new Blob([window.HELPERS_CODE],{type:"application/javascript"}),i=URL.createObjectURL(e),t=document.createElement("script");return t.src=i,new Promise(((e,i)=>{t.onload=()=>e(),t.onerror=()=>i(new Error("Failed to load helpers")),document.head.appendChild(t)}))}{const e=document.createElement("script");return e.src=this.getScriptBasePath()+"helpers.js",new Promise(((i,t)=>{e.onload=()=>i(),e.onerror=()=>t(new Error("Failed to load helpers")),document.head.appendChild(e)}))}}async loadCOIServiceWorker(){if("undefined"!=typeof SharedArrayBuffer)return void this.log("SharedArrayBuffer already available");const e=this.getScriptBasePath(),i=document.createElement("script");return i.src=e+"coi-serviceworker.js",new Promise((e=>{i.onload=()=>{this.log("COI service worker loaded"),e()},i.onerror=()=>{this.log("Failed to load COI service worker - SharedArrayBuffer may not be available"),e()},document.head.appendChild(i)}))}async initialize(){return this.initPromise||(this.initPromise=(async()=>{try{await this.loadCOIServiceWorker(),window.dbVersion=1,window.dbName="whisper.transcriber.models",await this.loadHelpers(),this.log("Helpers loaded"),await this.loadWasmModule(),this.log("WASM module initialized"),this.config.onStatus("Ready to load model")}catch(e){throw this.log("Failed to initialize: "+e),e}})()),this.initPromise}async loadModel(){if(!this.modelLoaded)return await this.initialize(),new Promise(((e,t)=>{const o=this.config.modelUrl,r=i.MODEL_SIZES[this.config.modelSize];this.config.onStatus("Loading model...");window.loadRemote(o,"whisper.bin",r,(e=>{this.config.onProgress(Math.round(100*e))}),((i,t)=>{try{this.Module.FS_unlink(i)}catch(e){}this.Module.FS_createDataFile("/",i,t,!0,!0),this.log(`Model stored: ${i}, size: ${t.length}`),this.modelLoaded=!0,this.config.onStatus("Model loaded successfully"),e()}),(()=>{this.config.onStatus("Model loading cancelled"),t(new Error("Model loading cancelled"))}),(e=>{this.log(e)}))}));this.log("Model already loaded")}async startRecording(){if(!this.modelLoaded)throw new Error("Model not loaded. Call loadModel() first.");if(this.isRecording)return void this.log("Already recording");if(!this.instance){const e=this.Module.init||this.Module.cwrap("init","number",["string"]);if(this.instance=e("whisper.bin"),!this.instance)throw new Error("Failed to initialize Whisper");this.log("Whisper instance initialized")}this.audioContext=new AudioContext({sampleRate:this.config.sampleRate,channelCount:1,echoCancellation:!1,autoGainControl:!0,noiseSuppression:!0});(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))(""),this.isRecording=!0,this.config.onStatus("Recording...");const e=[];try{const i=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1});this.mediaRecorder=new MediaRecorder(i),this.mediaRecorder.ondataavailable=i=>{e.push(i.data);const t=new Blob(e,{type:"audio/ogg; codecs=opus"}),o=new FileReader;o.onload=e=>{const i=new Uint8Array(e.target.result);this.audioContext&&this.audioContext.decodeAudioData(i.buffer,(e=>{const i=new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate),t=i.createBufferSource();t.buffer=e,t.connect(i.destination),t.start(0),i.startRendering().then((e=>{this.audio=e.getChannelData(0);const i=new Float32Array(null==this.audio0?this.audio.length:this.audio0.length+this.audio.length);if(null!=this.audio0&&i.set(this.audio0,0),i.set(this.audio,null==this.audio0?0:this.audio0.length),this.instance){(this.Module.set_audio||this.Module.cwrap("set_audio","",["number","array"]))(this.instance,i)}}))}))},o.readAsArrayBuffer(t)},this.mediaRecorder.onstop=()=>{this.isRecording&&setTimeout((()=>this.startRecording()),0)},this.mediaRecorder.start(this.config.audioIntervalMs),this.startTranscriptionPolling()}catch(e){throw this.isRecording=!1,this.config.onStatus("Error: "+e.message),e}}startTranscriptionPolling(){const e=setInterval((()=>{if(!this.isRecording)return void clearInterval(e);const i=(this.Module.get_transcribed||this.Module.cwrap("get_transcribed","string",[]))();null!=i&&i.length>1&&this.config.onTranscription(i)}),100)}stopRecording(){if(!this.isRecording)return void this.log("Not recording");(this.Module.set_status||this.Module.cwrap("set_status","",["string"]))("paused"),this.isRecording=!1,this.audio0=null,this.audio=null,this.mediaRecorder&&(this.mediaRecorder.stop(),this.mediaRecorder=null),this.audioContext&&(this.audioContext.close(),this.audioContext=null),this.config.onStatus("Stopped")}destroy(){this.stopRecording(),this.instance=null,this.Module=null,this.modelLoaded=!1}}i.MODEL_URLS={"tiny.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin","base.en":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin","tiny-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q5_1.bin","base-en-q5_1":"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en-q5_1.bin"},i.MODEL_SIZES={"tiny.en":75,"base.en":142,"tiny-en-q5_1":31,"base-en-q5_1":57},e.WhisperTranscriber=i}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sridhar-mani/whisper-web-transcriber",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Real-time audio transcription in the browser using OpenAI's Whisper model via WebAssembly",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",