Transcripción con Whisper
Patrones listos para producción para transcripción de audio/video utilizando OpenAI Whisper.
Requisitos del Sistema
Opciones de Instalación
Opción 1: OpenAI Whisper (Python)
# macOS/Linux/Windows
pip install openai-whisper
# Verificar
whisper --help
Opción 2: whisper.cpp (C++ - más rápido)
# macOS
brew install whisper-cpp
# Linux - compilar desde fuente
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp && make
# Windows - usar binarios precompilados o compilar con cmake
Opción 3: Insanely Fast Whisper (acelerado por GPU)
pip install insanely-fast-whisper
Selección del Modelo
| Modelo | Tamaño | VRAM | Precisión | Velocidad | Caso de Uso |
|---|---|---|---|---|---|
| tiny | 39M | ~1GB | Baja | Más rápida | Previsualizaciones rápidas |
| base | 74M | ~1GB | Media | Rápida | Transcripciones preliminares |
| small | 244M | ~2GB | Buena | Media | Uso general |
| medium | 769M | ~5GB | Mejor | Lenta | Transcripciones de calidad |
| large-v3 | 1550M | ~10GB | Óptima | Más lenta | Producción final |
Recomendación: Comienza con small para un equilibrio velocidad/calidad. Usa large-v3 para la entrega final.
Transcripción Básica
Usando OpenAI Whisper
# Transcripción básica (detección automática de idioma)
whisper audio.mp3 --model small
# Especificar idioma y formato de salida
whisper audio.mp3 --model medium --language en --output_format srt
# Múltiples formatos de salida
whisper audio.mp3 --model small --output_format all
# Con marcas de tiempo y sincronización a nivel de palabra
whisper audio.mp3 --model small --word_timestamps True
Usando whisper.cpp
# Descargar el modelo primero
./models/download-ggml-model.sh base.en
# Transcribir
./main -m models/ggml-base.en.bin -f audio.wav -osrt
# Con marcas de tiempo
./main -m models/ggml-base.en.bin -f audio.wav -ocsv
Formatos de Salida
SRT (SubRip Subtitle)
1
00:00:01,000 --> 00:00:04,500
Hola y bienvenidos a este video.
2
00:00:05,000 --> 00:00:08,200
Hoy hablaremos sobre edición de video.
VTT (WebVTT)
WEBVTT
00:00:01.000 --> 00:00:04.500
Hola y bienvenidos a este video.
00:00:05.000 --> 00:00:08.200
Hoy hablaremos sobre edición de video.
JSON (con sincronización a nivel de palabra)
{
"text": "Hello and welcome to this video.",
"segments": [
{
"id": 0,
"start": 1.0,
"end": 4.5,
"text": " Hello and welcome to this video.",
"words": [
{"word": "Hello", "start": 1.0, "end": 1.3},
{"word": "and", "start": 1.4, "end": 1.5},
{"word": "welcome", "start": 1.6, "end": 2.0},
{"word": "to", "start": 2.1, "end": 2.2},
{"word": "this", "start": 2.3, "end": 2.5},
{"word": "video", "start": 2.6, "end": 3.0}
]
}
]
}
Extracción de Audio para Transcripción
Antes de transcribir un video, extrae el audio en el formato óptimo:
# Extraer audio como WAV (16kHz, mono - óptimo para Whisper)
ffmpeg -i video.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio.wav
# Extraer como WAV de alta calidad para archivo
ffmpeg -i video.mp4 -vn -c:a pcm_s16le audio.wav
# Extraer como MP3 comprimido (más pequeño, aún funciona)
ffmpeg -i video.mp4 -vn -c:a libmp3lame -q:a 2 audio.mp3
Sincronización de Tiempos
Convertir JSON de Whisper a Sincronización FCP
import json
def whisper_to_fcp_timing(whisper_json_path, fps=24):
"""Convertir la salida JSON de Whisper a sincronización compatible con FCP."""
with open(whisper_json_path) as f:
data = json.load(f)
segments = []
for seg in data.get("segments", []):
segments.append({
"start_time": seg["start"],
"end_time": seg["end"],
"start_frame": int(seg["start"] * fps),
"end_frame": int(seg["end"] * fps),
"text": seg["text"].strip(),
"words": seg.get("words", [])
})
return segments
Sincronización Precisión de Fotograma
# Obtener recuento exacto de fotogramas y duración
ffprobe -v error -count_frames -select_streams v:0 \
-show_entries stream=nb_read_frames,duration,r_frame_rate \
-of json video.mp4
Diarización de Hablantes
Para contenido con múltiples hablantes, usa pyannote.audio:
pip install pyannote.audio
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained("pyannote/[email protected]")
diarization = pipeline("audio.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"{turn.start:.1f}s - {turn.end:.1f}s: {speaker}")
Procesamiento por Lotes
#!/bin/bash
# Transcribir todos los videos en el directorio
MODEL="small"
OUTPUT_DIR="transcripts"
mkdir -p "$OUTPUT_DIR"
for video in *.mp4 *.mov *.avi; do
[[ -f "$video" ]] || continue
base="${video%.*}"
# Extraer audio
ffmpeg -i "$video" -ar 16000 -ac 1 -c:a pcm_s16le "/tmp/${base}.wav" -y
# Transcribir
whisper "/tmp/${base}.wav" --model "$MODEL" \
--output_format all \
--output_dir "$OUTPUT_DIR"
# Limpiar audio temporal
rm "/tmp/${base}.wav"
echo "Transcrito: $video"
done
Optimización de Calidad
Mejorar la Precisión
- Reducción de ruido antes de la transcripción:
ffmpeg -i noisy_audio.wav -af "highpass=f=200,lowpass=f=3000,afftdn=nf=-25" clean_audio.wav
- Usar pista de idioma:
whisper audio.mp3 --language en --model medium
- Proporcionar un aviso inicial para contexto:
whisper audio.mp3 --initial_prompt "Discusión técnica sobre software de edición de video."
Consejos de Rendimiento
- Aceleración por GPU (si está disponible):
whisper audio.mp3 --model large-v3 --device cuda
- Procesar en fragmentos para videos largos:
# Dividir audio en fragmentos de 10 minutos
# Transcribir cada fragmento
# Fusionar resultados con ajuste de desplazamiento de tiempo
Manejo de Errores
# Validar archivo de audio antes de la transcripción
validate_audio() {
local file="$1"
if ffprobe -v error -select_streams a:0 -show_entries stream=codec_type -of csv=p=0 "$file" 2>/dev/null | grep -q "audio"; then
return 0
else
echo "Error: No se encontró flujo de audio en $file"
return 1
fi
}
# Verificar instalación de Whisper
check_whisper() {
if command -v whisper &> /dev/null; then
echo "Whisper disponible"
return 0
else
echo "Error: Whisper no instalado. Ejecuta: pip install openai-whisper"
return 1
fi
}
Habilidades Relacionadas
- ffmpeg-core - Extracción y preprocesamiento de audio
- final-cut-pro - Importar transcripciones como títulos o marcadores