Communitygithub.com

Editor de Video FFmpeg

Edita videos, extrae audio, crea GIFs, añade subtítulos, comprime, manipula archivos multimedia y transcribe/analiza contenido de voz (grabaciones de reuniones, entrevistas) con etiquetas de orador — todo usando ffmpeg y el script auxiliar fftools.py.

¿Qué es Editor de Video FFmpeg?

Este skill para agentes de IA (Claude Code, Cursor, Codex, etc.) convierte el terminal en un potente estudio de edición de video y análisis de voz, todo local y sin conexión. Proporciona un script auxiliar (fftools.py) que simplifica operaciones complejas de ffmpeg, como cortar, fusionar, redimensionar, añadir marcas de agua, cambiar velocidad y estabilizar videos. Además, incluye un sistema de transcripción offline basado en WhisperX y sherpa-onnx que genera transcripciones con marcas de tiempo y etiquetas de orador, ideal para reuniones y entrevistas. El skill funciona en cualquier sistema con ffmpeg y Python 3.12, y está diseñado para ser invocado mediante comandos claros y predecibles, devolviendo siempre JSON para facilitar su integración con el agente.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beveradb/claude-code-config/tree/HEAD/skills/ffmpeg

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿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 (comando subtitles)
  • .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 medium o distil-large-v3 para 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

CRFCalidadCaso de uso
18Sin pérdida visualArchivado, edición profesional
23Alta calidadffmpeg por defecto, buena para la mayoría de usos
28Buena calidadRecomendado para compartir, archivos más pequeños
32AceptableRedes sociales, compresión agresiva
38+Baja calidadPrevisualizaciones, 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

ContenedorCódec de videoCódec de audioCaso de uso
.mp4H.264 (libx264)AACCompatibilidad universal
.webmVP9 (libvpx-vp9)OpusWeb, archivos más pequeños
.mkvH.265 (libx265)OpusCompresión máxima
.movProResPCMEdició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 +genpts antes 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

Skills relacionados