Vosk en una Página Web
Implementación de Vosk en una Página Web
http://localhost:3000/index1.html
node server.js
Para usar Vosk en una página web, necesitaremos un enfoque diferente al uso directo en Python, ya que Vosk está escrito en C++ y normalmente se usa con bindings de Python/Java/Node.js. Aquí te mostraré cómo integrarlo en una aplicación web.
Opción 1: Vosk con Node.js en el backend + interfaz web
Esta es la solución más práctica para usar Vosk en una aplicación web.
1. Configuración del backend con Node.js
Primero, instala los paquetes necesarios:
npm install vosk express socket.io corsCrea un servidor (server.js):
const express = require('express');
const cors = require('cors');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const vosk = require('vosk');
// Configura CORS
app.use(cors());
// Carga el modelo (descárgalo primero de https://alphacephei.com/vosk/models)
const MODEL_PATH = "modelo-es"; // Cambia a tu modelo descargado
if (!fs.existsSync(MODEL_PATH)) {
console.error("Modelo no encontrado en " + MODEL_PATH);
process.exit(1);
}
vosk.setLogLevel(0);
const model = new vosk.Model(MODEL_PATH);
// Configura Socket.io para comunicación en tiempo real
io.on('connection', (socket) => {
console.log('Cliente conectado');
let rec = null;
socket.on('start', (sampleRate) => {
if (rec !== null) return;
rec = new vosk.Recognizer({model: model, sampleRate: sampleRate});
});
socket.on('audio', (data) => {
if (rec != null && rec.acceptWaveform(data)) {
const result = rec.result();
socket.emit('result', result);
}
});
socket.on('stop', () => {
if (rec !== null) {
const finalResult = rec.finalResult();
socket.emit('final', finalResult);
rec = null;
}
});
socket.on('disconnect', () => {
console.log('Cliente desconectado');
});
});
http.listen(3000, () => {
console.log('Servidor escuchando en http://localhost:3000');
});2. Interfaz web (HTML/JavaScript)
Crea un archivo index.html:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Reconocimiento de Voz con Vosk</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
#result { border: 1px solid #ccc; padding: 10px; min-height: 50px; margin: 20px 0; }
button { padding: 10px 15px; font-size: 16px; cursor: pointer; }
</style>
</head>
<body>
<h1>Reconocimiento de Voz con Vosk</h1>
<button id="startBtn">Comenzar</button>
<button id="stopBtn" disabled>Detener</button>
<div id="result"></div>
<div id="finalResult"></div>
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
<script>
const socket = io('http://localhost:3000');
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const resultDiv = document.getElementById('result');
const finalResultDiv = document.getElementById('finalResult');
let audioContext;
let processor;
let microphone;
// Configuración del audio
async function setupAudio() {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
microphone = audioContext.createMediaStreamSource(stream);
processor = audioContext.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (e) => {
const audioData = e.inputBuffer.getChannelData(0);
const raw = convertFloat32ToInt16(audioData);
socket.emit('audio', raw);
};
microphone.connect(processor);
processor.connect(audioContext.destination);
}
// Convertir Float32 a Int16
function convertFloat32ToInt16(buffer) {
const l = buffer.length;
const buf = new Int16Array(l);
for (let i = 0; i < l; i++) {
buf[i] = Math.min(1, buffer[i]) * 0x7FFF;
}
return buf.buffer;
}
// Eventos de los botones
startBtn.addEventListener('click', async () => {
try {
await setupAudio();
socket.emit('start', audioContext.sampleRate);
startBtn.disabled = true;
stopBtn.disabled = false;
resultDiv.textContent = "Escuchando...";
} catch (err) {
console.error("Error al iniciar:", err);
}
});
stopBtn.addEventListener('click', () => {
if (processor) {
processor.disconnect();
microphone.disconnect();
socket.emit('stop');
startBtn.disabled = false;
stopBtn.disabled = true;
}
});
// Escuchar resultados
socket.on('result', (data) => {
const result = JSON.parse(data);
if (result.text) {
resultDiv.textContent = result.text;
}
});
socket.on('final', (data) => {
const finalResult = JSON.parse(data);
if (finalResult.text) {
finalResultDiv.textContent = "Resultado final: " + finalResult.text;
}
});
</script>
</body>
</html>Opción 2: Vosk-js (versión WebAssembly)
Existe una versión de Vosk compilada a WebAssembly para usar directamente en el navegador:
Descarga los archivos necesarios:
HTML básico:
<!DOCTYPE html>
<html>
<head>
<title>Vosk.js en el navegador</title>
<script src="vosk.js"></script>
</head>
<body>
<button id="start">Iniciar</button>
<div id="output"></div>
<script>
const modelUrl = 'model-pequeño-es'; // Modelo pequeño en español
async function initVosk() {
// Cargar el modelo
const model = new Vosk.Model(modelUrl);
// Configurar el reconocedor
const rec = new Vosk.Recognizer({
model: model,
sampleRate: 16000
});
// Configurar el audio del navegador
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioContext = new AudioContext();
const source = audioContext.createMediaStreamSource(stream);
const processor = audioContext.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (e) => {
const audioData = e.inputBuffer.getChannelData(0);
const raw = new Int16Array(audioData.length);
for (let i = 0; i < audioData.length; i++) {
raw[i] = Math.min(1, audioData[i]) * 32767;
}
if (rec.acceptWaveform(raw)) {
const result = JSON.parse(rec.result());
document.getElementById('output').textContent = result.text;
}
};
source.connect(processor);
processor.connect(audioContext.destination);
}
document.getElementById('start').addEventListener('click', initVosk);
</script>
</body>
</html>Consideraciones importantes
Modelos de lenguaje: Debes descargar los modelos de español desde https://alphacephei.com/vosk/models
Para web, mejor usar modelos pequeños (ej.
vosk-model-small-es-0.42)
Rendimiento:
Los modelos grandes ofrecen mejor precisión pero consumen más recursos
En navegador, los modelos muy grandes pueden causar problemas
Seguridad:
El navegador pedirá permiso para usar el micrófono
En producción, usa HTTPS para las APIs de audio
Alternativas:
Para una solución más simple (pero menos precisa), considera la Web Speech API
Para máxima precisión, el enfoque Node.js backend es mejor
¿Necesitas ayuda con algún aspecto específico de esta implementación
Comentarios
Publicar un comentario