proyecto

 El código completo con las correcciones para solucionar el problema de CORS:

server.js (actualizado)

javascript
const express = require('express');
const cors = require('cors');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http, {
  cors: {
    origin: "*", // Permite todos los orígenes (en producción especifica tu dominio)
    methods: ["GET", "POST"]
  }
});
const vosk = require('vosk');
const fs = require('fs');
const path = require('path');

// Configura Express para servir archivos estáticos
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());

// Carga el modelo Vosk
const MODEL_PATH = "modelo-es";
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
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');
  });
});

// Ruta para servir el archivo HTML
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

http.listen(3000, () => {
  console.log('Servidor escuchando en http://localhost:3000');
});

index.html (actualizado)

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="/socket.io/socket.io.js"></script>
    <script>
        const socket = io(); // Ahora usa el mismo origen
        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>

Estructura de directorios recomendada:

text
tu-proyecto/
├── public/
│   ├── index.html
├── modelo-es/     (tu modelo Vosk descargado)
├── server.js
├── package.json

Pasos para implementar:

  1. Crea la estructura de directorios como se muestra arriba

  2. Coloca el archivo index.html en la carpeta public

  3. Asegúrate de tener el modelo Vosk en la carpeta modelo-es

  4. Instala las dependencias necesarias con:

    bash
    npm install express cors vosk socket.io
  5. Inicia el servidor con:

    bash
    node server.js
  6. Accede a la aplicación en http://localhost:3000

Estas modificaciones solucionarán:

  • El problema de CORS con la configuración adecuada

  • La carga del cliente Socket.IO desde el mismo servidor

  • El servicio del archivo HTML desde Express

  • La comunicación bidireccional entre cliente y servidor

La aplicación ahora debería funcionar correctamente sin los errores de CORS que estabas experimentando

Comentarios

Entradas más populares de este blog

index

Vosk en una Página Web

Proyecto de Transcripción de Voz en Tiempo Real