whispermix 1.4.0 → 1.4.4

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 CHANGED
@@ -29,11 +29,13 @@ import WhisperMix from 'whispermix';
29
29
  You can initialize WhisperMix with a specific model:
30
30
 
31
31
  ```javascript
32
- const whisper = new WhisperMix({ model: 'openai' }); // For OpenAI's Whisper
32
+ const whisper = new WhisperMix({ model: 'openai/whisper-1' }); // For OpenAI's Whisper
33
33
  // or
34
- const whisperGroq = new WhisperMix({ model: 'groq/large-v3' }); // For Groq's Whisper Large v3
34
+ const whisperGroq = new WhisperMix({ model: 'groq/whisper-large-v3' }); // For Groq's Whisper Large v3
35
35
  // or
36
- const whisperLocal = new WhisperMix({ model: 'xenova/large-v3' }); // For local Whisper
36
+ const whisperLocal = new WhisperMix({ model: 'xenova/whisper-large-v3' }); // For local Whisper (large)
37
+ // or
38
+ const whisperLocalBase = new WhisperMix({ model: 'xenova/whisper-base' }); // For local Whisper (base)
37
39
  ```
38
40
 
39
41
  ### 📄 Transcribing from a File
@@ -46,7 +48,7 @@ whisperGroq.fromFile(filePath)
46
48
 
47
49
  // For local Whisper with language specification
48
50
  const whisperLocal = new WhisperMix({
49
- model: 'xenova/large-v3',
51
+ model: 'xenova/whisper-large-v3',
50
52
  language: 'spanish' // Optional
51
53
  });
52
54
  whisperLocal.fromFile(filePath)
@@ -79,7 +81,7 @@ WhisperMix uses Bottleneck for rate limiting API-based models. You can configure
79
81
 
80
82
  ```javascript
81
83
  const whisper = new WhisperMix({
82
- model: 'whisper-1',
84
+ model: 'openai/whisper-1',
83
85
  bottleneck: {
84
86
  minTime: 3000,
85
87
  maxConcurrent: 1,
@@ -106,7 +108,7 @@ You can adjust these settings based on your specific rate limiting needs. Note t
106
108
 
107
109
  Creates a new WhisperMix instance.
108
110
 
109
- - `options.model`: The model to use for transcription. Can be 'openai' (OpenAI), 'groq/large-v3' (Groq), or 'xenova/large-v3' (local).
111
+ - `options.model`: The model to use for transcription. Can be `'openai/whisper-1'` (OpenAI), `'groq/whisper-large-v3'` (Groq), `'xenova/whisper-large-v3'` or `'xenova/whisper-base'` (local).
110
112
  - `options.bottleneck`: (Optional) Configuration for Bottleneck rate limiting (API models only).
111
113
  - `options.chunkSize`: (Optional) The size in seconds of the chunks to split the audio into. Default is 890 seconds.
112
114
  - `options.language`: (Optional) Language for local Whisper model. Defaults to 'auto' for automatic detection.
package/demo/groq.js CHANGED
@@ -1,17 +1,13 @@
1
1
  import 'dotenv/config';
2
2
  import WhisperMix from '../index.js';
3
3
 
4
- const transcribe = new WhisperMix({ model: 'whisper-large-v3' });
4
+ const transcribe = new WhisperMix({ model: 'groq/whisper-large-v3' });
5
5
 
6
- async function main() {
7
- for (let i = 0; i < 10; i++) {
8
- try {
9
- const result = await transcribe.fromFile('./example.mp3');
10
- console.log(`${i}/10`, result);
11
- } catch (error) {
12
- console.error(error);
13
- }
6
+ for (let i = 0; i < 10; i++) {
7
+ try {
8
+ const result = await transcribe.fromFile('./example.mp3');
9
+ console.log(`${i}/10`, result);
10
+ } catch (error) {
11
+ console.error(error);
14
12
  }
15
- }
16
-
17
- main();
13
+ }
package/demo/local.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import WhisperMix from '../index.js';
2
2
 
3
3
  const whisperLocal = new WhisperMix({
4
- model: 'xenova/large-v3'
4
+ model: 'xenova/whisper-large-v3'
5
5
  });
6
6
 
7
7
  const r = await whisperLocal.fromFile('conversation.wav');
package/index.js CHANGED
@@ -1,5 +1,3 @@
1
- import axios from 'axios';
2
- import FormData from 'form-data';
3
1
  import fs from 'fs';
4
2
  import Bottleneck from 'bottleneck';
5
3
  import path from 'path';
@@ -13,7 +11,7 @@ import audioDecode from 'audio-decode';
13
11
 
14
12
  class WhisperMix {
15
13
  constructor(setup = {}) {
16
- this.model = 'openai';
14
+ this.model = 'openai/whisper-1';
17
15
  this.bottleneck = {
18
16
  minTime: 2000,
19
17
  maxConcurrent: 1,
@@ -24,21 +22,21 @@ class WhisperMix {
24
22
  this.chunkSize = 15 * 60 - 10; // 14 minutes 50 seconds
25
23
 
26
24
  const config = {
27
- 'openai': {
25
+ 'openai/whisper-1': {
28
26
  url: 'https://api.openai.com/v1/audio/transcriptions',
29
27
  modelName: 'whisper-1',
30
28
  apiKey: process.env.OPENAI_API_KEY,
31
29
  },
32
- 'groq/large-v3': {
30
+ 'groq/whisper-large-v3': {
33
31
  url: 'https://api.groq.com/openai/v1/audio/transcriptions',
34
32
  modelName: 'whisper-large-v3',
35
33
  apiKey: process.env.GROQ_API_KEY,
36
34
  },
37
- 'xenova/large-v3': {
35
+ 'xenova/whisper-large-v3': {
38
36
  local: true,
39
37
  modelName: 'Xenova/whisper-large-v3',
40
38
  },
41
- 'xenova/base': {
39
+ 'xenova/whisper-base': {
42
40
  local: true,
43
41
  modelName: 'Xenova/whisper-base',
44
42
  },
@@ -47,6 +45,9 @@ class WhisperMix {
47
45
  Object.assign(this, setup);
48
46
 
49
47
  this.config = config[this.model];
48
+ if (!this.config) {
49
+ throw new Error(`Unknown model: "${this.model}". Valid models: ${Object.keys(config).join(', ')}`);
50
+ }
50
51
  this.apiKey = this.apiKey || this.config.apiKey;
51
52
  this.apiUrl = this.config.url;
52
53
  this.isLocal = this.config.local || false;
@@ -133,29 +134,40 @@ class WhisperMix {
133
134
  if (this.isLocal) {
134
135
  throw new Error('fromStream is not supported for local Whisper model. Use fromFile instead.');
135
136
  }
136
-
137
- return this.limiter.schedule(() => new Promise((resolve, reject) => {
138
- const formData = new FormData();
139
- formData.append('file', audioStream);
140
- formData.append('model', this.modelName);
141
137
 
142
- this._makeRequest(formData)
143
- .then(resolve)
144
- .catch(reject);
145
- }));
138
+ const chunks = [];
139
+ for await (const chunk of audioStream) {
140
+ chunks.push(chunk);
141
+ }
142
+ const buffer = Buffer.concat(chunks);
143
+
144
+ return this.limiter.schedule(() => this._makeRequest(buffer));
146
145
  }
147
146
 
148
- async _makeRequest(formData) {
147
+ async _makeRequest(buffer) {
149
148
  try {
150
- const response = await axios.post(this.apiUrl, formData, {
149
+ const blob = new Blob([buffer], { type: 'audio/mpeg' });
150
+ const formData = new FormData();
151
+ formData.append('file', blob, 'audio.mp3');
152
+ formData.append('model', this.modelName);
153
+
154
+ const response = await fetch(this.apiUrl, {
155
+ method: 'POST',
151
156
  headers: {
152
- ...formData.getHeaders(),
153
157
  'Authorization': `Bearer ${this.apiKey}`,
154
158
  },
159
+ body: formData,
155
160
  });
156
- return response.data.text.trim();
161
+
162
+ const responseData = await response.json();
163
+
164
+ if (!response.ok) {
165
+ throw responseData;
166
+ }
167
+
168
+ return responseData.text.trim();
157
169
  } catch (error) {
158
- throw error.response ? error.response.data : error.message;
170
+ throw error?.message || error;
159
171
  }
160
172
  }
161
173
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "whispermix",
3
3
  "description": "🎙️ WhisperMix is a versatile module for transcribing audio using OpenAI’s Whisper or Groq’s Whisper v3 model.",
4
- "version": "1.4.0",
4
+ "version": "1.4.4",
5
5
  "type": "module",
6
6
  "keywords": [
7
7
  "whisper",
@@ -46,10 +46,8 @@
46
46
  "dependencies": {
47
47
  "@xenova/transformers": "^2.17.2",
48
48
  "audio-decode": "^2.1.3",
49
- "axios": "^1.12.1",
50
49
  "bottleneck": "^2.19.5",
51
50
  "fluent-ffmpeg": "^2.1.3",
52
- "form-data": "^4.0.4",
53
51
  "get-audio-duration": "^4.0.1"
54
52
  }
55
53
  }