89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import cors from 'cors';
|
|
import express from 'express';
|
|
import multer from 'multer';
|
|
import { nodewhisper } from 'nodejs-whisper';
|
|
|
|
const app = express();
|
|
const port = Number(process.env.STT_PORT ?? 3334);
|
|
const host = process.env.STT_HOST ?? '0.0.0.0';
|
|
const uploadDir = path.resolve(process.cwd(), '.stt-uploads');
|
|
const modelRootPath = path.resolve(process.cwd(), '.whisper-models');
|
|
const modelName = process.env.STT_MODEL ?? 'tiny.en';
|
|
|
|
fs.mkdirSync(uploadDir, { recursive: true });
|
|
fs.mkdirSync(modelRootPath, { recursive: true });
|
|
|
|
const upload = multer({ dest: uploadDir });
|
|
|
|
app.use(cors());
|
|
|
|
app.get('/health', (_request, response) => {
|
|
response.json({ ok: true, model: modelName });
|
|
});
|
|
|
|
app.post('/transcribe', upload.single('audio'), async (request, response) => {
|
|
if (!request.file) {
|
|
response.status(400).json({ error: 'Missing audio file' });
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const text = await nodewhisper(request.file.path, {
|
|
modelName,
|
|
autoDownloadModelName: modelName,
|
|
modelRootPath,
|
|
removeWavFileAfterTranscription: true,
|
|
withCuda: false,
|
|
logger: quietLogger,
|
|
whisperOptions: {
|
|
outputInText: false,
|
|
outputInSrt: false,
|
|
outputInVtt: false,
|
|
outputInCsv: false,
|
|
outputInJson: false,
|
|
outputInJsonFull: false,
|
|
outputInLrc: false,
|
|
outputInWords: false,
|
|
translateToEnglish: false,
|
|
splitOnWord: true,
|
|
noGpu: true,
|
|
},
|
|
});
|
|
|
|
response.json({ text: cleanTranscript(text) });
|
|
} catch (error) {
|
|
response.status(500).json({ error: error instanceof Error ? error.message : String(error) });
|
|
} finally {
|
|
safeUnlink(request.file.path);
|
|
}
|
|
});
|
|
|
|
app.listen(port, host, () => {
|
|
console.log(`STT server listening on http://${host}:${port}`);
|
|
console.log(`Whisper model: ${modelName}`);
|
|
});
|
|
|
|
const quietLogger = {
|
|
debug: () => undefined,
|
|
info: () => undefined,
|
|
log: () => undefined,
|
|
warn: console.warn,
|
|
error: console.error,
|
|
};
|
|
|
|
function cleanTranscript(value) {
|
|
return String(value)
|
|
.replace(/\[[^\]]*\]/g, ' ')
|
|
.replace(/\([^)]*\)/g, ' ')
|
|
.replace(/\s+/g, ' ')
|
|
.trim();
|
|
}
|
|
|
|
function safeUnlink(filePath) {
|
|
if (filePath && fs.existsSync(filePath)) {
|
|
fs.unlinkSync(filePath);
|
|
}
|
|
}
|