clases-texto / app.py
srjosueaaron's picture
Update app.py
66acb42 verified
Raw
History Blame Contribute Delete
3.8 kB
import os
import tempfile
from datetime import datetime
import gradio as gr
from faster_whisper import WhisperModel
# ----------------------------------------------------------------------
# Configuración del modelo
# ----------------------------------------------------------------------
# Tamaños disponibles (de menor a mayor precisión/lentitud):
# tiny, base, small, medium, large-v3
# En una Space gratuita (CPU) "small" es un buen balance velocidad/calidad.
# Se puede cambiar sin tocar código con la variable de entorno WHISPER_MODEL
# (Settings > Variables and secrets en la Space de Hugging Face).
MODEL_SIZE = os.environ.get("WHISPER_MODEL", "small")
DEVICE = "cpu"
COMPUTE_TYPE = "int8" # cuantización para que corra rápido en CPU
IDIOMAS = {
"Español": "es",
"Inglés": "en",
"Portugués": "pt",
"Francés": "fr",
}
print(f"Cargando modelo Whisper ({MODEL_SIZE})... esto puede tardar un momento.")
model = WhisperModel(MODEL_SIZE, device=DEVICE, compute_type=COMPUTE_TYPE)
print("Modelo cargado correctamente.")
def format_timestamp(segundos: float) -> str:
m, s = divmod(int(segundos), 60)
h, m = divmod(m, 60)
if h > 0:
return f"{h:02d}:{m:02d}:{s:02d}"
return f"{m:02d}:{s:02d}"
def transcribir(audio_path, idioma, progreso=gr.Progress()):
if audio_path is None:
return "⚠️ Por favor sube un archivo de audio primero.", None
progreso(0, desc="Analizando audio...")
idioma_code = None if idioma == "Detectar automáticamente" else IDIOMAS[idioma]
segments, info = model.transcribe(
audio_path,
language=idioma_code,
beam_size=5,
vad_filter=True, # filtra silencios largos, acelera y limpia el resultado
)
duracion_total = info.duration if info.duration else 1
lineas = []
for segment in segments:
progreso(min(segment.end / duracion_total, 1.0), desc="Transcribiendo...")
inicio = format_timestamp(segment.start)
lineas.append(f"[{inicio}] {segment.text.strip()}")
resultado = "\n".join(lineas) if lineas else "No se detectó voz en el audio."
nombre_archivo = f"transcripcion_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
ruta_salida = os.path.join(tempfile.gettempdir(), nombre_archivo)
with open(ruta_salida, "w", encoding="utf-8") as f:
f.write(resultado)
progreso(1.0, desc="¡Listo!")
return resultado, ruta_salida
with gr.Blocks(title="Transcriptor de Clases") as demo:
gr.Markdown(
"""
# 🎙️ Transcriptor de Clases
Sube el audio de tu clase (mp3, wav, m4a, etc.) y obtén la transcripción
con marcas de tiempo. Funciona mejor con audios claros y sin mucho ruido de fondo.
"""
)
with gr.Row():
with gr.Column():
audio_input = gr.Audio(
label="Audio de la clase",
type="filepath",
sources=["upload"],
)
idioma_input = gr.Dropdown(
choices=["Detectar automáticamente"] + list(IDIOMAS.keys()),
value="Español",
label="Idioma del audio",
)
boton = gr.Button("Transcribir", variant="primary")
gr.Markdown(
"_Audios largos (más de 30-40 min) pueden tardar varios minutos "
"en una Space gratuita, ya que corre en CPU._"
)
with gr.Column():
salida_texto = gr.Textbox(label="Transcripción", lines=20, buttons=["copy"])
salida_archivo = gr.File(label="Descargar transcripción (.txt)")
boton.click(
fn=transcribir,
inputs=[audio_input, idioma_input],
outputs=[salida_texto, salida_archivo],
)
if __name__ == "__main__":
demo.launch()