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