Files
say/src/services/whisper.js
T

71 lines
2.1 KiB
JavaScript

/**
* WhisperService — распознавание речи (speech-to-text).
*
* Принимает буфер аудио + MIME-тип,
* отправляет на OpenAI-совместимый /v1/audio/transcriptions,
* возвращает распознанный текст.
*/
const fetch = require('node-fetch');
const FormData = require('form-data');
const { WHISPER_URL, WHISPER_MODEL, API_KEY } = require('../config');
/**
* @param {Buffer} audioBuffer — сырые байты аудио
* @param {string} mimeType — MIME-тип (audio/webm, audio/wav, ...)
* @param {string} language — язык распознавания (ISO 639-1)
* @returns {Promise<string>} — распознанный текст
*/
async function transcribe(audioBuffer, mimeType = 'audio/webm', language = 'ru') {
if (!API_KEY) throw new Error('API_KEY не задан в переменных окружения');
const suffix = mimeToExt(mimeType);
const form = new FormData();
form.append('file', audioBuffer, {
filename: `audio${suffix}`,
contentType: mimeType,
});
form.append('model', WHISPER_MODEL);
form.append('language', language);
console.log(`Whisper: отправка ${audioBuffer.length} байт (${mimeType})`);
const resp = await fetch(WHISPER_URL, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
},
body: form,
timeout: 30000,
});
if (!resp.ok) {
const text = await resp.text();
throw new Error(`Whisper ошибка ${resp.status}: ${text.slice(0, 200)}`);
}
const data = await resp.json();
const result = (data.text || '').trim();
console.log(`Whisper: распознано ${result.length} символов`);
return result;
}
/** MIME → расширение файла */
function mimeToExt(mime) {
const map = {
'audio/webm': '.webm',
'audio/wav': '.wav',
'audio/wave': '.wav',
'audio/mp3': '.mp3',
'audio/mpeg': '.mp3',
'audio/ogg': '.ogg',
'audio/flac': '.flac',
};
return map[mime] || '.webm';
}
module.exports = { transcribe };