Reconocimiento de voz Deepgram en tiempo real en una PWA

Fecha de publicación: 2023-03-10

Deepgram ofrece servicios de reconocimiento de voz y procesamiento de lenguaje natural. Este caso muestra cómo convertir voz en directo a texto dentro de una aplicación web. Demostración: deepgram.demo.wiredgeese.com.

SDK y límite de seguridad

Deepgram dispone de un SDK para JavaScript. El enfoque histórico de demostración lo conectaba desde la aplicación del navegador:

npm install @deepgram/sdk
cp ./node_modules/@deepgram/sdk/dist/browser/index.js \
  ./js/lib/deepgram.browser.sdk.mjs
import { Deepgram } from './lib/deepgram.browser.sdk.mjs';
const deepgram = new Deepgram(DEEPGRAM_API_KEY);

Es útil para aprender, pero una clave API permanente no debe ir en código de cliente. En un producto real, el servidor entrega un token limitado y de corta duración o actúa como intermediario de confianza. Así se controlan gasto, permisos y revocación.

Para un audio ya grabado se puede usar HTTP: se envía archivo o URL y se recibe texto. La transcripción en directo necesita en cambio un socket permanente.

Transcripción en streaming

La secuencia es directa:

  1. abrir un WebSocket con parámetros de reconocimiento, incluido idioma;
  2. pedir acceso al micrófono desde el navegador;
  3. grabar audio en fragmentos pequeños;
  4. enviar los fragmentos por el socket y recibir resultados por la misma conexión.
const deepgram = new Deepgram(API_KEY);
const socket = deepgram.transcription.live({ language: LANG });
socket.addEventListener('open', onSocketOpen);
socket.addEventListener('message', onSocketMessage);

La captura se inicia con MediaRecorder:

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
recorder.start(TIME_SLICE);
TIME_SLICE define el intervalo del evento dataavailable. Allí enviamos el fragmento únicamente si el socket sigue abierto:

recorder.addEventListener('dataavailable', (event) => { if (event.data.size > 0 && socket.readyState === 1) { socket.send(event.data); } });

La respuesta es JSON y el texto está en data.channel.alternatives[0].transcript.

Cómo tratar el resultado

El servicio devuelve versiones intermedias y finales de una frase. Incluye start, duration, las marcas is_final/speech_final y confidence por palabra. La interfaz no debe añadir cada respuesta sin más: mantiene segmentos por tiempo y sustituye el borrador por el texto final.

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.
}

La calidad depende de idioma, ruido, micrófono, modelo y vocabulario del dominio. Antes de implantarlo hay que probar situaciones reales, pedir consentimiento claro para el micrófono y explicar el almacenamiento de audio y transcripciones.

Conclusión

Deepgram permite añadir a una PWA la transcripción de grabaciones y voz en directo: el navegador captura sonido, WebSocket transporta el flujo y la aplicación compone el texto a partir de las respuestas. Es útil para notas, formularios por voz y soporte, siempre que la arquitectura proteja credenciales y respete la privacidad de quienes hablan. Wiredgeese puede diseñar e implementar esta integración para un producto concreto.

Fragmentos adicionales de código fuente

});
mediaRecorder.start(DEF_TIME_SLICE);
}); The DEF_TIME_SLICE parameter refers to the interval at which the dataavailable event is triggered and recorded by the media recorder.
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
{
{
{
},
{
},
{
}
]
}
]
},
},
}
}