Transcripción de Voz con Whisper

Explicación del Código de Transcripción de Voz con Whisper

Este proyecto es un sistema de transcripción de voz en tiempo real que utiliza:

  • Whisper (modelo de IA de OpenAI para reconocimiento de voz)

  • Flask (backend en Python)

  • Web Audio API (para capturar audio del navegador)

  • Socket.IO (para comunicación en tiempo real)

Estructura del Proyecto

text
proyecto/
├── app.py          # Servidor backend
├── templates/
│   └── index.html  # Interfaz web
└── static/
    └── script.js   # Lógica del cliente

Requisitos para ejecutarlo

  1. Python 3.7+

  2. FFmpeg (debe estar instalado y accesible en el PATH)

  3. Dependencias de Python (instalables con pip)

Instalación

  1. Instala las dependencias:

bash
pip install flask flask-socketio eventlet openai-whisper
  1. Asegúrate de tener FFmpeg instalado:

bash
ffmpeg -version

Explicación detallada del código

1. app.py (Backend)

python
import whisper
import tempfile
from flask import Flask, render_template
from flask_socketio import SocketIO
import eventlet
import os
import subprocess

eventlet.monkey_patch()  # Necesario para SocketIO con Flask

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")

# Carga el modelo Whisper (base, small, medium, large)
model = whisper.load_model("base")

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('audio_chunk')
def handle_audio(data):
    # Crea archivos temporales
    with tempfile.NamedTemporaryFile(suffix=".webm", delete=False) as input_file:
        input_file.write(data)
        input_path = input_file.name

    with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as output_file:
        output_path = output_file.name

    # Convierte el audio a formato WAV con FFmpeg
    ffmpeg_cmd = [
        "ffmpeg", "-y", "-i", input_path,
        "-ar", "16000", "-ac", "1", output_path
    ]

    try:
        subprocess.run(ffmpeg_cmd, check=True)
        # Transcribe el audio
        result = model.transcribe(output_path, language='es')
        text = result.get('text', '').strip()
        if text:
            socketio.emit('transcription', text)
    except Exception as e:
        print("Error:", e)
    finally:
        # Limpia archivos temporales
        os.remove(input_path)
        os.remove(output_path)

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000)

2. index.html (Interfaz)

html
<!DOCTYPE html>
<html>
<head>
  <!-- Estructura básica y estilos -->
</head>
<body>
  <h1>🎙️ Dictador de Voz</h1>
  <textarea id="texto" placeholder="Aquí aparecerá la transcripción..." readonly></textarea>
  <button id="btn">Iniciar Dictado</button>
  <div id="status">Estado: Inactivo</div>

  <!-- Dependencias -->
  <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
  <script src="/static/script.js"></script>
</body>
</html>

3. script.js (Cliente)

javascript
const btn = document.getElementById('btn');
const texto = document.getElementById('texto');
const status = document.getElementById('status');

const socket = io();
let mediaRecorder;
let audioChunks = [];
let escuchando = false;

btn.addEventListener('click', async () => {
  if (!escuchando) {
    // Inicia la grabación
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder = new MediaRecorder(stream);
    
    mediaRecorder.ondataavailable = e => {
      if (e.data.size > 0) audioChunks.push(e.data);
    };

    mediaRecorder.onstop = async () => {
      // Envía el audio al servidor
      const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
      const arrayBuffer = await audioBlob.arrayBuffer();
      socket.emit('audio_chunk', new Uint8Array(arrayBuffer));
      status.textContent = 'Estado: Procesando...';
    };

    mediaRecorder.start();
    // Actualiza la interfaz
    status.textContent = 'Estado: Escuchando...';
    btn.textContent = 'Detener Dictado';
    escuchando = true;
  } else {
    // Detiene la grabación
    mediaRecorder.stop();
    status.textContent = 'Estado: Inactivo';
    btn.textContent = 'Iniciar Dictado';
    escuchando = false;
  }
});

// Recibe la transcripción del servidor
socket.on('transcription', (data) => {
  texto.value += data + ' ';
  status.textContent = 'Estado: Transcripción completada.';
});

Cómo funciona

  1. Cliente (navegador):

    • El usuario hace clic en "Iniciar Dictado"

    • El navegador solicita permiso para usar el micrófono

    • Comienza a grabar audio en formato WebM

    • Cuando se detiene, envía los fragmentos de audio al servidor

  2. Servidor:

    • Recibe los fragmentos de audio

    • Convierte WebM a WAV usando FFmpeg

    • Usa Whisper para transcribir el audio a texto

    • Envía el texto de vuelta al cliente

  3. Cliente:

    • Recibe el texto y lo muestra en el área de texto

Posibles problemas y soluciones

  1. Error al instalar Whisper:

    • Asegúrate de tener Python 3.7+

    • Prueba con pip install --upgrade --no-deps --force-reinstall whisper

  2. FFmpeg no encontrado:

    • Instala FFmpeg y asegúrate de que esté en tu PATH

    • En Windows, descárgalo de https://ffmpeg.org/

  3. Problemas de permisos del micrófono:

    • Asegúrate de que el navegador tenga permiso para usar el micrófono

    • La página debe servirse sobre HTTPS (o localhost)

  4. Rendimiento lento:

    • Usa un modelo más pequeño (tiny o base en lugar de medium/large)

    • Reduce la frecuencia de muestreo del audio

Este proyecto es excelente para aplicaciones de dictado, transcripción de reuniones, o cualquier sistema que necesite convertir voz a texto en tiempo real.

Comentarios

Entradas más populares de este blog

1-configurar Vosk para que utilice todos los recursos de mi pc

3-Whisper vs Vosk