/** * 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} — распознанный текст */ 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 };