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:

bash
Copy
Download
npm install vosk express socket.io cors

Crea un servidor (server.js):

javascript
Copy
Download
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:

html
Copy
Download
Run
<!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:

  1. Descarga los archivos necesarios:

  2. HTML básico:

html
Copy
Download
Run
<!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

  1. 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)

  2. Rendimiento:

    • Los modelos grandes ofrecen mejor precisión pero consumen más recursos

    • En navegador, los modelos muy grandes pueden causar problemas

  3. Seguridad:

    • El navegador pedirá permiso para usar el micrófono

    • En producción, usa HTTPS para las APIs de audio

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

Entradas más populares de este blog

index

Proyecto de Transcripción de Voz en Tiempo Real