Communitygithub.com

Jenesyx/reel-story

사용자가 /reel-story를 실행하거나, 화면을 가득 채우고 역동적인 움직임이 있는 릴 편집(스피커 전체 화면, 자체 B-롤 클립으로의 전환, 음성에 따라 나타나는 스티커/위젯, 마스코트, 스피커 뒤의 큰 글자, 자막 없음)을 raw/ 폴더의 talking-head 테이크에 대해 요청할 때 사용합니다.

reel-story란 무엇인가요?

이 스킬은 스피커가 항상 전체 화면에 유지되는 ‘스토리’ 형식의 릴(Reel)을 제작하는 파이프라인입니다. 입력된 테이크(take)의 음성을 텍스트로 변환하고, 얼굴 위치를 추적하며, 설정 파일에서 B-롤 클립, 브랜드 자산, 마스코트 등을 불러와 컷어웨이(cut-away), 깊이 효과(depth moment: 스피커 뒤에 큰 글자나 브랜드 배경을 배치), 그리고 음성 동기화 그래픽을 결합합니다. 각 장면(beat)은 2~4초마다 변화하며, 자막은 사용하지 않지만 핵심 키워드 그래픽은 허용됩니다. 이 스킬은 주로 Windows/macOS/Linux에서 Python 스크립트를 통해 실행되며, Hyperframes라는 프론트엔드 렌더링 엔진을 사용하여 최종 동영상을 생성합니다. ffprobe, ffmpeg 및 whisper 같은 도구를 단계별로 활용하며, 사용자와의 대화를 통해 누락된 입력(예: 테이크 상태, 주석 키워드, 발음이 어려운 이름 등)을 보충합니다. 코드 예제는 `examples/story/story_stoodi_inviteraw.py`에 제공되어 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Jenesyx/arta-edit-studio/tree/main/.claude/skills/reel-story

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

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

문서

Reel — 스토리 편집(전체 화면, 움직임)

스피커는 항상 전체 화면으로 유지됩니다. 스토리는 크리에이터 본인의 클립으로의 컷어웨이, 음성에 따라 나타나는 스티커/카드/위젯, 반응하는 마스코트, 그리고 스피커 뒤에 큰 글자나 브랜드 배경이 위치하는 깊이 효과(人物 매트)로 전달됩니다. 작업 예시: examples/story/story_stoodi_inviteraw.py.

인수: $ARGUMENTS

기본값(사용자가 명시적으로 변경을 요청한 경우만 변경)

먼저 reel.config.json을 읽습니다(없으면 reel.config.example.json으로 대체).

항목기본값
자막없음. 키워드 그래픽은 괜찮지만, 실행 중인 대본은 절대 표시하지 않음
오디오테이크 자체 믹스, 그대로 사용 — finish.py가 리먹싱. 효과음, 배경 음악 없음
테이크이미 컷, 그레이딩, 음악이 추가되었다고 가정 → 컷이나 그레이딩하지 않음. Raw/미편집 → 먼저 질문
B-롤설정 파일의 broll_dir; 설명은 work/_catalog/<폴더>/NOTES.md에 있음
브랜드설정 파일의 brand + palette. 마스코트 파일이 없으면 마스코트 장면 없음
CTA댓글 키워드를 화면에 크게 표시; 팔로우 카드 = @<creator.handle> 텍스트만, 얼굴 크롭 절대 안 함
언어설정 파일의 language(Whisper 및 사용할 텍스트 클래스를 결정)

입력

테이크 이름과 주제는 인수에서 받아옵니다. 한 번에 하나의 메시지로, 누락된 항목(테이크가 이미 컷/그레이딩/음악이 포함되었는지, 댓글 키워드, Whisper가 잘못 들을 수 있는 이름이나 전문 용어, 포함/제외할 클립)만 질문합니다.

파이프라인

PY = .venv/Scripts/python.exe -X utf8 (Windows) or .venv/bin/python -X utf8 (macOS/Linux). 긴 단계는 백그라운드에서 실행.

#단계명령 / 동작확인
1보기ffprobe로 테이크 정보 확인; 연락처 시트 ffmpeg -i raw/<take> -vf fps=1/5,scale=216:384,tile=9x2 -frames:v 1 work/<take>/sheet.jpg 생성 및 확인머리 위 여유 공간, 텍스트가 프레임 내에서 반전되어 있는지?, 이미 그레이딩되었는지?
2전사$PY tools/transcribe.py <take> --prompt "<names, jargon>"이름 교정; 단어 간격 > 3초 → 해당 구간 다시 전사
3얼굴$PY tools/face_track.py <take>FACE = (x, y) 및 머리 위쪽 출력
4B-롤$PY tools/story_assets.py <take> catalog; NOTES.md 읽기; 아직 설명되지 않은 클립 조각을 보고 NOTES.md에 해당 행 추가HDR / 반전 / VFR 플래그 확인
5비트 시트work/<take>/beats.md 작성: time | words | mode | what. 아래 규칙 참조, 기법은 references/techniques.md 참조모든 비트가 단어에 연결되어야 함
6매트깊이 효과가 있으면: $PY tools/story_assets.py <take> matte (~80초 분량 CPU 약 8분, 백그라운드, ffmpeg 병렬 처리 안 함)work/<take>/matte/fg.webm
7테이크 모듈examples/story/story_stoodi_inviteraw.py 복사 → tools/story_<slug>.py (slug: 테이크 이름, 영숫자가 아닌 문자는 _로 변환); NAME, FACE, BROLL, TILES, MIRRORED, scenes, SCENES 설정(DUR는 선택 사항 — 자동 탐지). 마스코트 이름 = assets/mascot 내 파일명(소문자, 공백은 -로 변환)
8자산$PY tools/story_assets.py <take> all (마스코트, 로고, B-롤 트림, 타일)
9빌드$PY tools/story_build.py <take>; work/<take>/sc 디렉토리에서: npx hyperframes lint public → 0 오류 (nested_structure 경고는 정상); npx hyperframes snapshot public -o ../snaps --no-end --describe false --at <모든 비트>; 연락처 시트 읽고, 수정, 다시 빌드
10빠른 렌더링$PY tools/finish.py <take> --seconds 12; work/<take>/sc/quick_sheet.jpg 확인오버레이가 들어오고 나가야 함; 색상이 어둡지 않아야 함
11전체 렌더링$PY tools/finish.py <take> (~80초 분량 약 12분, 백그라운드) → final/<take>/, 확인, qa/sheet.jpg 생성시트를 프레임별로 확인
12보고서경로, 길이, 비트, 사용된 클립, 반전/톤 매핑된 항목, 결과 확인. 새로 알게 된 내용이 있으면 이 스킬에 추가

비트 규칙

  • 2~4초마다 무언가가 변경되어야 함. 스피커만 나오는 구간은 약 5초를 초과하지 않음.
  • 모드를 혼합: 스피커 + 스티커 · B-롤 컷어웨이(런타임의 약 25–30%) · 깊이 효과(릴당 46회) · 스피커가 페이스캠 버블로 표시되는 전체 화면 그래픽(최대 12회).
  • 큐(Cue) = transcript.json에서 음성이 시작되는 시간. 각 요소는 다음 비트 전에 사라져야 함.
  • 깊이 단어는 머리 위에 위치(3단계에서 얻은 머리 위쪽): 한 번에 하나의 큰 단어, 이전 단어는 날아가 사라짐. 여러 줄이 쌓이면 머리 뒤에 가려지므로 주의.
  • 안전 구역: y 150(Instagram 헤더) 위나 y 1560(캡션) 아래에는 텍스트를 배치하지 않음; y 1100~1650 사이에서는 x < 960 유지(좋아요/댓글 버튼 영역).
  • 숫자로 표시되는 사실은 반드시 테이크에서 가져와야 함. 설명적 레이블은 괜찮음.
  • 페르시아어/아랍어 텍스트: .fa 클래스 사용(요소에만 RTL 적용 — <html>에 dir="rtl" 사용 금지, 검은색으로 렌더링됨), letter-spacing: 0, 숫자는 fa() 사용, 큰 0은 라틴어 0으로 표시(페르시아어 0은 점). 라틴 텍스트: .en; 큰 표시 단어: .blk.

엔진 계약 — 이미 해결된 버그

  • Scene = def scene(c: Comp): c.clip(layer, id, start, end, html, track), c.broll(name, a, b, mstart), c.matte(n, a, b), c.j(js...). 레이어: under(버블 뒤), tiles, behind(테이크와 매트 사이), fw, broll, over, fx.
  • 클립 div는 id k-<id>를 가짐; #<id>-i 또는 내부 id를 애니메이션 — 절대 .clip 자체를 애니메이션하지 않음.
  • 화면 밖에서 슬라이드 인하는 모든 요소는 from 상태에 autoAlpha:0이 있어야 함. 그렇지 않으면 일찍 보임.
  • 요소의 첫 번째 트윈은 초기 상태를 설정함(fromTo는 즉시 렌더링됨); 이후 트윈: .to 또는 immediateRender:false 사용.
  • from:"random" 지연 또는 Math.random 사용 금지 — DOM 순서는 Python에서 random.Random(seed)로 셔플.
  • 같은 속성, 같은 요소: 한 트윈이 끝나야 다음 트윈이 시작됨(lint overlapping_gsap_tweens 확인).
  • #cam scale/x/y/clipPath/borderRadius가 펀치인, 버블, 모자이크를 제어. 매트는 #cam 내부에 있으므로 깊이 효과는 카메라 스케일에 관계없이 정렬 유지.
  • 읽을 수 있는 텍스트가 포함된 전면 카메라 B-롤 → MIRRORED에 추가. 메인 테이크는 절대 반전하지 않음.
  • HLG/HDR 소스는 story_assets.py에 의해 톤 매핑됨. finish.py가 "HDR auto-promotion"에서 멈추면, 해당 경로를 벗어난 소스가 있음.
  • hyperframes snapshot은 렌더링의 증거가 아님 — 10단계가 그 역할을 함.

Individual skills in this repo

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

관련 스킬