Распознавание речи Deepgram в реальном времени в PWA
Дата публикации: 2023-03-10Deepgram предоставляет сервисы распознавания речи и обработки естественного языка. В этом кейсе показано, как использовать его для преобразования живой речи в текст внутри веб-приложения. Демонстрация: deepgram.demo.wiredgeese.com.
SDK и граница безопасности
Для JavaScript доступен SDK Deepgram. Исторический демо-подход подключал его к браузерному приложению:
npm install @deepgram/sdk cp ./node_modules/@deepgram/sdk/dist/browser/index.js \ ./js/lib/deepgram.browser.sdk.mjsimport { Deepgram } from './lib/deepgram.browser.sdk.mjs'; const deepgram = new Deepgram(DEEPGRAM_API_KEY);
Для демонстрации это помогает быстро понять интеграцию, но постоянный API-ключ нельзя безопасно помещать в клиентский код. В рабочем продукте сервер выдаёт краткоживущий ограниченный токен либо сам выступает доверенным посредником. Это позволяет контролировать расходы, права и отзыв доступа.
Для заранее записанного аудио API можно вызвать обычным HTTP-запросом: отправить файл или URL и получить текст. Потоковая расшифровка устроена иначе — нужен постоянный сокет.
Потоковая расшифровка
Последовательность проста:
- открыть WebSocket с параметрами распознавания, включая язык;
- получить доступ к микрофону через браузер;
- записывать звук небольшими частями;
- отправлять части в сокет и получать результаты по тому же соединению.
const deepgram = new Deepgram(API_KEY);
const socket = deepgram.transcription.live({ language: LANG });
socket.addEventListener('open', onSocketOpen);
socket.addEventListener('message', onSocketMessage);
Запись запускает стандартный MediaRecorder:
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
recorder.start(TIME_SLICE);
TIME_SLICE задаёт интервал события dataavailable. В нём отправляем фрагмент, только если сокет открыт:
recorder.addEventListener('dataavailable', (event) => {
if (event.data.size > 0 && socket.readyState === 1) {
socket.send(event.data);
}
});
Ответ приходит как JSON, а текст лежит в data.channel.alternatives[0].transcript.
Как обработать результат
Сервис возвращает промежуточные и финальные версии фразы. В ответе есть start, duration, флаги is_final/speech_final и уровень уверенности confidence для слов. Поэтому интерфейс не должен просто дописывать каждый ответ: он хранит сегменты по времени и заменяет черновой текст финальным.
function onSocketMessage(message) {
const data = JSON.parse(message.data);
const transcript = data.channel.alternatives[0].transcript;
// Merge transcript by start/duration and final-state flags.
}
Качество зависит от языка, шума, микрофона, модели и словаря предметной области. Перед внедрением нужны тесты на реальных сценариях, явное согласие на доступ к микрофону и понятная политика хранения аудио и транскриптов.
Итог
Deepgram позволяет добавить в PWA расшифровку записей и живой речи: браузер захватывает звук, WebSocket передаёт поток, а приложение собирает текст из ответов. Такой сценарий подходит для заметок, голосовых форм и поддержки, если архитектура защищает учётные данные и уважает приватность говорящих. Wiredgeese может спроектировать и реализовать такую интеграцию под конкретный продукт.
Дополнительные фрагменты исходного кода
mediaRecorder.addEventListener(‘dataavailable’, async (event) => {
if (event.data.size > 0 && deepgramSocket.readyState === 1) {
deepgramSocket.send(event.data);
}
});
function onSocketMessage(message) {
const received = JSON.parse(message.data);
console.log(received);
}
data.channel.alternatives[0].transcript
{
{
{
},
{
},
{
} ] } ] },
},
} }