Convertir audio a texto con Python permite transcribir entrevistas, reuniones, clases, notas de voz y vídeos sin escribir todo manualmente. Existen dos enfoques principales: utilizar un servicio remoto de reconocimiento de voz o ejecutar un modelo local como Whisper. Los servicios remotos son fáciles de integrar, pero envían el audio a un proveedor. Los modelos locales ofrecen mayor privacidad y control, aunque requieren más memoria, tiempo de procesamiento y una instalación adecuada.
Para construir una solución mantenible conviene saber trabajar con archivos y rutas mediante pathlib, crear una interfaz de terminal con argparse, mostrar barras de progreso con tqdm y gestionar errores con try y except.
Elegir entre reconocimiento remoto y local
Una API remota suele ser adecuada para aplicaciones pequeñas, equipos con poca capacidad y casos donde el proveedor cumple los requisitos de privacidad. Un modelo local es preferible para archivos sensibles, procesamiento frecuente o trabajo sin conexión. También puedes combinar ambos: usar Whisper local como opción predeterminada y una API como respaldo.
Instalar Whisper
El proyecto oficial de Whisper está disponible en el repositorio oficial de OpenAI. Crea un entorno virtual e instala el paquete:
python -m venv .venv
.venv\Scripts\activate
python -m pip install -U openai-whisperEn macOS o Linux activa con source .venv/bin/activate. Whisper depende de FFmpeg para leer formatos como MP3, M4A y MP4. Instálalo desde una fuente oficial de tu sistema y verifica:
ffmpeg -versionPrimera transcripción
import whisper
modelo = whisper.load_model("base")
resultado = modelo.transcribe("audio.mp3", language="es")
print(resultado["text"])Los modelos más pequeños consumen menos recursos y son más rápidos, pero pueden cometer más errores. Los modelos grandes suelen mejorar la precisión a costa de tiempo y memoria. Prueba con audios representativos antes de decidir.
Detectar automáticamente el idioma
resultado = modelo.transcribe("audio.mp3")
print("Idioma detectado:", resultado["language"])
print(resultado["text"])La detección puede fallar en fragmentos cortos, ruido intenso o conversaciones multilingües. Cuando conoces el idioma, indicarlo explícitamente puede mejorar la estabilidad.
Guardar la transcripción
from pathlib import Path
entrada = Path("audio.mp3")
salida = entrada.with_suffix(".txt")
salida.write_text(
resultado["text"].strip(),
encoding="utf-8"
)Utiliza UTF-8 para conservar acentos y caracteres especiales. No sobrescribas un archivo existente sin confirmación o una opción explícita.
Obtener segmentos y marcas de tiempo
for segmento in resultado["segments"]:
inicio = segmento["start"]
fin = segmento["end"]
texto = segmento["text"].strip()
print(f"[{inicio:.2f} - {fin:.2f}] {texto}")Estos segmentos sirven para subtítulos, navegación y revisión. Puedes convertir los segundos al formato HH:MM:SS,mmm y generar un archivo SRT.
Generar subtítulos SRT
def tiempo_srt(segundos: float) -> str:
milisegundos = int((segundos % 1) * 1000)
total = int(segundos)
horas, resto = divmod(total, 3600)
minutos, segundos = divmod(resto, 60)
return f"{horas:02}:{minutos:02}:{segundos:02},{milisegundos:03}"
def guardar_srt(segmentos, ruta):
lineas = []
for indice, segmento in enumerate(segmentos, start=1):
lineas.extend([
str(indice),
f"{tiempo_srt(segmento['start'])} --> {tiempo_srt(segmento['end'])}",
segmento["text"].strip(),
"",
])
Path(ruta).write_text("\n".join(lineas), encoding="utf-8")Procesar una carpeta completa
from pathlib import Path
FORMATOS = {".mp3", ".wav", ".m4a", ".flac", ".mp4"}
def transcribir_carpeta(modelo, carpeta: Path):
for archivo in carpeta.iterdir():
if archivo.is_file() and archivo.suffix.lower() in FORMATOS:
salida = archivo.with_suffix(".txt")
if salida.exists():
print(f"Omitido: {salida.name}")
continue
resultado = modelo.transcribe(str(archivo), language="es")
salida.write_text(resultado["text"].strip(), encoding="utf-8")Carga el modelo una sola vez y reutilízalo. Cargarlo para cada archivo aumenta mucho el tiempo total.
Crear una interfaz de terminal
import argparse
parser = argparse.ArgumentParser(description="Transcribe audio con Whisper")
parser.add_argument("entrada", help="Archivo o carpeta")
parser.add_argument("--modelo", default="base")
parser.add_argument("--idioma", default=None)
parser.add_argument("--formato", choices=["txt", "srt"], default="txt")
args = parser.parse_args()Valida que la ruta exista y que el formato sea compatible. Para un programa distribuido, muestra mensajes claros cuando FFmpeg no esté instalado o el modelo no pueda descargarse.
Usar SpeechRecognition
La biblioteca SpeechRecognition ofrece una interfaz común para varios motores. Su página oficial en PyPI documenta instalación, micrófonos y servicios compatibles.
import speech_recognition as sr
reconocedor = sr.Recognizer()
with sr.AudioFile("audio.wav") as fuente:
audio = reconocedor.record(fuente)
try:
texto = reconocedor.recognize_google(audio, language="es-ES")
print(texto)
except sr.UnknownValueError:
print("No se pudo entender el audio")
except sr.RequestError as error:
print("Fallo del servicio:", error)Algunos motores requieren Internet, credenciales o tienen límites. Revisa las condiciones antes de procesar contenido de terceros.
Convertir formatos con FFmpeg
Para normalizar a WAV mono de 16 kHz:
ffmpeg -i entrada.mp3 -ar 16000 -ac 1 salida.wavEn Python puedes ejecutar FFmpeg mediante subprocess.run sin shell=True:
import subprocess
subprocess.run([
"ffmpeg", "-y", "-i", "entrada.mp3",
"-ar", "16000", "-ac", "1", "salida.wav"
], check=True)No construyas un comando de shell concatenando nombres recibidos del usuario. Pasar una lista de argumentos reduce riesgos de inyección.
Mejorar la calidad
Una grabación clara mejora más que muchos ajustes. Acerca el micrófono, reduce eco, evita música de fondo y utiliza un volumen estable. Para reuniones, identifica a los participantes y evita que hablen al mismo tiempo. Whisper transcribe palabras, pero no realiza diarización de hablantes por sí solo.
Los nombres propios, siglas y términos técnicos pueden quedar mal. Un paso de revisión o un glosario posterior ayuda a corregirlos. No reemplaces palabras automáticamente sin comprobar el contexto.
Dividir audios muy largos
Procesar horas de audio de una sola vez puede consumir memoria. Divide el archivo en fragmentos con FFmpeg, conserva un pequeño solapamiento y ajusta las marcas de tiempo al recombinar. El solapamiento reduce palabras cortadas en el límite, pero debes eliminar duplicados.
Privacidad y consentimiento
Antes de grabar o transcribir conversaciones, verifica las leyes y reglas aplicables. Obtén consentimiento cuando sea necesario. Si utilizas una API externa, informa dónde se procesarán los datos y durante cuánto tiempo se conservarán. Para información médica, legal o empresarial sensible, considera procesamiento local y almacenamiento cifrado.
Errores frecuentes
Los fallos más comunes son no instalar FFmpeg, usar una ruta incorrecta, intentar procesar un formato no compatible, cargar el modelo repetidamente, quedarse sin memoria y confiar ciegamente en la transcripción. También es frecuente olvidar UTF-8 o sobrescribir resultados ya revisados.
Estructura recomendada
transcriptor/
├── app.py
├── audio/
├── resultados/
├── requirements.txt
└── README.mdSepara entrada y resultados, fija versiones y documenta el modelo utilizado. Si varias personas revisan las transcripciones, guarda también el archivo original, los segmentos y la versión corregida.
Conclusión
Python permite crear un transcriptor gratuito y flexible con Whisper local o SpeechRecognition. Una solución confiable debe validar archivos, reutilizar el modelo, registrar errores, conservar UTF-8 y proteger la privacidad. Las marcas de tiempo y la exportación SRT convierten el proyecto en una herramienta útil para entrevistas, clases y vídeos. La transcripción automática acelera el trabajo, pero una revisión humana sigue siendo necesaria cuando la precisión importa.






