Communitygithub.com

Easel clipify — 펀치라인→9:16 페이스 팬

영어 토크 펀치라인 컷, 16:9→9:16 페이스 팬, opus 단어 ASS. preview.png. Easel 1.6k★.

Easel clipify — 펀치라인→9:16 페이스 팬란 무엇인가요?

숏폼 2단계: Easel clipify. 펀치라인→세로. claude-shorts 다음.

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

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Clipify

동영상에서 가장 재미있는 순간을 찾아 독립된 클립으로 자르고, 선택적으로 16:9 → 9:16 형식(얼굴 패닝 또는 분할 화면)으로 변환한 후, 오푸스(opus) 스타일의 단어별 자막을 입힙니다.

입력

  • 동영상 파일 경로 (사용자가 제공하지 않으면 요청할 것)
  • 선택 사항: 요청 형식 (9:16, 16:9, 1:1) — 제공되지 않은 경우, 후보 선정 후 질문
  • 선택 사항: 자막 스타일 선호도 — 제공되지 않은 경우, 자막 입히기 전 질문

도구 (가장 빠른 경로만 사용)

  • Whisper: whisper --model tiny.en --word_timestamps True --output_format json (small.en 대비 약 10배 빠름; 영어에 대해 품질 양호). 비영어의 경우: --model base 사용 (--language 생략).
  • ffmpeg: 하드웨어 디코딩은 선택 사항이며 플랫폼에 따라 다릅니다 — -hwaccel auto를 사용하거나 생략하십시오 (macOS: videotoolbox; Linux: vaapi/cuda/없음). 렌더링 시 -preset ultrafast를 추가하십시오. 최종 마스터에는 -c:v libx264 -crf 20을 사용하십시오.
  • Numpy: 오디오 정렬용 (FFT 상호 상관). scipy/cv2는 필요하지 않습니다.
  • 스크립트: <skill-dir>/scripts/ (여기서 <skill-dir>은 이 SKILL.md 파일이 있는 디렉토리입니다 — 일반적으로 ~/.claude/skills/clipify/)
    • analyze.py — 두 개의 ROI 모션 파일에서 화자 타임라인 생성
    • build_pan.py — 하드 컷이 포함된 ffmpeg 자르기 x-표현식 생성
    • build_ass.py — Whisper JSON에서 오푸스 스타일 ASS 자막 생성
    • audio_align.py — 긴 원본에서 하위 클립의 오프셋 찾기

작업 디렉토리: /tmp/clipify/ (시작 시 생성, 디버깅을 위해 아티팩트 유지).


워크플로우

1단계 — 가장 재미있는 부분 찾기

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

결과 JSON (또는 .txt)을 읽고 3~5개의 후보 클립을 고르십시오. 찾아야 할 재미 신호:

  • 펀치라인과 반응: "what", "wait", "no way" 같은 단어, 웃음, "haha", 욕설
  • 반전 순간: 설정 질문 → 예상치 못한 대답
  • 어색한 침묵: 긴 간격이 있는 Whisper 세그먼트 또는 필러 단어 ("uh", "um")
  • 자조적 발언 / 인용구: 독립적으로 사용할 수 있는 짧은 평서문
  • 오디오 피크: ffmpeg -af volumedetect를 사용하거나 빠른 대화 교대 (짧은 Whisper 세그먼트 교대)를 찾아 감지

각 후보에 대해 [시작, 끝, 재미있는 이유, 제안 제목]을 제안하십시오. 10~25초 클립을 목표로 하십시오. 목록을 보여주고 사용자가 확인/선택하게 하십시오.

2단계 — 선택된 각 클립 자르기

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

(즉시 자르기를 위해 -c copy를 사용하십시오. 컷이 프레임 정확해야 하는 경우에만 다시 인코딩하십시오.)

3단계 — 출력 형식 결정

사용자에게 질문하십시오 (이미 지정한 경우 건너뜁니다): "9:16 (TikTok / Reels), 16:9 (YouTube), 아니면 1:1 (Insta 피드)?"

4단계 — 16:9 → 9:16인 경우: 얼굴 간 패닝 vs 분할 화면

ffprobe로 소스 종횡비를 감지하십시오. 소스가 16:9이고 대상이 9:16인 경우 질문:

"두 가지 옵션: (a) 하드 컷 팬 — 말하는 사람을 따라다니며 (한 번에 한 명의 얼굴만 화면에 표시), 또는 (b) 분할 화면 — 두 얼굴을 모두 볼 수 있도록 수직으로 쌓습니다. 어느 것을 원하십니까?"

클립에 얼굴이 하나만 있는 경우 (단일 화자 클립) 질문을 건너뜁니다. 단일 화자의 경우 중앙 자르기만 수행합니다.

4a단계 — 얼굴 간 패닝 (빠른 컷의 대화하는 머리 권장)

  1. 두 얼굴 ROI 위치 찾기. 한 프레임 샘플 추출: ffmpeg -ss <중간> -i <클립> -frames:v 1 /tmp/clipify/probe.jpg. 읽습니다. 소스 픽셀 공간에서 각 얼굴의 입+턱 영역을 x,y,w,h로 대략적으로 파악합니다. (cv2 필요 없음 — 클립 내 카메라는 정적이며, 한 프레임이면 충분합니다.) 박스를 그려 확인:

    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
    

    최대 두 번 반복합니다. 박스는 입 + 턱을 덮고 손/마이크는 피해야 합니다. 과도하게 조정하지 마십시오 — 프레임 차이 분석은 관대합니다.

  2. 각 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. 화자 타임라인 구축 (최소 지속 시간 1.0초 — 짧은 감탄사는 이전 화자에 병합):

    python3 <skill-dir>/scripts/analyze.py /tmp/clipify/L.txt /tmp/clipify/R.txt 1.0 > /tmp/clipify/segments.json
    
  4. 소스로부터 9:16 세로 스트립을 위한 팬 x좌표 선택. 소스 W=1920이고 대상 W=1080인 경우, 자르기 스트립 너비 = 608입니다.

    • LEFT_X = face_left_center_x - 304 (0 이상으로 고정)
    • RIGHT_X = face_right_center_x - 304 (source_W - 608 이하로 고정)
  5. 하드 컷 x 표현식 생성 및 렌더링:

    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
    

    소스 1920×1080을 가정합니다. 4K 소스의 경우 먼저 다운스케일하거나 모든 좌표를 두 배로 늘리십시오.

4b단계 — 분할 화면 (두 얼굴 항상 표시)

두 개의 쌓인 타일, 각각 1080×960. 활성 화자의 타일이 위에 있습니다 — 화자가 변경될 때 오버레이가 전환됩니다.

[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>을 between(t,a,b)+between(t,a,b)+...로 segments.json에서 빌드합니다. 타일 자르기는 각 얼굴 주변 약 720×640 (1.125:1 비율로 1080×960 일치)을 대상으로 해야 합니다.

5단계 — 자막 추가

한 번만 질문하십시오 (사용자가 이미 스타일을 지정하지 않은 경우에만):

"세 가지 자막 스타일: 오푸스 (크고 굵은 흰색, 노란색 활성 단어 강조), 노래방 (4단어 청크, 녹색 강조), 미니멀 (깔끔한 헬베티카, 강조 없음). 또는 마음에 드는 예시를 붙여넣으십시오."

사용자가 참조 이미지/예시를 붙여넣는 경우: 글꼴, 크기, 두께, 색상, 위치 및 애니메이션을 최대한 가깝게 일치시키십시오 — 수동으로 사용자 정의 ASS를 작성하거나 build_ass.py를 확장하십시오.

그렇지 않으면 프리셋을 사용하십시오:

# 자른 클립의 정확한 타임스탬프를 얻기 위해 클립 시작을 기준으로 Whisper 재실행
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

자막 입히기:

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"

6단계 — 전달

  • 각 출력을 <source_dir>/clipify_out/에 저장합니다 (없으면 생성)
  • 클립당 한 줄씩 출력: 이름, 길이, 재미있었던 이유, 출력 경로
  • 첫 번째 출력 경로를 출력하거나 엽니다 (Linux xdg-open <경로>, macOS open <경로>) — 사용자가 확인할 수 있도록
  • 반복 작업 제안 (다른 스타일, 다른 ROI, 분할 화면으로 전환, 자막 타이밍 재조정)

함정 (이전 실행에서 얻은 교훈 — 반복하지 마십시오)

  • ROI를 과도하게 조정하지 마십시오. 최대 두 번 반복. 모션 차이는 관대합니다 — 입+턱을 덮는 더 넓은 ROI가 입 중앙에 완벽하게 맞지 않아도 잘 작동합니다.
  • 클립 내 장면 전환을 주의하십시오. ffmpeg -filter:v "select='gt(scene,0.3)',showinfo" -f null -를 실행하여 컷 수를 세십시오. 16:9→9:16 클립에 컷이 많은 경우, 고정된 얼굴 ROI는 주요 장면에 대해서만 작동합니다. 사용자에게 경고하고, 단일 테이크 클립을 선택하거나 전환 중에 중앙이 벗어난 프레이밍을 수락하도록 제안하십시오.
  • 소스 해상도가 중요합니다. 소스가 4K인 경우, 먼저 1920×1080으로 다운스케일하거나 (더 빠르며 9:16 출력에 적합) 모든 ROI/팬 좌표에 2를 곱하십시오.
  • 소스에 포함된 자막. 일부 "원본" 클립에는 여전히 자막이 있습니다. 그렇다면 오디오 상호 상관(audio_align.py)을 통해 자막이 없는 마스터를 찾아 거기서부터 자르십시오.
  • 짧은 클립으로 충분하다면 전체 길이의 소스에 대해 Whisper를 실행하지 마십시오. 2단계 후 자른 클립에 대해 Whisper를 실행하십시오. 1단계에서 재미있는 순간을 찾기 위해 대본이 필요한 경우에만 전체 소스에 대해 Whisper를 실행하십시오.
  • 한 줄로 계획을 말한 다음 행동하십시오. 모든 반복을 설명하지 마십시오.

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

관련 스킬