Communitygithub.com

Easel clipify — punchline→9:16 face-pan

Encuentra punchlines en charlas largas en inglés, corta shorts 10–25s, reencuadra 16:9→9:16 con face-pan/split y quema ASS opus palabra a palabra. Scripts + assets/preview.png. Suite ZJU-REAL/Easel 1.6k★.

¿Qué es Easel clipify — punchline→9:16 face-pan?

Short-form Editing paso 2 (punchline/reframe): Easel clipify — Whisper detecta beats graciosos → trim → face-pan 9:16 → ASS karaoke opus. preview.png en assets. Puentea picks de claude-shorts a clips verticales listos para feed mudo.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ZJU-REAL/Easel/tree/main/skills/openclaw/clipify

Preguntar en tu IA favorita

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

Documentación

Clipify

Encuentra los momentos más divertidos de un vídeo, recórtalos en clips independientes, opcionalmente reformatea 16:9 → 9:16 (seguimiento de rostro o pantalla dividida) e incrusta subtítulos palabra por palabra al estilo Opus.

Entradas

  • Una ruta de archivo de vídeo (el usuario la proporcionará; si no, pregúntala)
  • Opcional: formato solicitado (9:16, 16:9, 1:1) — si no se proporciona, pregunta después de seleccionar los candidatos
  • Opcional: preferencia de estilo de subtítulos — si no se proporciona, pregunta antes de subtitular

Herramientas (usa solo la ruta más rápida)

  • Whisper: whisper --model tiny.en --word_timestamps True --output_format json (≈10× más rápido que small.en; calidad suficiente para inglés). Para otros idiomas: --model base (omite --language).
  • ffmpeg: la decodificación por hardware es opcional y específica de la plataforma — usa -hwaccel auto, u omítelo (macOS: videotoolbox; Linux: vaapi/cuda/ninguno). Añade -preset ultrafast para las previsualizaciones. Usa -c:v libx264 -crf 20 para la versión final maestra.
  • NumPy para la alineación de audio (correlación cruzada FFT). No se necesita scipy/cv2.
  • Scripts: <skill-dir>/scripts/ (donde <skill-dir> es el directorio que contiene este SKILL.md — normalmente ~/.claude/skills/clipify/)
    • analyze.py — línea de tiempo del hablante a partir de dos archivos de movimiento ROI
    • build_pan.py — expresión x de recorte de ffmpeg con cortes duros
    • build_ass.py — subtítulos ASS al estilo Opus desde el JSON de Whisper
    • audio_align.py — encuentra el desplazamiento de un subclip en un origen más largo

Directorio de trabajo: /tmp/clipify/ (crear al inicio, dejar artefactos para depuración).


Flujo de trabajo

Paso 1 — Encuentra las partes más divertidas

mkdir -p /tmp/clipify
ffmpeg -y -i "$VIDEO" -vn -ac 1 -ar 16000 /tmp/clipify/audio.wav
whisper /tmp/clipify/audio.wav --model tiny.en --word_timestamps True --output_format json --output_dir /tmp/clipify --language en

Lee el JSON resultante (o .txt) y selecciona de 3 a 5 clips candidatos. Señales de humor a escanear:

  • Remates y reacciones: palabras como "qué", "espera", "no puede ser", risas, "jaja", insultos
  • Momentos de giro: pregunta preparatoria → respuesta inesperada
  • Pausas incómodas: segmento de Whisper con un gran espacio, o muletillas ("eh", "um")
  • Autocrítica / frases citables: oraciones declarativas cortas que se sostienen por sí solas
  • Picos de audio: detecta mediante ffmpeg -af volumedetect o busca un intercambio rápido (segmentos cortos alternados de Whisper)

Para cada candidato, propón: [inicio, fin, por qué es divertido, título sugerido]. Apunta a clips de 10–25 s. Muestra la lista y deja que el usuario confirme/seleccione.

Paso 2 — Recorta cada clip elegido

ffmpeg -y -ss "$INICIO" -t "$DURACIÓN" -i "$VIDEO" -c copy /tmp/clipify/clip_$N.mp4

(Usa -c copy para un recorte instantáneo. Re-codifica solo si los cortes deben ser precisos por fotograma).

Paso 3 — Decide el formato de salida

Pregunta al usuario (omite si ya lo especificó): "¿9:16 (TikTok / Reels), 16:9 (YouTube) o 1:1 (feed de Insta)?"

Paso 4 — Si 16:9 → 9:16: paneo entre rostros vs pantalla dividida

Detecta la relación de aspecto de origen con ffprobe. Si el origen es 16:9 y el destino es 9:16, pregunta:

"Dos opciones: (a) paneo con corte duro que sigue a quien habla (un solo rostro en pantalla a la vez), o (b) pantalla dividida apilada con ambos rostros visibles. ¿Cuál prefieres?"

Omite la pregunta si solo hay un rostro (clip de un solo hablante). Para un solo hablante, simplemente recorta centrando.

Paso 4a — Paneo entre rostros (recomendado para diálogos rápidos de dos hablantes)

  1. Localiza las dos ROI de los rostros. Muestra un fotograma: ffmpeg -ss <medio> -i <clip> -frames:v 1 /tmp/clipify/probe.jpg. Léelo. Estima a ojo el área de boca+mentón de cada rostro como x,y,w,h en el espacio de píxeles del origen. (No se necesita cv2 — la cámara es estática dentro de un clip; un fotograma es suficiente). Verifica dibujando cajas:

    ffmpeg -i probe.jpg -vf "drawbox=x=$LX:y=$LY:w=$LW:h=$LH:[email protected]:t=4,drawbox=x=$RX:y=$RY:w=$RW:h=$RH:[email protected]:t=4" verify.jpg
    

    Itera como máximo dos veces. Las cajas deben cubrir boca + mentón y evitar manos/micrófonos. No ajustes en exceso — la diferencia de fotogramas es tolerante.

  2. Extrae la energía de movimiento por fotograma en cada ROI:

    ffmpeg -y -i clip.mp4 -filter_complex "
    [0:v]split=2[a][b];
    [a]crop=$LW:$LH:$LX:$LY,format=gray,tblend=all_mode=difference,signalstats,metadata=mode=print:key=lavfi.signalstats.YAVG:file=/tmp/clipify/L.txt[la];
    [b]crop=$RW:$RH:$RX:$RY,format=gray,tblend=all_mode=difference,signalstats,metadata=mode=print:key=lavfi.signalstats.YAVG:file=/tmp/clipify/R.txt[ra]
    " -map "[la]" -f null - -map "[ra]" -f null -
    
  3. Construye la línea de tiempo del hablante (duración mínima 1.0 s — las interjecciones cortas se fusionan con el hablante anterior):

    python3 <skill-dir>/scripts/analyze.py /tmp/clipify/L.txt /tmp/clipify/R.txt 1.0 > /tmp/clipify/segments.json
    
  4. Elige las coordenadas x del paneo para una franja vertical 9:16 del origen. Con origen W=1920 y destino W=1080, el ancho de la franja de recorte es 608.

    • IZQUIERDA_X = centro_x_rostro_izquierdo - 304 (limitar a ≥ 0)
    • DERECHA_X = centro_x_rostro_derecho - 304 (limitar a ≤ origen_W - 608)
  5. Genera la expresión x de corte duro y renderiza:

    EXPR=$(python3 <skill-dir>/scripts/build_pan.py /tmp/clipify/segments.json $IZQUIERDA_X $DERECHA_X)
    ffmpeg -y -i clip.mp4 -filter_complex \
      "[0:v]crop=608:1080:x='$EXPR':y=0,scale=1080:1920:flags=lanczos[v]" \
      -map "[v]" -map 0:a -c:v libx264 -preset fast -crf 20 -pix_fmt yuv420p \
      -c:a aac -b:a 192k /tmp/clipify/clip_paneado.mp4
    

    Se asume origen 1920×1080; para origen 4K, reduce la escala primero o duplica todas las coordenadas.

Paso 4b — Pantalla dividida (ambos rostros siempre visibles)

Dos mosaicos apilados, 1080×960 cada uno. El mosaico del hablante activo está arriba — la superposición cambia en los cambios de hablante.

[0:v]split=2[a0][a1];
[a0]crop=Wcrop:Hcrop:LX_tile:LY_tile,scale=1080:960,split=2[lt0][lt1];
[a1]crop=Wcrop:Hcrop:RX_tile:RY_tile,scale=1080:960,split=2[rt0][rt1];
[lt0][rt0]vstack[layoutL];
[rt1][lt1]vstack[layoutR];
[layoutL][layoutR]overlay=0:0:enable='<HABLANTE_DERECHO_HABILITADO>'[v]

Construye <HABLANTE_DERECHO_HABILITADO> desde segments.json como between(t,a,b)+between(t,a,b)+... sobre los segmentos del hablante derecho. Los recortes de los mosaicos deben apuntar a ~720×640 alrededor de cada rostro (1.125:1 para coincidir con 1080×960).

Paso 5 — Añade subtítulos

Pregunta una vez (solo si el usuario no ha especificado ya un estilo):

"Tres estilos de subtítulos: opus (blanco grande y negrita, resaltado de palabra activa en amarillo), karaoke (grupos de 4 palabras, resaltado verde), minimal (Helvetica limpio, sin resaltado). O pega un ejemplo que te guste."

Si pega una imagen de referencia/ejemplo: iguala la fuente, tamaño, peso, color, posición y animación lo más fielmente posible — escribe un ASS personalizado a mano o amplía build_ass.py.

En caso contrario, usa el preajuste:

# Vuelve a ejecutar whisper en el clip recortado para obtener marcas de tiempo precisas relativas al inicio del clip
whisper /tmp/clipify/clip_paneado.mp4 --model tiny.en --word_timestamps True --output_format json --output_dir /tmp/clipify --language en
python3 <skill-dir>/scripts/build_ass.py /tmp/clipify/clip_paneado.json /tmp/clipify/captions.ass opus

Incrusta los subtítulos:

ffmpeg -y -i /tmp/clipify/clip_paneado.mp4 -vf "subtitles=/tmp/clipify/captions.ass" \
  -c:v libx264 -preset fast -crf 20 -c:a copy "$SALIDA.mp4"

Paso 6 — Entrega

  • Guarda cada salida en <directorio_origen>/clipify_out/ (crea el directorio si no existe)
  • Imprime una línea por clip: nombre, duración, qué fue divertido, ruta de salida
  • Imprime la primera ruta de salida (o ábrela — Linux xdg-open <ruta>, macOS open <ruta>) para que el usuario pueda revisarla
  • Ofrece iterar (diferente estilo, diferente ROI, cambiar a pantalla dividida, reajustar tiempos de subtítulos)

Errores comunes (lecciones de ejecuciones anteriores — no repetir)

  • No ajustes en exceso las ROI. Máximo dos iteraciones. La diferencia de movimiento es tolerante — las ROI más amplias que cubren boca+mentón funcionan bien incluso si no están perfectamente centradas en la boca.
  • Cuidado con los cambios de escena dentro de un clip. Ejecuta ffmpeg -filter:v "select='gt(scene,0.3)',showinfo" -f null - para contar los cortes. Si un clip 16:9→9:16 tiene muchos cortes, las ROI fijas de rostro solo funcionan para la escena dominante; advierte al usuario y ofrece seleccionar un clip de una sola toma o aceptar un encuadre descentrado durante los cortes.
  • La resolución de origen importa. Si el origen es 4K, reduce la escala a 1920×1080 primero (más rápido, suficiente para salida 9:16) o multiplica todas las coordenadas ROI/paneo por 2.
  • Subtítulos incrustados en el origen. Algunos clips "en bruto" aún tienen subtítulos. Si es así, encuentra el máster sin subtítulos mediante correlación cruzada de audio (audio_align.py) y recorta desde allí.
  • No ejecutes whisper en el vídeo completo de larga duración si un clip corto es suficiente. Ejecuta whisper en el clip recortado después del Paso 2; solo ejecuta whisper en el origen completo en el Paso 1 si necesitas una transcripción para encontrar momentos divertidos.
  • Expresa el plan en una línea, luego actúa. No narres cada iteración.

Individual skills in this repo

This repo contains 9 individual skills — each has its own dedicated page.

ZJU-REAL/Easel

AI 视频生成:文生视频 / 图生视频 / 数字人首帧驱动。通过可插拔 provider(通义万相 Wan / 火山 Seedance / 快手可灵 / OpenAI 兼容)异步生成视频,用户自备 API key。当用户说 AI 视频生成、文生视频、图生视频、AI 生成视频、AI 短视频、让图片动起来、数字人视频、生成一段视频 时使用。与 video-strategy(选型/策略)、video-editing(剪辑处理)、clipify(切片)区别:本 SKILL 是从 0 用 AI 生成新视频。

ZJU-REAL/Easel

通用音频处理:音频剪辑/裁剪、格式转码(mp3/wav/m4a/aac)、音量归一化、从视频提取音轨、多段拼接、淡入淡出、变速(保音高)。当用户说“剪音频”“裁一段”“转成 mp3”“调音量/响度”“提取音轨/扒音频”“拼接音频”“淡入淡出”“加速/减速音频”“变速不变调”时使用。与 audio-denoise 的区别:audio-denoise 专做降噪,audio-editing 做除降噪外的通用音频操作(也内置 denoise 作为兜底)。

ZJU-REAL/Easel

一句话主题 → 成品短视频:自动串联 文案→配图/AI视频→配音→字幕→BGM→合成,把 Easel 制作层零件编排成一条'一键出片'流水线。**单条视频、口播/资讯向,画面默认逐句配图 + Ken Burns 缓动,需要动态时才逐段图生视频**。当用户说 一键生成视频、自动做短视频、主题生成视频、帮我做条视频、口播视频一条龙、自动出片、短视频一键生成 时使用。**有剧情/角色/对白/反转/多集的短剧改用 short-drama(每镜强制图生视频、不用静态图冒充);只写脚本用 video-script;只生成单个片段用 ai-video-gen。**

ZJU-REAL/Easel

自动字幕 / 语音转字幕:把音频或视频里的语音识别成字幕文件(SRT/ASS/TXT/JSON),可选把字幕烧录进视频。当用户说自动字幕、语音转字幕、视频加字幕、上字幕、转录、听写、字幕文件、生成字幕、烧字幕时使用。

ZJU-REAL/Easel

音乐卡点视频 / 踩点视频:检测背景音乐的节拍,让图片或片段在节拍点上切换,配推进/白闪特效,做出燃系'卡点'短视频。当用户说 卡点视频、踩点视频、音乐卡点、节奏卡点、按音乐切换、鼓点视频、踩节奏、beat 卡点、图片卡点、卡点混剪 时使用。基于 shared/scripts/beatsync.py(librosa 节拍检测)。与 slideshow-video 区别:slideshow 每图固定时长、柔和转场,本 SKILL 切换点由音乐节拍决定、硬切踩点带特效。

ZJU-REAL/Easel

>- 通用图像处理加工:改尺寸/缩放、裁剪、补边适配平台尺寸、格式转换(png/jpg/webp)、 压缩到目标大小、加文字或图片水印、圆角、多图拼接、生成缩略图、读图片信息。 基于 image_ops.py 确定性处理。 使用时机:用户说"改尺寸"、"缩放图片"、"裁剪"、"压缩图片"、"加水印"、"转格式"、 "圆角"、"拼图/多图联排"、"缩略图"、"适配小红书/朋友圈尺寸"、"把图 pad 成 1:1"。 和 card-*(卡片类)的区别:card-* 是"HTML 设计→渲染出图", image-editing 只加工已有图片,不负责视觉设计。

ZJU-REAL/Easel

多角色对话配音:按 cast 和逐行对白为不同角色分配音色与情绪,合成多声线音轨和带角色名字幕。 当用户说“多角色/双人/剧本/对话配音、多人对白、不同角色不同声音、有声剧配音”时使用。 单一公共音色用 tts-voiceover;克隆本人音色用 voice-clone;整部短剧制作由 short-drama 编排。

ZJU-REAL/Easel

Easel video-highlights: CN/livestream highlight extract + stable static vertical reframe (sibling to clipify).

ZJU-REAL/Easel

>- 视频制作策略与工具选型:AI 视频生成模型对比、视频脚本结构设计、制作流程规划,覆盖产品演示/解说/社媒短视频场景。 当用户说"视频怎么做""视频选型""用什么工具做视频""视频制作流程""视频策略""视频系列规划"时使用。 和 video-script 的区别:video-strategy 做内容规划与工具选型,video-script 写具体某条视频的脚本。

Skills relacionados