rudywizz-motion은(는) 무엇을 하나요?
결정론적 렌더러: 모든 프레임이 계산되고(헤드리스 Chromium + WebGL2) ffmpeg로 파이프되므로, 동일한 입력은 항상 동일한 비디오를 생성합니다. 이 폴더는 자체 포함되어 있습니다:
engine/ cli.mjs (진입점), host.js, timeline.js, camera.js, gl/ (셰이더), data/ (지도), fonts/
styles/ 스타일당 하나의 폴더 (style.js)
templates/ 미리 제작된 컴포지션 (JSON)
assets/demo/ 원본 데모 일러스트레이션 (CC0)
1. 일회성 설정 (첫 번째 렌더링 전에 확인)
RM="${CLAUDE_SKILL_DIR}" # 이 SKILL.md가 있는 폴더
[ -f "$RM/engine/cli.mjs" ] || RM=$(ls -dt "${CLAUDE_PLUGIN_ROOT}/skills/rudywizz-motion" ~/.claude/plugins/cache/*/rudywizz-motion/*/skills/rudywizz-motion ~/.claude/skills/rudywizz-motion .claude/skills/rudywizz-motion 2>/dev/null | head -1)
TMP=$(node -p "require('os').tmpdir()") # bash와 Node가 모두 동의하는 임시 디렉토리 (Windows에서도)
cd "$RM" && npm install --no-audit --no-fund # playwright 설치 (유일한 종속성)
node engine/cli.mjs doctor # Node ✓ ffmpeg ✓ 브라우저 ✓ WebGL2 ✓ — 각 ✗에 대한 해결 방법 출력
사용자 폴더에서 node "$RM/engine/cli.mjs" …로 렌더링을 실행하여 상대 경로가 거기에서 확인되도록 합니다.
브라우저 확인에 실패하면: npx playwright install chromium (또는 RM_CHROME=/path/to/chrome 설정).
ffmpeg가 없으면 사용자에게 설치 방법을 알려줍니다(macOS brew install ffmpeg, Windows winget install ffmpeg, Linux apt install ffmpeg).
2. 작업 유형 선택
| 사용자가 원하는 것 | 수행할 작업 |
|---|---|
| 하나의 애니메이션 텍스트/타이틀 | render <style> --text "…" |
| 지도 / 경로 애니메이션 | render map-route --set 'route=["İstanbul","Konya"]' |
| 자신의 이미지를 에칭으로 변환 | render image --image photo.jpg --look engrave --grade sepia --film 0.6 |
| 자신의 클립에 카메라 움직임 적용 | render clip --clip in.mp4 --camera handheld --set speed='"ramp-mid"' |
| 편집기용 투명 오버레이 (로우더 서드, 캡션, CTA) | render lower-third --text "이름 / 역할" --alpha --out name.mov |
| 다중 장면 릴 / 다큐 / 티저 / 인트로 | init reel.json 또는 템플릿에서 시작하여 편집 (4번 섹션) |
템플릿: node engine/cli.mjs templates - 한 줄 설명과 함께 모두 나열합니다.
사용자의 에셋 옆에 복사(cp "$RM/templates/<name>.json" .), 텍스트/경로 편집, 렌더링.
3. 워크플로우 (항상)
- 스타일, 텍스트, 형식(기본 9:16 1080×1920), 카메라, 그레이드를 결정합니다.
- 먼저 스틸 샷을 확인하세요 — 저렴하고 레이아웃 문제를 잡아냅니다:
node "$RM/engine/cli.mjs" still <style|comp.json> --at 2.5 --size 540 --out "$TMP/check.png"→ PNG를 열어 확인합니다. 2~3개의 순간(각 장면의 시작, 중간, 끝)을 확인합니다.warning/error줄을 읽으세요: 오타를 지적하고 올바른 키를 제안합니다. - 렌더링:
node engine/cli.mjs render … --out out.mp4 - 확인:
ffprobe -v error -show_entries format=duration -of csv=p=0 out.mp4로 한두 프레임을 캡처합니다. - 파일을 한 줄 컨텍스트와 함께 전달합니다.
경험 법칙
- 짧은 텍스트가 좋습니다: 줄당 1~6단어, 최대 ~4줄. 줄바꿈에는
" / "또는\n을 사용하세요. - 텍스트에 ğ/ş/ı/İ가 있으면 터키어 대소문자가 자동으로 적용됩니다. 그렇지 않으면 터키어 텍스트의 경우
--lang tr을 전달합니다 (i → İ). - 렌더링은 CPU 집약적입니다: 1080p 프레임당 약 0.2~0.5초.
--size 540으로 미리보기하고 최종은 1080p로 하세요. - 사용자의 명시적 동의 없이 웹에서 이미지/클립을 다운로드하지 마세요. 사용자의 파일을 사용하세요.
- 투명 오버레이:
--alpha --out file.mov(ProRes 4444) 또는.webm. - 음악:
--audio song.mp3및--bpm N을 사용하여beat-cut,lyric-video및beat-punch카메라가 박자에 맞춰지도록 합니다.
4. 컴포지션 JSON
{
"format": "9:16",
"lang": "tr",
"bpm": 96,
"audio": "song.mp3",
"look": { "grade": "teal-orange", "bloom": 0.3, "grain": 0.05, "leak": 0.2, "aberration": 0.3,
"vignette": 0.3, "film": 0, "weave": 0, "distortion": 0 },
"motionBlur": 1,
"scenes": [
{ "style": "map-route", "route": ["İstanbul", "Kapadokya"], "duration": 6, "camera": "drift",
"transition": { "type": "whip", "duration": 0.45, "dir": "left" } },
{ "clip": "beach.mp4", "in": 3.2, "duration": 2.5, "speed": "ramp-mid", "camera": "handheld",
"overlay": { "style": "captions", "text": "Kaş, Antalya" },
"transition": { "type": "burn", "duration": 0.8 } },
{ "image": "portrait.jpg", "look": { "type": "engrave", "reveal": 3 }, "duration": 4, "camera": "push-in" },
{ "style": "neon-sign", "text": "See you / soon", "duration": 3 }
],
"overlays": [ { "style": "captions", "text": "…", "from": 0, "to": 5 } ]
}
- 장면 유형:
style(모든 스타일 ID + 해당 옵션),image(image경로, 또는 2.5D 시차 효과를 위한layers: [{src, depth}]),clip(clip,in,speed: 숫자 |ramp-in|ramp-out|ramp-mid),color. - 경로는 JSON 파일을 기준으로 합니다.
transition은 해당 장면이 끝날 때 적용됩니다. 다음 장면은 이 장면이 끝나기duration초 전에 시작됩니다.overlay= 해당 장면 위에 그려지는 스타일(카메라와 함께 움직임).overlays= 모든 것 위에 고정, 그레이드되지 않음.- 카메라: 프리셋 이름 또는
{ "preset": "drift", "amount": 0.6, "shake": 0.5, "keys": [{ "at": 0, "zoom": 1 }, { "at": 1, "zoom": 1.3, "ease": "outExpo" }] }.
5. 카탈로그
카메라 — static, drift, push-in, pull-out, punch-in, crash-zoom, whip-from-left, whip-from-right, whip-from-top, spin-in, rise, orbit, tilt-reveal, tilt-left, tilt-right, vertigo, handheld, float, beat-punch. 카메라 움직임은 자동으로 모션 블러가 적용됩니다.
전환 — cut, fade, flash, dip, whip, zoom, spin, glitch, ink, burn, liquid, iris, wipe, blinds, pixelate, leak, cube, ripple, doors, stretch, luma.
룩 (이미지/클립) — engrave (잉크가 그려짐 → 해칭 → 세피아 워시), sketch, oldphoto, duotone, halftone, posterize, noir. 옵션: { "type": "engrave", "reveal": 3, "delay": 0.2, "paper": "#ece0c4", "ink": "#33210f" }.
그레이드 — none, teal-orange, kodak, fuji, sepia, noir, bleach, cyber, sunset, matte (+ gradeAmount 0–1).
스타일 — node engine/cli.mjs list 명령으로 실시간 목록을 확인하세요. 각 스타일의 옵션은 styles/<id>/style.js 상단에 문서화되어 있습니다 (defaults + options).
| 스타일 | 설명 | 주요 옵션 |
|---|---|---|
| map-route | 지구본/평면 지도/터키 주 위의 경로 비행, 핀 + 라벨 | route, mode globe·flat·turkey·auto, theme dark·atlas·light, icon, highlight |
| history-title | 금박 연도 카운터 + 챕터 타이틀 | text "1453 / Title / Subtitle", from |
| parchment-letter | 불에 탄 양피지, 손글씨 + 깃펜 + 밀랍 인장 | place, signature, seal |
| murmuration | 찌르레기 떼가 단어로 접힘 | birds, 하늘 색상 |
| led-marquee | 상점/미니버스 LED "kayan yazı" 보드 | 줄당 하나의 보드, colors |
| receipt | 감열지 프린터가 메시지를 인쇄하고 찢어짐 | header, items, total, date |
| ink-bleed | 잉크 방울이 글자로 퍼짐 | ink, paper |
| halftone-press | 2색 등사 인쇄 | inkA, inkB, dot |
| signal-tune | 구형 TV: 스노우 → 테스트 카드 → 방송 | channel, station |
| inflate | Y2K 크롬 풍선 글자 | chrome, face |
| orbit-ring | 행성 주위의 텍스트 고리 | 줄당 하나의 고리 |
| beat-cut | 박자당 하나의 스탬프 단어, 스위스 포스터 스타일 | bpm, offset |
| lyric-video | 박자에 맞춰 단어별로 조명되는 가사 | bpm, times, credit |
| captions | 릴 캡션, 활성 단어가 알약 모양으로 강조 (--alpha 사용) | times, maxWords, pill, position |
| split-flap | 출발 보드 플립 (터키식 드럼) | title, cols |
| neon-sign | 벽돌 위 네온 튜브, 하나는 고장남 | colors, broken |
| odometer | 숫자까지 굴러가는 롤링 숫자 | text "10000 takipçi", prefix, suffix |
| pixel-quest | 8비트 타이틀 화면 | pixel, subtitle |
| vhs-memory | 홈 비디오 테이프 룩 | date, clock |
| 운동 타이포그래피 | ||
| word-stack | 양쪽 정렬 포스터 스택, 각 줄이 전체 너비로 박힘 | accent, beat, kicker |
| typewriter | 키별로 타이핑되며 깜박이는 커서 | theme paper·terminal, speed, prompt |
| scramble | 무작위 문자들이 텍스트로 디코딩 | font mono·display, resolve, hud |
| ticker-rows | 거대한 행이 교차 방향으로 스크롤 | rows, tilt, speed, accent |
| highlight-quote | 인용문이 페이드 인, 마커가 키워드를 훑음 | author, highlight (단어), marker |
| glitch-title | RGB 분할 + 데이터모시가 깨끗한 타이틀로 안착 | subtitle, colors, every |
| 3D | ||
| extrude-3d | 통통한 돌출 글자가 스윙하며 회전 | face, side, bg, depth |
| cube-spin | 큐브가 면을 돌며 한 면당 한 줄 | colors, ink, floor |
| text-tunnel | 텍스트 고리를 통과하여 타이틀로 비행 | line 1 = 타이틀, rings, ring, colors |
| retro-grid | 신스웨이브 그리드, 줄무늬 태양, 크롬 타이틀 | line 1 크롬, 나머지 스크립트, sky, sun, speed |
| particle-sphere | 입자 구체가 단어로 변형 | count, morphAt, colors |
| card-carousel | 카드의 3D 링이 마지막 줄에 착지 | images (로컬 파일), turns, colors |
| 소셜 및 방송 | ||
| countdown | 3·2·1 링 스위프, 그 다음 텍스트 | from, tick, accent |
| lower-third | 뉴스/유튜브 이름 스트랩 (--alpha 사용) | line 1 이름, line 2 역할, theme solid·glass·minimal, position |
| chat-story | 메시징 채팅, 타이핑 점 | 한 줄당 하나의 메시지, > = 나, name, theme |
| bar-chart | 막대 차트 경주, 값이 올라감 | items: [["A",10],…], unit, note, source |
| cta-follow | 커서가 팔로우를 클릭, 체크 + 컨페티 | line 1 핸들, line 2 버튼, line 3 부제목, done |
스타일 옵션은 --set key=value (JSON 값: --set 'route=["A","B"]') 또는 장면 객체의 키로 전달합니다.
6. 문제 해결
unknown place "X"(map-route):"lat,lon"또는{ "name": "X", "lat": 0, "lon": 0 }을 사용하세요.- 카메라 움직임에 의해 텍스트 잘림: 카메라
amount를 낮추거나drift/float를 사용하세요. - 느린 렌더링: 초안에는
--size 540을 사용하세요. 최고 품질이 필요하지 않다면--motion-blur를 4 이상으로 설정하지 마세요. - 출력이 흰색/비어 있음:
still을 실행하고 오류를 읽으세요.doctor가 WebGL2를 확인합니다. - Windows PowerShell / cmd가
--set 'route=["A","B"]'를 망가뜨림: 옵션을 파일에 쓰고--params opts.json을 사용하거나 컴포지션 JSON을 사용하세요. - 터키어 이름(ı, ş…)을 포함하는 영어 텍스트는 자동으로 터키어 대소문자가 적용됩니다. 이를 중지하려면
--lang en을 전달하세요.