¿Qué hace Editor de Video FFmpeg?
Edita video, audio e imágenes desde la terminal usando ffmpeg y el script auxiliar fftools.py.
Herramienta CLI
Todas las operaciones pasan por el script auxiliar. Encuéntralo en la ubicación donde clonaste el repositorio, o en:
SCRIPT="~/.claude/skills/ffmpeg/scripts/fftools.py"
Toda la salida es JSON.
Referencia de Comandos
# INFO — Obtener detalles del archivo (duración, resolución, códecs, tamaño)
python3 $SCRIPT info entrada.mp4
# CUT — Extraer un segmento
python3 $SCRIPT cut entrada.mp4 salida.mp4 --inicio 00:01:30 --fin 00:02:45
python3 $SCRIPT cut entrada.mp4 salida.mp4 --inicio 00:01:30 --duracion 30
# MERGE — Concatenar múltiples videos
python3 $SCRIPT merge video1.mp4 video2.mp4 video3.mp4 -o fusionado.mp4
python3 $SCRIPT merge video1.mp4 video2.mp4 -o fusionado.mp4 --recode # diferentes códecs
# EXTRACT-AUDIO — Extraer pista de audio
python3 $SCRIPT extract-audio entrada.mp4 salida.mp3
python3 $SCRIPT extract-audio entrada.mp4 salida.opus --tasa-bits 128k
# SUBTITLES — Incrustar subtítulos en el video
python3 $SCRIPT subtitles entrada.mp4 salida.mp4 --srt subs.srt
# RESIZE — Cambiar resolución
python3 $SCRIPT resize entrada.mp4 salida.mp4 --ancho 1280 --alto 720
python3 $SCRIPT resize entrada.mp4 salida.mp4 --ancho 1920 --alto -1 # auto altura
# GIF — Video a GIF animado (dos pasadas, alta calidad)
python3 $SCRIPT gif entrada.mp4 salida.gif --fps 15 --ancho 480
python3 $SCRIPT gif entrada.mp4 salida.gif --inicio 00:00:05 --duracion 3
# THUMBNAIL — Extraer un solo fotograma
python3 $SCRIPT thumbnail entrada.mp4 thumb.jpg --tiempo 00:00:30
# THUMBNAILS — Extraer N fotogramas espaciados uniformemente
python3 $SCRIPT thumbnails entrada.mp4 --contar 10 --directorio-salida ./thumbs/
# COMPRESS — Reducir tamaño de archivo
python3 $SCRIPT compress entrada.mp4 salida.mp4 --crf 28 --preset medium
python3 $SCRIPT compress entrada.mp4 pequeño.mp4 --crf 32 --preset fast # agresivo
# SPEED — Cambiar velocidad de reproducción
python3 $SCRIPT speed entrada.mp4 rapido.mp4 --factor 2.0 # 2x más rápido
python3 $SCRIPT speed entrada.mp4 lento.mp4 --factor 0.5 # mitad de velocidad (cámara lenta)
# WATERMARK — Añadir superposición de imagen
python3 $SCRIPT watermark entrada.mp4 salida.mp4 --marca-agua logo.png --posicion abajo-derecha
# TEXT — Incrustar superposición de texto
python3 $SCRIPT text entrada.mp4 salida.mp4 --texto "Capítulo 1" --posicion centro --tamano 72 --borde
python3 $SCRIPT text entrada.mp4 salida.mp4 --texto "¡Oferta!" --posicion arriba-izquierda --inicio 5 --fin 15
# CONVERT — Cambiar formato
python3 $SCRIPT convert entrada.avi salida.mp4
python3 $SCRIPT convert entrada.mp4 salida.webm --video-codec libvpx-vp9
# FRAMES — Extraer fotogramas como imágenes
python3 $SCRIPT frames entrada.mp4 --directorio-salida ./frames/
python3 $SCRIPT frames entrada.mp4 --directorio-salida ./frames/ --cada 30 # cada 30º fotograma
# AUDIO-REPLACE — Reemplazar pista de audio
python3 $SCRIPT audio-replace entrada.mp4 salida.mp4 --audio musica.mp3
# VOLUME — Ajustar nivel de audio
python3 $SCRIPT volume entrada.mp4 salida.mp4 --nivel 2.0 # duplicar volumen
python3 $SCRIPT volume entrada.mp4 salida.mp4 --nivel 0.5 # reducir volumen a la mitad
python3 $SCRIPT volume entrada.mp4 salida.mp4 --nivel 10dB # aumentar 10dB
# FADE — Añadir efectos de entrada/salida gradual
python3 $SCRIPT fade entrada.mp4 salida.mp4 --entrada-gradual 2 --salida-gradual 3
# STABILIZE — Estabilizar video tembloroso (requiere filtro vidstab)
python3 $SCRIPT stabilize entrada.mp4 salida.mp4 --temblor 7 --suavizado 15
# TRANSCRIBE — Transcripción de voz a texto CON etiquetas de orador (offline; ver sección Transcripción)
python3 $SCRIPT transcribe reunion.mp4 # → reunion.json/.srt/.txt
python3 $SCRIPT transcribe reunion.mp4 --oradores 3 # indicar el número de oradores
python3 $SCRIPT transcribe reunion.mp4 --sin-diarizar # solo transcripción, sin oradores
Transcripción y Análisis — entender lo que se dice en un video
Usa el comando transcribe para convertir una grabación de reunión, entrevista o
cualquier video/audio con voz en una transcripción con marcas de tiempo y etiquetas
de orador. Esta es la herramienta para preguntas como "¿qué se discutió?", "¿quién dijo
qué?", "resume esta reunión" o "encuentra dónde hablaron de X".
Funciona 100% local y sin conexión — el audio nunca abandona la máquina, sin API en la nube. Internamente usa: WhisperX (large-v3) para transcripción + marcas de tiempo a nivel de palabra, y sherpa-onnx para la diarización de oradores (sin tokens, modelos ONNX abiertos).
Instalación única (necesita red una vez)
Ejecuta el comando slash /setup-transcribe, o directamente:
bash ~/.claude/skills/ffmpeg/scripts/install-transcribe.sh
Por defecto, descarga un paquete precompilado desde el release de GitHub (rápido:
sin compuertas de modelo, sin compilación de torch) y lo instala completamente offline;
si no está disponible (falta el release, o plataforma cuyas wheels no coinciden) cae
automáticamente en una compilación desde cero. Crea un entorno virtual Python 3.12 aislado
(usando uv) y todos los modelos; después, transcribe no necesita red. Si el comando
informa que el entorno virtual falta, ejecútalo.
Para forzar un modo específico:
bash install-transcribe.sh --release # solo el paquete precompilado del release
bash install-transcribe.sh --build # solo compilación desde cero (HF + PyPI)
HF_TOKEN=hf_xxx bash install-transcribe.sh --build # también habilitar --diarizer pyannote
¿Sin acceso a Internet / sin acceso a HuggingFace? Compila un paquete autónomo una vez en una máquina con conexión, alójalo en cualquier servidor e instala desde él sin necesidad de HF/PyPI:
# En una máquina donde install-transcribe.sh ya se ejecutó:
bash ~/.claude/skills/ffmpeg/scripts/make-bundle.sh ffmpeg-transcribe-bundle.tar.gz
El paquete contiene todo: código, modelos, cachés de modelos y wheels de Python. Si supera
los 2GB se divide automáticamente en <nombre>.part-aa, <nombre>.part-ab, … (cada uno <2GB)
para ajustarse a los límites de alojamiento/subida. Luego, en la máquina de destino (solo necesita
uv, ffmpeg y python3.12):
# Paquete de un solo archivo:
bash install-transcribe.sh --bundle https://tuservidor/ffmpeg-transcribe-bundle.tar.gz
# Paquete dividido — pasa las partes en orden (se concatenan automáticamente):
bash install-transcribe.sh --bundle \
https://tuservidor/ffmpeg-transcribe-bundle.tar.gz.part-aa \
https://tuservidor/ffmpeg-transcribe-bundle.tar.gz.part-ab
(Para reensamblar manualmente en su lugar: cat ffmpeg-transcribe-bundle.tar.gz.part-* > ffmpeg-transcribe-bundle.tar.gz.)
Uso
# Transcripción completa + etiquetas de orador (escribe reunion.json, reunion.srt, reunion.txt)
python3 $SCRIPT transcribe reunion.mp4
# Opciones
python3 $SCRIPT transcribe entrevista.mp4 --oradores 2 # número conocido de oradores → mejor precisión
python3 $SCRIPT transcribe llamada.m4a --idioma es # forzar idioma (saltar detección automática)
python3 $SCRIPT transcribe conferencia.mp4 --formato txt # solo escribir .txt
python3 $SCRIPT transcribe largo.mp4 --model medium # más rápido, menos preciso
python3 $SCRIPT transcribe q4.mp4 --diarizer pyannote # diarizador de mayor calidad (necesita token HF)
python3 $SCRIPT transcribe notas.mp4 --sin-diarizar # solo transcripción, sin separación de oradores
python3 $SCRIPT transcribe raw.wav -o ./out/sesion # ruta base de salida personalizada
Formatos de salida
.txt— legible por humanos, agrupado por turno de orador. Léelo para entender el contenido:[00:03:12] ORADOR_01: ....srt— subtítulos con etiquetas de orador, para incrustar de nuevo (comandosubtitles).json— datos estructurados completos: cada segmento + palabra con horas de inicio/fin y orador, para análisis programático (búsqueda, líneas de tiempo, citas con marcas de tiempo)
Flujo de trabajo para análisis de reuniones
# 1. Transcribir con etiquetas de orador
python3 $SCRIPT transcribe reunion.mp4
# 2. Leer la transcripción para analizar el contenido
# (usa la herramienta Read en reunion.txt, o analiza reunion.json para marcas de tiempo)
# 3. A partir de aquí puedes resumir, extraer elementos de acción, encontrar quién-dijo-qué,
# o saltar a un momento: combina una marca de tiempo JSON con `cut`/`thumbnail`.
python3 $SCRIPT cut reunion.mp4 clip.mp4 --inicio 00:12:30 --fin 00:14:00
Notas:
- La transcripción se ejecuta en CPU (CTranslate2 no tiene ruta GPU en Apple Silicon), por lo que
large-v3 es aproximadamente 1–2× el tiempo real. Una reunión de 1 hora ≈ 30–60 min de procesamiento —
funciona bien en segundo plano. Usa
--model mediumodistil-large-v3para mayor velocidad. - Pasar
--oradores N(cuando sepas el número) mejora notablemente la diarización.
Flujo de Trabajo Estándar
Paso 1 — Analizar la entrada
Siempre comienza obteniendo información del archivo:
python3 $SCRIPT info entrada.mp4
Esto te da duración, resolución, códecs, tamaño de archivo. Úsalo para tomar decisiones inteligentes sobre la configuración de salida.
Paso 2 — Realizar la operación
Usa el comando apropiado. Para ediciones complejas, encadena múltiples operaciones — usa la salida de una como entrada de la siguiente.
Paso 3 — Verificar el resultado
Después de cualquier operación, examina la salida para confirmar que funcionó:
python3 $SCRIPT info salida.mp4
Paso 4 — Mostrar el resultado
Usa la herramienta Read para mostrar imágenes (miniaturas, fotogramas). Para videos, informa al usuario la ruta de salida y el tamaño del archivo.
ffmpeg sin procesar — Para operaciones avanzadas
Cuando el script auxiliar no cubra tu caso de uso, usa ffmpeg directamente:
# Imagen dentro de imagen (Picture-in-picture)
ffmpeg -y -i principal.mp4 -i superposicion.mp4 \
-filter_complex "[1:v]scale=320:-1[pip];[0:v][pip]overlay=W-w-10:H-h-10" \
-c:v libx264 -c:a copy salida.mp4
# Comparación lado a lado
ffmpeg -y -i izquierda.mp4 -i derecha.mp4 \
-filter_complex "[0:v]pad=iw*2:ih[bg];[bg][1:v]overlay=W/2:0" \
-c:v libx264 salida.mp4
# Cuadrícula/mosaico (2x2)
ffmpeg -y -i a.mp4 -i b.mp4 -i c.mp4 -i d.mp4 \
-filter_complex "[0:v]scale=640:360[v0];[1:v]scale=640:360[v1];
[2:v]scale=640:360[v2];[3:v]scale=640:360[v3];
[v0][v1]hstack[arriba];[v2][v3]hstack[abajo];[arriba][abajo]vstack" \
-c:v libx264 cuadricula.mp4
# Invertir video
ffmpeg -y -i entrada.mp4 -vf reverse -af areverse invertido.mp4
# Extraer canal de audio específico
ffmpeg -y -i entrada.mp4 -af "pan=mono|c0=FL" canal_izquierdo.wav
# Reducción de ruido
ffmpeg -y -i entrada.mp4 -af "afftdn=nf=-25" sin_ruido.mp4
# Corrección de color (brillo, contraste, saturación)
ffmpeg -y -i entrada.mp4 -vf "eq=brightness=0.1:contrast=1.2:saturation=1.3" corregido.mp4
# Clave de croma (eliminación de pantalla verde)
ffmpeg -y -i pantalla_verde.mp4 -i fondo.mp4 \
-filter_complex "[0:v]chromakey=0x00FF00:0.3:0.1[fg];[1:v][fg]overlay" \
-c:v libx264 compuesto.mp4
# Timelapse a partir de secuencia de imágenes
ffmpeg -y -framerate 30 -i frame_%04d.jpg -c:v libx264 -pix_fmt yuv420p timelapse.mp4
# Video a partir de una sola imagen + audio
ffmpeg -y -loop 1 -i portada.jpg -i audio.mp3 -c:v libx264 -tune stillimage \
-c:a aac -shortest salida.mp4
# Fundido cruzado entre dos videos (1 segundo)
ffmpeg -y -i primero.mp4 -i segundo.mp4 \
-filter_complex "xfade=transition=fade:duration=1:offset=DURACION_PRIMERO_MENOS_1" \
-c:v libx264 fundido_cruzado.mp4
Guía de Calidad CRF
| CRF | Calidad | Caso de uso |
|---|---|---|
| 18 | Sin pérdida visual | Archivado, edición profesional |
| 23 | Alta calidad | ffmpeg por defecto, buena para la mayoría de usos |
| 28 | Buena calidad | Recomendado para compartir, archivos más pequeños |
| 32 | Aceptable | Redes sociales, compresión agresiva |
| 38+ | Baja calidad | Previsualizaciones, miniaturas |
CRF más bajo = archivo más grande, mejor calidad. Cada +6 aproximadamente reduce el tamaño del archivo a la mitad.
Referencia Rápida de Formatos
| Contenedor | Códec de video | Códec de audio | Caso de uso |
|---|---|---|---|
.mp4 | H.264 (libx264) | AAC | Compatibilidad universal |
.webm | VP9 (libvpx-vp9) | Opus | Web, archivos más pequeños |
.mkv | H.265 (libx265) | Opus | Compresión máxima |
.mov | ProRes | PCM | Edición profesional |
.gif | — | — | Animaciones, sin audio |
Manejo de Errores
- "No such file" — Verifica la ruta de entrada, usa rutas absolutas
- "Unknown encoder" — Códec no compilado. Revisa
ffmpeg -encoders - "Permission denied" — La ruta de salida no tiene permisos de escritura
- "Avi header too large" — Entrada corrupta, prueba con
-fflags +genptsantes de la entrada - Timeout — El video es muy largo. Aumenta el tiempo de espera o usa
--preset ultrafast - Out of memory — Reduce la resolución primero, luego procesa