@derogab/stt-proxy 0.2.1 → 0.3.1
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 +27 -4
- package/dist/cjs/index.js +103 -41
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +103 -41
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# stt-proxy
|
|
2
|
-
A simple and lightweight proxy for seamless integration with multiple STT providers including Whisper.cpp.
|
|
2
|
+
A simple and lightweight proxy for seamless integration with multiple STT providers including Whisper.cpp and Cloudflare AI.
|
|
3
3
|
|
|
4
4
|
## Features
|
|
5
5
|
|
|
@@ -28,6 +28,15 @@ console.log(result.text);
|
|
|
28
28
|
The package automatically detects which STT provider to use based on your environment variables.
|
|
29
29
|
Configure one or more providers:
|
|
30
30
|
|
|
31
|
+
### Provider Selection
|
|
32
|
+
```bash
|
|
33
|
+
STT_PROVIDER=cloudflare # Optional, force a specific provider (whisper.cpp, cloudflare)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
When `STT_PROVIDER` is set, the specified provider will be used and an error is thrown if its credentials are not configured. When not set, providers are selected automatically based on priority.
|
|
37
|
+
|
|
38
|
+
> **Note:** `PROVIDER` is supported as a fallback for backward compatibility when `STT_PROVIDER` is not set.
|
|
39
|
+
|
|
31
40
|
### Whisper.cpp (Local)
|
|
32
41
|
```bash
|
|
33
42
|
WHISPER_CPP_MODEL_PATH=/path/to/ggml-base.bin # Required, path to your GGML model file
|
|
@@ -38,6 +47,14 @@ Download models from [HuggingFace](https://huggingface.co/ggerganov/whisper.cpp/
|
|
|
38
47
|
curl -L -o ggml-base.bin https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin
|
|
39
48
|
```
|
|
40
49
|
|
|
50
|
+
### Cloudflare AI
|
|
51
|
+
```bash
|
|
52
|
+
CLOUDFLARE_ACCOUNT_ID=your-account-id # Required
|
|
53
|
+
CLOUDFLARE_AUTH_KEY=your-api-token # Required
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Uses the `@cf/openai/whisper-large-v3-turbo` model.
|
|
57
|
+
|
|
41
58
|
## API Reference
|
|
42
59
|
|
|
43
60
|
### `transcribe(audio: string | Buffer, options?): Promise<TranscribeOutput>`
|
|
@@ -87,14 +104,17 @@ console.log(result3.text);
|
|
|
87
104
|
|
|
88
105
|
## Provider Priority
|
|
89
106
|
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
When `STT_PROVIDER` environment variable is set, that provider is used directly.
|
|
108
|
+
|
|
109
|
+
Otherwise, the package selects providers in the following order:
|
|
110
|
+
1. **Whisper.cpp** (if `WHISPER_CPP_MODEL_PATH` is set and file exists)
|
|
111
|
+
2. **Cloudflare AI** (if `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_AUTH_KEY` are set)
|
|
92
112
|
|
|
93
113
|
If no providers are configured, the function throws an error.
|
|
94
114
|
|
|
95
115
|
## Requirements
|
|
96
116
|
|
|
97
|
-
- **FFmpeg**: Required for audio conversion.
|
|
117
|
+
- **FFmpeg**: Required for audio conversion (Whisper.cpp only).
|
|
98
118
|
```bash
|
|
99
119
|
# macOS
|
|
100
120
|
brew install ffmpeg
|
|
@@ -114,6 +134,9 @@ npm install
|
|
|
114
134
|
|
|
115
135
|
# Build the package
|
|
116
136
|
npm run build
|
|
137
|
+
|
|
138
|
+
# Run tests
|
|
139
|
+
npm test
|
|
117
140
|
```
|
|
118
141
|
|
|
119
142
|
## Credits
|
package/dist/cjs/index.js
CHANGED
|
@@ -6,17 +6,27 @@ const fs = require("fs");
|
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const os = require("os");
|
|
8
8
|
const child_process_1 = require("child_process");
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Shared utilities
|
|
11
|
+
// ============================================================================
|
|
12
|
+
function cleanTranscription(text) {
|
|
13
|
+
return text.replace(/[\x00-\x1F\x7F]/g, '').trim();
|
|
14
|
+
}
|
|
15
|
+
function generateTempPath(prefix, extension) {
|
|
16
|
+
const randomId = `${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
17
|
+
return path.join(os.tmpdir(), `${prefix}_${randomId}.${extension}`);
|
|
18
|
+
}
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Whisper.cpp provider
|
|
21
|
+
// ============================================================================
|
|
9
22
|
let whisperInstance = null;
|
|
10
23
|
let currentModelPath = null;
|
|
11
|
-
function getWhisperModelPath() {
|
|
12
|
-
return process.env['WHISPER_CPP_MODEL_PATH'];
|
|
13
|
-
}
|
|
14
24
|
function isWhisperConfigured() {
|
|
15
|
-
const modelPath =
|
|
16
|
-
return modelPath
|
|
25
|
+
const modelPath = process.env['WHISPER_CPP_MODEL_PATH'];
|
|
26
|
+
return !!modelPath && fs.existsSync(modelPath);
|
|
17
27
|
}
|
|
18
28
|
async function getWhisperInstance() {
|
|
19
|
-
const modelPath =
|
|
29
|
+
const modelPath = process.env['WHISPER_CPP_MODEL_PATH'];
|
|
20
30
|
if (!modelPath) {
|
|
21
31
|
throw new Error('WHISPER_CPP_MODEL_PATH environment variable is not set');
|
|
22
32
|
}
|
|
@@ -36,8 +46,7 @@ async function getWhisperInstance() {
|
|
|
36
46
|
return whisperInstance;
|
|
37
47
|
}
|
|
38
48
|
function audioToPcm(audioPath) {
|
|
39
|
-
const
|
|
40
|
-
const tempPcmPath = path.join(tempDir, `whisper_${Date.now()}_${Math.random().toString(36).substring(7)}.pcm`);
|
|
49
|
+
const tempPcmPath = generateTempPath('whisper', 'pcm');
|
|
41
50
|
try {
|
|
42
51
|
(0, child_process_1.execSync)(`ffmpeg -y -i "${audioPath}" -ar 16000 -ac 1 -f f32le "${tempPcmPath}"`, { stdio: 'pipe' });
|
|
43
52
|
const pcmBuffer = fs.readFileSync(tempPcmPath);
|
|
@@ -49,15 +58,10 @@ function audioToPcm(audioPath) {
|
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
|
-
function cleanTranscription(text) {
|
|
53
|
-
return text
|
|
54
|
-
.replace(/[\x00-\x1F\x7F]/g, '')
|
|
55
|
-
.trim();
|
|
56
|
-
}
|
|
57
61
|
function resultsToText(results) {
|
|
58
62
|
return results.map((r) => r.text).join(' ');
|
|
59
63
|
}
|
|
60
|
-
async function
|
|
64
|
+
async function transcribeWithWhisper(audioPath, options = {}) {
|
|
61
65
|
if (!fs.existsSync(audioPath)) {
|
|
62
66
|
throw new Error(`Audio file not found: ${audioPath}`);
|
|
63
67
|
}
|
|
@@ -65,41 +69,92 @@ async function transcribe_whispercpp(audioPath, options = {}) {
|
|
|
65
69
|
const pcmData = audioToPcm(audioPath);
|
|
66
70
|
const transcribeParams = {
|
|
67
71
|
format: 'simple',
|
|
72
|
+
...(options.language !== undefined && { language: options.language }),
|
|
73
|
+
...(options.translate !== undefined && { translate: options.translate }),
|
|
68
74
|
};
|
|
69
|
-
if (options.language !== undefined) {
|
|
70
|
-
transcribeParams.language = options.language;
|
|
71
|
-
}
|
|
72
|
-
if (options.translate !== undefined) {
|
|
73
|
-
transcribeParams.translate = options.translate;
|
|
74
|
-
}
|
|
75
75
|
const task = await whisper.transcribe(pcmData, transcribeParams);
|
|
76
76
|
const results = await task.result;
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
text: cleanTranscription(text),
|
|
80
|
-
};
|
|
77
|
+
return { text: cleanTranscription(resultsToText(results)) };
|
|
81
78
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Cloudflare provider
|
|
81
|
+
// ============================================================================
|
|
82
|
+
function isCloudflareConfigured() {
|
|
83
|
+
return !!(process.env['CLOUDFLARE_ACCOUNT_ID'] && process.env['CLOUDFLARE_AUTH_KEY']);
|
|
84
|
+
}
|
|
85
|
+
async function transcribeWithCloudflare(audioPath, options = {}) {
|
|
86
|
+
if (!fs.existsSync(audioPath)) {
|
|
87
|
+
throw new Error(`Audio file not found: ${audioPath}`);
|
|
88
|
+
}
|
|
89
|
+
const accountId = process.env['CLOUDFLARE_ACCOUNT_ID'];
|
|
90
|
+
const authKey = process.env['CLOUDFLARE_AUTH_KEY'];
|
|
91
|
+
if (!accountId || !authKey) {
|
|
92
|
+
throw new Error('Cloudflare credentials not configured. Set CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY environment variables.');
|
|
93
|
+
}
|
|
94
|
+
const audioBuffer = fs.readFileSync(audioPath);
|
|
95
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/@cf/openai/whisper-large-v3-turbo`;
|
|
96
|
+
const response = await fetch(url, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: {
|
|
99
|
+
'Authorization': `Bearer ${authKey}`,
|
|
100
|
+
'Content-Type': 'application/json',
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
audio: audioBuffer.toString('base64'),
|
|
104
|
+
task: options.translate ? 'translate' : 'transcribe',
|
|
105
|
+
vad_filter: true,
|
|
106
|
+
...(options.language && { language: options.language }),
|
|
107
|
+
}),
|
|
108
|
+
});
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
const errorBody = await response.text();
|
|
111
|
+
throw new Error(`Cloudflare API error: ${response.status} ${response.statusText} - ${errorBody}`);
|
|
112
|
+
}
|
|
113
|
+
const data = await response.json();
|
|
114
|
+
if (!data.success || !data.result?.text) {
|
|
115
|
+
const errorMessage = data.errors?.[0]?.message || 'Unknown Cloudflare API error';
|
|
116
|
+
throw new Error(`Cloudflare transcription failed: ${errorMessage}`);
|
|
117
|
+
}
|
|
118
|
+
return { text: cleanTranscription(data.result.text) };
|
|
119
|
+
}
|
|
120
|
+
function selectProvider() {
|
|
121
|
+
// Check for explicit provider selection (STT_PROVIDER takes priority, PROVIDER is fallback)
|
|
122
|
+
const explicitProvider = (process.env['STT_PROVIDER'] || process.env['PROVIDER'])?.toLowerCase();
|
|
123
|
+
if (explicitProvider) {
|
|
124
|
+
// Validate explicit provider configuration
|
|
125
|
+
switch (explicitProvider) {
|
|
126
|
+
case 'whisper.cpp':
|
|
127
|
+
if (!isWhisperConfigured()) {
|
|
128
|
+
throw new Error("STT_PROVIDER is set to 'whisper.cpp' but WHISPER_CPP_MODEL_PATH is not configured or model file does not exist.");
|
|
129
|
+
}
|
|
130
|
+
return 'whisper.cpp';
|
|
131
|
+
case 'cloudflare':
|
|
132
|
+
if (!isCloudflareConfigured()) {
|
|
133
|
+
throw new Error("STT_PROVIDER is set to 'cloudflare' but CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY are not configured.");
|
|
134
|
+
}
|
|
135
|
+
return 'cloudflare';
|
|
136
|
+
default:
|
|
137
|
+
throw new Error(`Unknown provider: ${explicitProvider}. Valid providers are: whisper.cpp, cloudflare`);
|
|
87
138
|
}
|
|
88
|
-
return transcribe_whispercpp(audio, options);
|
|
89
139
|
}
|
|
90
|
-
|
|
140
|
+
// Auto-detection priority: whisper.cpp > cloudflare
|
|
141
|
+
if (isWhisperConfigured())
|
|
142
|
+
return 'whisper.cpp';
|
|
143
|
+
if (isCloudflareConfigured())
|
|
144
|
+
return 'cloudflare';
|
|
145
|
+
throw new Error('No STT provider configured. Set WHISPER_CPP_MODEL_PATH or CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY environment variables.');
|
|
91
146
|
}
|
|
92
|
-
async function
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
throw new Error('No STT provider configured. Set WHISPER_CPP_MODEL_PATH environment variable.');
|
|
147
|
+
async function transcribeFromPath(audioPath, options, provider) {
|
|
148
|
+
if (provider === 'cloudflare') {
|
|
149
|
+
return transcribeWithCloudflare(audioPath, options);
|
|
96
150
|
}
|
|
97
|
-
|
|
98
|
-
|
|
151
|
+
return transcribeWithWhisper(audioPath, options);
|
|
152
|
+
}
|
|
153
|
+
async function transcribeFromBuffer(audioBuffer, options, provider) {
|
|
154
|
+
const tempPath = generateTempPath('stt_input', 'audio');
|
|
99
155
|
fs.writeFileSync(tempPath, audioBuffer);
|
|
100
156
|
try {
|
|
101
|
-
|
|
102
|
-
return result;
|
|
157
|
+
return await transcribeFromPath(tempPath, options, provider);
|
|
103
158
|
}
|
|
104
159
|
finally {
|
|
105
160
|
if (fs.existsSync(tempPath)) {
|
|
@@ -107,6 +162,15 @@ async function transcribeBuffer(audioBuffer, options = {}) {
|
|
|
107
162
|
}
|
|
108
163
|
}
|
|
109
164
|
}
|
|
165
|
+
async function transcribe(audio, options = {}) {
|
|
166
|
+
const provider = selectProvider();
|
|
167
|
+
return Buffer.isBuffer(audio)
|
|
168
|
+
? transcribeFromBuffer(audio, options, provider)
|
|
169
|
+
: transcribeFromPath(audio, options, provider);
|
|
170
|
+
}
|
|
171
|
+
// ============================================================================
|
|
172
|
+
// Cleanup handlers
|
|
173
|
+
// ============================================================================
|
|
110
174
|
async function freeWhisper() {
|
|
111
175
|
if (whisperInstance) {
|
|
112
176
|
await whisperInstance.free();
|
|
@@ -114,7 +178,6 @@ async function freeWhisper() {
|
|
|
114
178
|
currentModelPath = null;
|
|
115
179
|
}
|
|
116
180
|
}
|
|
117
|
-
// Automatically clean up Whisper instance on process exit
|
|
118
181
|
process.on('exit', () => {
|
|
119
182
|
if (whisperInstance) {
|
|
120
183
|
// Note: Cannot use async operations in 'exit' handler
|
|
@@ -123,7 +186,6 @@ process.on('exit', () => {
|
|
|
123
186
|
currentModelPath = null;
|
|
124
187
|
}
|
|
125
188
|
});
|
|
126
|
-
// Handle graceful shutdown signals
|
|
127
189
|
const shutdownHandler = async () => {
|
|
128
190
|
await freeWhisper();
|
|
129
191
|
process.exit(0);
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -3,17 +3,27 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import * as os from 'os';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Shared utilities
|
|
8
|
+
// ============================================================================
|
|
9
|
+
function cleanTranscription(text) {
|
|
10
|
+
return text.replace(/[\x00-\x1F\x7F]/g, '').trim();
|
|
11
|
+
}
|
|
12
|
+
function generateTempPath(prefix, extension) {
|
|
13
|
+
const randomId = `${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
14
|
+
return path.join(os.tmpdir(), `${prefix}_${randomId}.${extension}`);
|
|
15
|
+
}
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Whisper.cpp provider
|
|
18
|
+
// ============================================================================
|
|
6
19
|
let whisperInstance = null;
|
|
7
20
|
let currentModelPath = null;
|
|
8
|
-
function getWhisperModelPath() {
|
|
9
|
-
return process.env['WHISPER_CPP_MODEL_PATH'];
|
|
10
|
-
}
|
|
11
21
|
function isWhisperConfigured() {
|
|
12
|
-
const modelPath =
|
|
13
|
-
return modelPath
|
|
22
|
+
const modelPath = process.env['WHISPER_CPP_MODEL_PATH'];
|
|
23
|
+
return !!modelPath && fs.existsSync(modelPath);
|
|
14
24
|
}
|
|
15
25
|
async function getWhisperInstance() {
|
|
16
|
-
const modelPath =
|
|
26
|
+
const modelPath = process.env['WHISPER_CPP_MODEL_PATH'];
|
|
17
27
|
if (!modelPath) {
|
|
18
28
|
throw new Error('WHISPER_CPP_MODEL_PATH environment variable is not set');
|
|
19
29
|
}
|
|
@@ -33,8 +43,7 @@ async function getWhisperInstance() {
|
|
|
33
43
|
return whisperInstance;
|
|
34
44
|
}
|
|
35
45
|
function audioToPcm(audioPath) {
|
|
36
|
-
const
|
|
37
|
-
const tempPcmPath = path.join(tempDir, `whisper_${Date.now()}_${Math.random().toString(36).substring(7)}.pcm`);
|
|
46
|
+
const tempPcmPath = generateTempPath('whisper', 'pcm');
|
|
38
47
|
try {
|
|
39
48
|
execSync(`ffmpeg -y -i "${audioPath}" -ar 16000 -ac 1 -f f32le "${tempPcmPath}"`, { stdio: 'pipe' });
|
|
40
49
|
const pcmBuffer = fs.readFileSync(tempPcmPath);
|
|
@@ -46,15 +55,10 @@ function audioToPcm(audioPath) {
|
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
}
|
|
49
|
-
function cleanTranscription(text) {
|
|
50
|
-
return text
|
|
51
|
-
.replace(/[\x00-\x1F\x7F]/g, '')
|
|
52
|
-
.trim();
|
|
53
|
-
}
|
|
54
58
|
function resultsToText(results) {
|
|
55
59
|
return results.map((r) => r.text).join(' ');
|
|
56
60
|
}
|
|
57
|
-
async function
|
|
61
|
+
async function transcribeWithWhisper(audioPath, options = {}) {
|
|
58
62
|
if (!fs.existsSync(audioPath)) {
|
|
59
63
|
throw new Error(`Audio file not found: ${audioPath}`);
|
|
60
64
|
}
|
|
@@ -62,41 +66,92 @@ async function transcribe_whispercpp(audioPath, options = {}) {
|
|
|
62
66
|
const pcmData = audioToPcm(audioPath);
|
|
63
67
|
const transcribeParams = {
|
|
64
68
|
format: 'simple',
|
|
69
|
+
...(options.language !== undefined && { language: options.language }),
|
|
70
|
+
...(options.translate !== undefined && { translate: options.translate }),
|
|
65
71
|
};
|
|
66
|
-
if (options.language !== undefined) {
|
|
67
|
-
transcribeParams.language = options.language;
|
|
68
|
-
}
|
|
69
|
-
if (options.translate !== undefined) {
|
|
70
|
-
transcribeParams.translate = options.translate;
|
|
71
|
-
}
|
|
72
72
|
const task = await whisper.transcribe(pcmData, transcribeParams);
|
|
73
73
|
const results = await task.result;
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
text: cleanTranscription(text),
|
|
77
|
-
};
|
|
74
|
+
return { text: cleanTranscription(resultsToText(results)) };
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Cloudflare provider
|
|
78
|
+
// ============================================================================
|
|
79
|
+
function isCloudflareConfigured() {
|
|
80
|
+
return !!(process.env['CLOUDFLARE_ACCOUNT_ID'] && process.env['CLOUDFLARE_AUTH_KEY']);
|
|
81
|
+
}
|
|
82
|
+
async function transcribeWithCloudflare(audioPath, options = {}) {
|
|
83
|
+
if (!fs.existsSync(audioPath)) {
|
|
84
|
+
throw new Error(`Audio file not found: ${audioPath}`);
|
|
85
|
+
}
|
|
86
|
+
const accountId = process.env['CLOUDFLARE_ACCOUNT_ID'];
|
|
87
|
+
const authKey = process.env['CLOUDFLARE_AUTH_KEY'];
|
|
88
|
+
if (!accountId || !authKey) {
|
|
89
|
+
throw new Error('Cloudflare credentials not configured. Set CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY environment variables.');
|
|
90
|
+
}
|
|
91
|
+
const audioBuffer = fs.readFileSync(audioPath);
|
|
92
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/@cf/openai/whisper-large-v3-turbo`;
|
|
93
|
+
const response = await fetch(url, {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: {
|
|
96
|
+
'Authorization': `Bearer ${authKey}`,
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify({
|
|
100
|
+
audio: audioBuffer.toString('base64'),
|
|
101
|
+
task: options.translate ? 'translate' : 'transcribe',
|
|
102
|
+
vad_filter: true,
|
|
103
|
+
...(options.language && { language: options.language }),
|
|
104
|
+
}),
|
|
105
|
+
});
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
const errorBody = await response.text();
|
|
108
|
+
throw new Error(`Cloudflare API error: ${response.status} ${response.statusText} - ${errorBody}`);
|
|
109
|
+
}
|
|
110
|
+
const data = await response.json();
|
|
111
|
+
if (!data.success || !data.result?.text) {
|
|
112
|
+
const errorMessage = data.errors?.[0]?.message || 'Unknown Cloudflare API error';
|
|
113
|
+
throw new Error(`Cloudflare transcription failed: ${errorMessage}`);
|
|
114
|
+
}
|
|
115
|
+
return { text: cleanTranscription(data.result.text) };
|
|
116
|
+
}
|
|
117
|
+
function selectProvider() {
|
|
118
|
+
// Check for explicit provider selection (STT_PROVIDER takes priority, PROVIDER is fallback)
|
|
119
|
+
const explicitProvider = (process.env['STT_PROVIDER'] || process.env['PROVIDER'])?.toLowerCase();
|
|
120
|
+
if (explicitProvider) {
|
|
121
|
+
// Validate explicit provider configuration
|
|
122
|
+
switch (explicitProvider) {
|
|
123
|
+
case 'whisper.cpp':
|
|
124
|
+
if (!isWhisperConfigured()) {
|
|
125
|
+
throw new Error("STT_PROVIDER is set to 'whisper.cpp' but WHISPER_CPP_MODEL_PATH is not configured or model file does not exist.");
|
|
126
|
+
}
|
|
127
|
+
return 'whisper.cpp';
|
|
128
|
+
case 'cloudflare':
|
|
129
|
+
if (!isCloudflareConfigured()) {
|
|
130
|
+
throw new Error("STT_PROVIDER is set to 'cloudflare' but CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY are not configured.");
|
|
131
|
+
}
|
|
132
|
+
return 'cloudflare';
|
|
133
|
+
default:
|
|
134
|
+
throw new Error(`Unknown provider: ${explicitProvider}. Valid providers are: whisper.cpp, cloudflare`);
|
|
84
135
|
}
|
|
85
|
-
return transcribe_whispercpp(audio, options);
|
|
86
136
|
}
|
|
87
|
-
|
|
137
|
+
// Auto-detection priority: whisper.cpp > cloudflare
|
|
138
|
+
if (isWhisperConfigured())
|
|
139
|
+
return 'whisper.cpp';
|
|
140
|
+
if (isCloudflareConfigured())
|
|
141
|
+
return 'cloudflare';
|
|
142
|
+
throw new Error('No STT provider configured. Set WHISPER_CPP_MODEL_PATH or CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_AUTH_KEY environment variables.');
|
|
88
143
|
}
|
|
89
|
-
async function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
throw new Error('No STT provider configured. Set WHISPER_CPP_MODEL_PATH environment variable.');
|
|
144
|
+
async function transcribeFromPath(audioPath, options, provider) {
|
|
145
|
+
if (provider === 'cloudflare') {
|
|
146
|
+
return transcribeWithCloudflare(audioPath, options);
|
|
93
147
|
}
|
|
94
|
-
|
|
95
|
-
|
|
148
|
+
return transcribeWithWhisper(audioPath, options);
|
|
149
|
+
}
|
|
150
|
+
async function transcribeFromBuffer(audioBuffer, options, provider) {
|
|
151
|
+
const tempPath = generateTempPath('stt_input', 'audio');
|
|
96
152
|
fs.writeFileSync(tempPath, audioBuffer);
|
|
97
153
|
try {
|
|
98
|
-
|
|
99
|
-
return result;
|
|
154
|
+
return await transcribeFromPath(tempPath, options, provider);
|
|
100
155
|
}
|
|
101
156
|
finally {
|
|
102
157
|
if (fs.existsSync(tempPath)) {
|
|
@@ -104,6 +159,15 @@ async function transcribeBuffer(audioBuffer, options = {}) {
|
|
|
104
159
|
}
|
|
105
160
|
}
|
|
106
161
|
}
|
|
162
|
+
export async function transcribe(audio, options = {}) {
|
|
163
|
+
const provider = selectProvider();
|
|
164
|
+
return Buffer.isBuffer(audio)
|
|
165
|
+
? transcribeFromBuffer(audio, options, provider)
|
|
166
|
+
: transcribeFromPath(audio, options, provider);
|
|
167
|
+
}
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Cleanup handlers
|
|
170
|
+
// ============================================================================
|
|
107
171
|
async function freeWhisper() {
|
|
108
172
|
if (whisperInstance) {
|
|
109
173
|
await whisperInstance.free();
|
|
@@ -111,7 +175,6 @@ async function freeWhisper() {
|
|
|
111
175
|
currentModelPath = null;
|
|
112
176
|
}
|
|
113
177
|
}
|
|
114
|
-
// Automatically clean up Whisper instance on process exit
|
|
115
178
|
process.on('exit', () => {
|
|
116
179
|
if (whisperInstance) {
|
|
117
180
|
// Note: Cannot use async operations in 'exit' handler
|
|
@@ -120,7 +183,6 @@ process.on('exit', () => {
|
|
|
120
183
|
currentModelPath = null;
|
|
121
184
|
}
|
|
122
185
|
});
|
|
123
|
-
// Handle graceful shutdown signals
|
|
124
186
|
const shutdownHandler = async () => {
|
|
125
187
|
await freeWhisper();
|
|
126
188
|
process.exit(0);
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAWvB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAiND,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAMnH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@derogab/stt-proxy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A simple and lightweight proxy for seamless integration with multiple STT (Speech-to-Text) providers including Whisper.cpp",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"test": "vitest run",
|
|
30
30
|
"test:unit": "vitest run --exclude='**/*.integration.test.*'",
|
|
31
31
|
"test:whisper": "vitest run --testTimeout=300000 --hookTimeout=600000 test/whisper-cpp.integration.test.ts",
|
|
32
|
+
"test:cloudflare": "vitest run --testTimeout=60000 --hookTimeout=60000 test/cloudflare.integration.test.ts",
|
|
32
33
|
"test:watch": "vitest watch",
|
|
33
34
|
"test:coverage": "vitest run --coverage",
|
|
34
35
|
"typecheck": "tsc --noEmit -p tsconfig.esm.json"
|
|
@@ -43,6 +44,8 @@
|
|
|
43
44
|
"transcription",
|
|
44
45
|
"whisper",
|
|
45
46
|
"whisper.cpp",
|
|
47
|
+
"cloudflare",
|
|
48
|
+
"cloudflare-ai",
|
|
46
49
|
"proxy",
|
|
47
50
|
"gateway"
|
|
48
51
|
],
|