Communitygithub.com

Easel clipify — Punchline→9:16 Face-Pan

Punchlines finden, 10–25s Shorts, 16:9→9:16 Face-Pan/Split, Opus-Wort-ASS. preview.png. Easel 1.6k★.

Was ist Easel clipify — Punchline→9:16 Face-Pan?

Short-form Schritt 2: Easel clipify. Punchlines→9:16. Nach claude-shorts.

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

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Clipify

Finde die lustigsten Momente in einem Video, schneide sie als eigenständige Clips aus, formatiere optional 16:9 → 9:16 (Gesichts-Pan oder Splitscreen) und brenne Opus-artige Wort-für-Wort-Untertitel ein.

Eingaben

  • Ein Videodateipfad (der Benutzer wird ihn bereitstellen; andernfalls nachfragen)
  • Optional: gewünschtes Format (9:16, 16:9, 1:1) — falls nicht angegeben, nach Auswahl der Kandidaten erfragen
  • Optional: Untertitel-Stil-Präferenz — falls nicht angegeben, vor dem Untertiteln erfragen

Werkzeuge (nur den schnellsten Weg verwenden)

  • Whisper: whisper --model tiny.en --word_timestamps True --output_format json (≈10× schneller als small.en; Qualität für Englisch ausreichend). Für Nicht-Englisch: --model base ( --language weglassen).
  • ffmpeg: Hardware-Dekodierung ist optional und plattformspezifisch — -hwaccel auto verwenden oder weglassen (macOS: videotoolbox; Linux: vaapi/cuda/keine). Für Renderings -preset ultrafast hinzufügen. Für das endgültige Master -c:v libx264 -crf 20 verwenden.
  • Numpy für Audioausrichtung (FFT-Kreuzkorrelation). Kein scipy/cv2 erforderlich.
  • Skripte: <skill-dir>/scripts/ (wobei <skill-dir> das Verzeichnis ist, das diese SKILL.md enthält — typischerweise ~/.claude/skills/clipify/)
    • analyze.py — Sprecherzeitlinie aus zwei ROI-Bewegungsdateien
    • build_pan.py — ffmpeg-Crop-x-Ausdruck mit harten Schnitten
    • build_ass.py — Opus-artige ASS-Untertitel aus Whisper-JSON
    • audio_align.py — Offset eines Sub-Clips in einer längeren Quelle finden

Arbeitsverzeichnis: /tmp/clipify/ (zu Beginn erstellen, Artefakte zum Debuggen hinterlassen).


Arbeitsablauf

Schritt 1 — Die lustigsten Teile finden

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

Das resultierende JSON (oder .txt) lesen und 3–5 Kandidaten-Clips auswählen. Lustige Signale, nach denen gesucht werden sollte:

  • Pointen und Reaktionen: Wörter wie "was", "warte", "echt jetzt", Lachen, "haha", Fluchen
  • Wendepunkte: Setup-Frage → unerwartete Antwort
  • Peinliche Pausen: Whisper-Segment mit langer Lücke oder Füllwörter ("äh", "hm")
  • Selbstironie / zitierfähige Einzeiler: Kurze, in sich geschlossene Aussagesätze
  • Audio-Peaks: Erkennung via ffmpeg -af volumedetect oder nach schnellem Hin und Her (alternierende kurze Whisper-Segmente) suchen

Für jeden Kandidaten vorschlagen: [Start, Ende, warum-lustig, vorgeschlagener Titel]. Auf 10–25s Clips abzielen. Die Liste anzeigen und den Benutzer bestätigen/auswählen lassen.

Schritt 2 — Jeden ausgewählten Clip zuschneiden

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

(-c copy für sofortigen Schnitt verwenden. Nur neu codieren, wenn Schnitte frame-genau sein müssen.)

Schritt 3 — Das Ausgabeformat festlegen

Den Benutzer fragen (überspringen, falls bereits angegeben): "9:16 (TikTok / Reels), 16:9 (YouTube) oder 1:1 (Insta-Feed)?"

Schritt 4 — Wenn 16:9 → 9:16: Pan zwischen Gesichtern vs. Splitscreen

Quellseitenverhältnis mit ffprobe erkennen. Wenn Quelle 16:9 und Ziel 9:16 ist, fragen:

"Zwei Optionen: (a) Hard-Cut-Pan, der dem jeweils Sprechenden folgt (ein Gesicht gleichzeitig auf dem Bildschirm), oder (b) Splitscreen-Stapel mit beiden sichtbaren Gesichtern. Welche möchtest du?"

Die Frage überspringen, wenn es nur ein Gesicht gibt (Einzelsprecher-Clip). Bei einem Einzelsprecher einfach zentriert zuschneiden.

Schritt 4a — Pan zwischen Gesichtern (empfohlen für schnelle Talking-Head-Dialoge)

  1. Die beiden Gesichts-ROIs lokalisieren. Ein Frame mustern: ffmpeg -ss <Mitte> -i <Clip> -frames:v 1 /tmp/clipify/probe.jpg. Lesen. Die Mund+Kinn-Region jedes Gesichts als x,y,w,h im Pixelraum der Quelle grob schätzen. (Kein cv2 nötig — Kamera ist innerhalb eines Clips statisch; ein Frame reicht.) Durch Einzeichnen von Boxen verifizieren:

    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
    

    Maximal zweimal iterieren. Boxen sollten Mund+Kinn abdecken und Hände/Mikrofone vermeiden. Nicht überoptimieren — Frame-Differenzierung ist verzeihend.

  2. Bewegungsenergie pro Frame in jeder ROI extrahieren:

    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. Sprecherzeitlinie erstellen (min. Verweildauer 1,0s — kurze Einwürfe werden dem vorherigen Sprecher zugeschlagen):

    python3 <skill-dir>/scripts/analyze.py /tmp/clipify/L.txt /tmp/clipify/R.txt 1.0 > /tmp/clipify/segments.json
    
  4. Pan-x-Koordinaten für einen 9:16-Vertikalstreifen aus der Quelle wählen. Bei Quell-W=1920 und Ziel-W=1080 beträgt die Crop-Streifenbreite 608.

    • LEFT_X = face_left_center_x - 304 (auf ≥ 0 begrenzen)
    • RIGHT_X = face_right_center_x - 304 (auf ≤ source_W - 608 begrenzen)
  5. Den Hard-Cut-x-Ausdruck generieren und rendern:

    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
    

    Quelle 1920×1080 angenommen; bei 4K-Quelle entweder zuerst verkleinern oder alle Koordinaten verdoppeln.

Schritt 4b — Splitscreen (beide Gesichter immer sichtbar)

Zwei gestapelte Kacheln, 1080×960 jede. Die Kachel des aktiven Sprechers ist oben — das Overlay wechselt bei Sprecherwechseln.

[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]

<RIGHT_SPEAKER_ENABLE> aus segments.json als between(t,a,b)+between(t,a,b)+... über die Segmente des rechten Sprechers erstellen. Kachel-Crops sollten ~720×640 um jedes Gesicht herum anvisieren (1,125:1, um 1080×960 zu entsprechen).

Schritt 5 — Untertitel hinzufügen

Einmal fragen (nur wenn der Benutzer nicht bereits einen Stil angegeben hat):

"Drei Untertitel-Stile: opus (groß fett weiß, gelbe Aktiv-Wort-Hervorhebung), karaoke (4-Wort-Blöcke, grüne Hervorhebung), minimal (saubere Helvetica, keine Hervorhebung). Oder füge ein Beispiel ein, das dir gefällt."

Wenn er ein Referenzbild/Beispiel einfügt: Schriftart, Größe, Gewicht, Farbe, Position und Animation so genau wie möglich nachahmen — ein benutzerdefiniertes ASS von Hand schreiben oder build_ass.py erweitern.

Sonst die Voreinstellung verwenden:

# Whisper erneut auf dem zugeschnittenen Clip ausführen, für genaue Zeitstempel relativ zum Clip-Start
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

Untertitel einbrennen:

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

Schritt 6 — Liefern

  • Jede Ausgabe in <source_dir>/clipify_out/ speichern (mkdir, falls nicht vorhanden)
  • Eine Zeile pro Clip ausgeben: Name, Dauer, was lustig war, Ausgabepfad
  • Den ersten Ausgabepfad ausgeben (oder öffnen — Linux xdg-open <Pfad>, macOS open <Pfad>), damit der Benutzer ihn überprüfen kann
  • Iteration anbieten (anderer Stil, andere ROI, zu Splitscreen wechseln, Untertitel neu timen)

Fallstricke (Lehren aus früheren Durchläufen — nicht wiederholen)

  • ROIs nicht überoptimieren. Maximal zwei Iterationen. Bewegungsdifferenzierung ist verzeihend — breitere ROIs, die Mund+Kinn abdecken, funktionieren auch dann gut, wenn sie nicht perfekt mundzentriert sind.
  • Achtung vor Szenenschnitten innerhalb eines Clips. ffmpeg -filter:v "select='gt(scene,0.3)',showinfo" -f null - ausführen, um Schnitte zu zählen. Wenn ein 16:9→9:16-Clip viele Schnitte hat, funktionieren die festen Gesichts-ROIs nur für die dominierende Szene; den Benutzer warnen und anbieten, entweder einen Einzel-Einstellungs-Clip auszuwählen oder während der Schnitte eine außermittige Rahmung zu akzeptieren.
  • Quellauflösung ist wichtig. Wenn die Quelle 4K ist, entweder zuerst auf 1920×1080 verkleinern (schneller, für 9:16-Ausgabe ausreichend) oder alle ROI/Pan-Koordinaten mit 2 multiplizieren.
  • Eingebrannte Untertitel in der Quelle. Manche "rohen" Clips haben dennoch Untertitel. Wenn ja, das Master ohne Untertitel über Audio-Kreuzkorrelation (audio_align.py) finden und von dort aus zuschneiden.
  • Whisper nicht auf der gesamten Spielfilmlänge ausführen, wenn ein kurzer Clip ausreicht. Whisper den zugeschnittenen Clip nach Schritt 2 ausführen; die gesamte Quelle nur in Schritt 1 mit Whisper bearbeiten, wenn ein Transkript zum Finden lustiger Momente benötigt wird.
  • Den Plan in einer Zeile darlegen, dann handeln. Nicht jede Iteration kommentieren.

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 写具体某条视频的脚本。

Verwandte Skills