proyecto
El código completo con las correcciones para solucionar el problema de CORS:
server.js (actualizado)
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)
<!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:
tu-proyecto/
├── public/
│ ├── index.html
├── modelo-es/ (tu modelo Vosk descargado)
├── server.js
├── package.jsonPasos para implementar:
Crea la estructura de directorios como se muestra arriba
Coloca el archivo
index.htmlen la carpetapublicAsegúrate de tener el modelo Vosk en la carpeta
modelo-esInstala las dependencias necesarias con:
npm install express cors vosk socket.ioInicia el servidor con:
node server.jsAccede 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
Publicar un comentario