Communitygithub.com

Easel clipify — punchline→9:16 face-pan

Repère punchlines, coupe 10–25s, reframing 16:9→9:16 face-pan/split, ASS opus mot à mot. preview.png. Suite Easel 1.6k★.

Qu'est-ce que Easel clipify — punchline→9:16 face-pan ?

Short-form étape 2 : Easel clipify. Punchlines→9:16→ASS opus. Après claude-shorts.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Clipify

Trouvez les moments les plus drôles d'une vidéo, découpez-les en clips autonomes, reformatez éventuellement du 16:9 au 9:16 (face-pan ou écran partagé) et gravez des sous-titres mot par mot de type opus.

Entrées

  • Un chemin de fichier vidéo (l'utilisateur le fournira ; sinon demandez-le)
  • Optionnel : format demandé (9:16, 16:9, 1:1) — s'il n'est pas donné, demandez après que les candidats soient sélectionnés
  • Optionnel : préférence de style de sous-titres — s'il n'est pas donné, demandez avant le sous-titrage

Outils (utilisez uniquement le chemin le plus rapide)

  • Whisper : whisper --model tiny.en --word_timestamps True --output_format json (≈10 × plus rapide que small.en ; qualité suffisante pour l'anglais). Pour le non-anglais : --model base (omettre --language).
  • ffmpeg : le décodage matériel est optionnel et spécifique à la plateforme — utilisez -hwaccel auto, ou omettez-le (macOS : videotoolbox ; Linux : vaapi/cuda/aucun). Ajoutez -preset ultrafast pour les rendus. Utilisez -c:v libx264 -crf 20 pour le master final.
  • Numpy pour l'alignement audio (corrélation croisée FFT). Pas besoin de scipy/cv2.
  • Scripts : <skill-dir>/scripts/ (où <skill-dir> est le répertoire contenant ce SKILL.md — généralement ~/.claude/skills/clipify/)
    • analyze.py — ligne du temps des locuteurs à partir de deux fichiers de mouvement ROI
    • build_pan.py — expression x de crop ffmpeg avec coupures franches
    • build_ass.py — sous-titres ASS de style opus à partir du JSON de Whisper
    • audio_align.py — trouver le décalage d'un sous-clip dans une source plus longue

Répertoire de travail : /tmp/clipify/ (le créer au début, laisser les artefacts pour le débogage).


Flux de travail

Étape 1 — Trouver les parties les plus drôles

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

Lisez le JSON résultant (ou .txt) et sélectionnez 3 à 5 clips candidats. Signaux amusants à rechercher :

  • Chutes et réactions : mots comme "quoi", "attends", "pas possible", rire, "haha", jurons
  • Moments de renversement : question de mise en place → réponse inattendue
  • Pauses gênantes : segment Whisper avec un long écart, ou remplissage ("euh", "hum")
  • Auto-dérision / répliques citables : phrases déclaratives courtes qui se suffisent à elles-mêmes
  • Pics audio : détecter via ffmpeg -af volumedetect ou chercher un va-et-vient rapide (segments Whisper courts alternés)

Pour chaque candidat, proposez : [start, end, pourquoi-c'est-drôle, titre suggéré]. Visez des clips de 10 à 25 s. Affichez la liste et laissez l'utilisateur confirmer/sélectionner.

Étape 2 — Découper chaque clip choisi

ffmpeg -y -ss "$START" -t "$DURATION" -i "$VIDEO" -c copy /tmp/clipify/clip_$N.mp4

(Utilisez -c copy pour un découpage instantané. Ne ré-encodez que si les coupes doivent être précises à l'image.)

Étape 3 — Décider du format de sortie

Demandez à l'utilisateur (passez s'il a déjà spécifié) : "9:16 (TikTok / Reels), 16:9 (YouTube) ou 1:1 (fil Instagram) ?"

Étape 4 — Si 16:9 → 9:16 : panoramique entre les visages vs écran partagé

Détectez le format source avec ffprobe. Si la source est en 16:9 et la cible en 9:16, demandez :

"Deux options : (a) panoramique à coupures franches qui suit la personne qui parle (un seul visage à l'écran à la fois), ou (b) écran partagé superposé avec les deux visages visibles. Laquelle préférez-vous ?"

Ignorez la question s'il n'y a qu'un seul visage (clip avec un seul locuteur). Pour un seul locuteur, centrez le recadrage.

Étape 4a — Panoramique entre les visages (recommandé pour un dialogue rapide à têtes parlantes)

  1. Localisez les deux ROI des visages. Échantillonnez une image : ffmpeg -ss <milieu> -i <clip> -frames:v 1 /tmp/clipify/probe.jpg. Lisez-la. Estimez à l'œil la zone bouche+menton de chaque visage sous forme de x,y,w,h dans l'espace pixel de la source. (Pas besoin de cv2 — la caméra est statique dans un clip ; une seule image suffit.) Vérifiez en dessinant des boîtes :

    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
    

    Itérez au plus deux fois. Les boîtes doivent couvrir la bouche + le menton et éviter les mains/micros. Ne sur-ajustez pas — la différence d'image est tolérante.

  2. Extrayez l'énergie de mouvement par image dans chaque 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. Construisez la ligne du temps des locuteurs (temps de séjour minimum 1.0 s — les courtes interjections fusionnent avec le locuteur précédent) :

    python3 <skill-dir>/scripts/analyze.py /tmp/clipify/L.txt /tmp/clipify/R.txt 1.0 > /tmp/clipify/segments.json
    
  4. Choisissez les coordonnées x du panoramique pour une bande verticale 9:16 à partir de la source. Avec une source W=1920 et une cible W=1080, largeur de la bande de recadrage = 608.

    • GAUCHE_X = face_left_center_x - 304 (clamp ≥ 0)
    • DROITE_X = face_right_center_x - 304 (clamp ≤ source_W - 608)
  5. Générez l'expression x de coupure franche et effectuez le rendu :

    EXPR=$(python3 <skill-dir>/scripts/build_pan.py /tmp/clipify/segments.json $LEFT_X $RIGHT_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_panned.mp4
    

    Source 1920×1080 supposée ; pour une source 4K, réduisez d'abord ou doublez toutes les coordonnées.

Étape 4b — Écran partagé (les deux visages toujours visibles)

Deux tuiles empilées, 1080×960 chacune. La tuile du locuteur actif est en haut — la superposition bascule lors des changements de locuteur.

[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='<RIGHT_SPEAKER_ENABLE>'[v]

Construisez <RIGHT_SPEAKER_ENABLE> à partir de segments.json sous la forme between(t,a,b)+between(t,a,b)+... sur les segments du locuteur de droite. Les recadrages des tuiles doivent cibler environ 720×640 autour de chaque visage (1.125:1 pour correspondre à 1080×960).

Étape 5 — Ajouter des sous-titres

Demandez une fois (uniquement si l'utilisateur n'a pas déjà spécifié un style) :

"Trois styles de sous-titres : opus (gras blanc grand, surlignage jaune du mot actif), karaoké (groupes de 4 mots, surlignage vert), minimal (Helvetica propre, pas de surlignage). Ou collez un exemple que vous aimez."

S'ils collent une image de référence/un exemple : adaptez la police, la taille, le poids, la couleur, la position et l'animation aussi fidèlement que possible — écrivez un ASS personnalisé à la main ou étendez build_ass.py.

Sinon, utilisez le préréglage :

# Réexécutez whisper sur le clip découpé pour des horodatages précis par rapport au début du clip
whisper /tmp/clipify/clip_panned.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_panned.json /tmp/clipify/captions.ass opus

Gravez les sous-titres :

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

Étape 6 — Livrer

  • Sauvegardez chaque sortie dans <source_dir>/clipify_out/ (créez le répertoire s'il manque)
  • Affichez une ligne par clip : nom, durée, ce qui était drôle, chemin de sortie
  • Affichez le premier chemin de sortie (ou ouvrez-le — Linux xdg-open <chemin>, macOS open <chemin>) pour que l'utilisateur puisse le vérifier
  • Proposez d'itérer (style différent, ROI différent, passer à l'écran partagé, retimbrer les sous-titres)

Pièges (leçons des exécutions précédentes — ne les répétez pas)

  • Ne sur-ajustez pas les ROI. Deux itérations maximum. La différence de mouvement est tolérante — des ROI plus larges couvrant la bouche+menton fonctionnent bien même s'ils ne sont pas parfaitement centrés sur la bouche.
  • Attention aux changements de plan à l'intérieur d'un clip. Exécutez ffmpeg -filter:v "select='gt(scene,0.3)',showinfo" -f null - pour compter les coupures. Si un clip 16:9→9:16 comporte de nombreuses coupures, les ROI de visage fixes ne fonctionnent que pour la scène dominante ; prévenez l'utilisateur et proposez soit de choisir un clip en plan unique, soit d'accepter un cadrage décentré pendant les coupures.
  • La résolution source compte. Si la source est en 4K, réduisez-la d'abord en 1920×1080 (plus rapide, bien pour une sortie 9:16) ou multipliez toutes les coordonnées ROI/panoramique par 2.
  • Sous-titres incrustés dans la source. Certains clips "bruts" ont encore des sous-titres. Si c'est le cas, trouvez le master sans sous-titres par corrélation croisée audio (audio_align.py) et découpez à partir de là.
  • N'exécutez pas whisper sur la source complète de long métrage si un court clip suffit. Whisper le clip découpé après l'étape 2 ; ne whisper la source complète qu'à l'étape 1 si vous avez besoin d'une transcription pour trouver les moments drôles.
  • Énoncez le plan en une ligne, puis agissez. Ne racontez pas chaque itération.

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 associés