Kinetix: 코드로 만드는 릴
Kinetix는 저장소(repo)에 있습니다. (PATH 상의 kinetix, $KINETIX_HOME, 또는 runtime/kinetix.js가 있는 kinetix/ 체크아웃에서 찾을 수 있습니다.)
아래 명령은 모두 kinetix <cmd>로 실행합니다. 먼저 kinetix doctor를 실행하고, 빠진 부분이 있으면 ./setup.sh를 실행하세요.
모델: 모든 프레임은 시간의 순수 함수입니다. 릴(reel)은 타임라인에 장면이 있는 index.html입니다. 사운드트랙은 동일한 비트 그리드 위에서 music.py로 제작되어, 컷, 떨림, 드롭이 함께 맞아떨어집니다.
1. 먼저 실제 자료를 수집하세요
- 스토리는 제품 자체의 말에서 나옵니다. README, 사이트 카피, 앱 문자열을 읽고 인용하세요. 통계, 사용자, 수상, 속도를 절대 지어내지 마세요.
- 실제를 보여주세요. 앱 스크린샷, 화면 녹화, 또는 Playwright로 2× DPI로 캡처한 라이브 웹 페이지를 사용하세요. 캡처 시 라이브 백엔드에 접속하게 된다면, 실제 레코드를 생성하는 대신 브라우저에서 API를 모의(mock) 처리(
page.route)하세요. 시뮬레이션 또는 데모 영상은 그렇게 표시하세요. - 숫자는 한 번만 선택하세요. 출처가 일치하지 않으면(1.2초 vs 1.5초), 하나의 값을 일관되게 사용하고 인수인계 시 어떤 값을 사용했는지 말하세요.
- 음성은 선택 사항입니다. 음성 라인의 경우 사용자가 키를 보유한 TTS API(
tools/tts_sarvam.py는 인도 언어용)를 사용한 다음kinetix captions를 실행하세요.
2. 그리드에서 계획하세요
150 BPM에서 비트는 0.4초, 마디(bar)는 1.6초입니다. 모든 구역 경계와 모든 큰 히트는 비트 위에 있어야 합니다. 검증된 50~60초 형태:
| 구역 | 마디 | 역할 |
|---|---|---|
| 콜드 오프닝 | 3 | 2초 이내의 공감 가는 훅: 시점(POV) + 문제점 |
| 빌드 | 6–7 | 마디 컷으로 점점 고조, 이후 라이저(riser) |
| 갭 | ¼ | 거의 무음 0.4초 ("그때까지…") |
| 드롭 1 | 8 | 로고 슬램, 이후 제품 흐름, 액션당 한 비트 |
| 하프타임 | 4–5 | 반전 또는 깊이, 필터 처리되고 더 조용하게 |
| 드롭 2 | 8–10 | 빠른 플렉스: 영상, 실제 통계, 증거 |
| 아웃트로 | 3 | 로고, 태그라인, URL, 페이드 아웃 |
텍스트는 읽을 수 있어야 합니다. 빠르게 들어오고, 유지: 레이블은 약 0.8초, 문장은 단어당 0.3초. 순차 텍스트는 매 다른 비트에 배치합니다. 텍스트가 아닌 악센트만 매 비트마다 올 수 있습니다.
3. 릴을 제작하세요
kinetix new my-reel # 세로 방향; 1920x1080의 경우 --landscape 추가
my-reel/index.html은 런타임을 사용합니다. (references/runtime.md):
const K = Kinetix.init({ width: 1080, height: 1920, bpm: 150, build: [[3.2, 9.2]], drops: [[9.6, 16]], glitches: [9.6], fonts: [...] });
K.scene(9.6, 12.8, `<div class="c big t" style="left:540px;top:800px;font-size:230px">BRAND</div>`,
(lt, q) => K.slam(q(".t"), lt, 0, { from: 3 }));
K.start({ dur: 19.2 }).then(({ timeline }) => { window.__timelines["main"] = timeline; }); // 이 문자 그대로 유지
장면 패턴(전화기 프레임, 홀로그램 영상 패널, 통계 슬램, 채팅 버블, 카운터, 타이핑)은 references/recipes.md에 있습니다.
브랜드를 유지하세요: 제품의 색상, 글꼴, 로고를 가져와 kinetix.css의 :root 변수로 테마를 적용하세요.
4. 사운드트랙 제작 (references/music.md)
- 배경음:
kinetix music gen "<장르, 악기, 분위기>" --bpm 150 --seconds 60 -o my-reel/assets/bed.wav. MusicGen은 프롬프트의 BPM을 따르며, 도구가 정확한 그리드로 시간 늘이기를 수행하고bed.json을 작성합니다. GPU나 MusicGen이 없으면Mix(bpm=150, seconds=DUR)로 순수 신디사이저 믹스를 만듭니다. music.py:m = Mix("assets/bed.wav", seconds=DUR), 그 다음:- 장면과 동일한 시간에 히트 배치:
m.add(t, h.impact()),m.drums(...),m.sfx("impact/...") - 편곡 형태 만들기:
m.lowpass([(t, hz), ...]),m.bed_level(...),m.gap(14.0, 14.4) - 그런 다음
kinetix mix my-reel실행.
- 장면과 동일한 시간에 히트 배치:
- 다이나믹 확인 (들을 수 없으므로 측정). 구역별 RMS는 빌드에서 드롭으로 올라가고, 하프타임에서 낮아지며, 드롭에서 정점을 찍어야 합니다. 빌드가 드롭보다 크면 빌드의 신디사이저 레이어를 낮추세요. 또한 스펙트로그램(
ffmpeg ... showspectrumpic)을 렌더링하고 살펴보세요. - 음성: 믹싱 후, Whisper로 믹스된 구간에서 음성이 들리는지 확인하세요.
5. 캡션 (선택 사항, 음성 필요)
captions-lines.json은 [{"clip": "assets/line1.wav", "at": 1.62, "text": "exact script", "y": 600}]을 보유합니다. 그런 다음 kinetix captions my-reel을 실행하세요. Whisper는 스크립트를 프롬프트로 사용하여 영어 모드로 실행되므로, 힌글리시(Hinglish) 및 기타 로마자 표기 라인의 철자가 유지됩니다. 페이지는 라인별로 빌드됩니다.
6. 확인: 보고, 게이트하기
kinetix snap my-reel 1.5,4,9,..., 장면당 한 번씩. 연속 사진(contact sheets)을 열고 실제로 보세요. 빈 프레임은 JS 오류 또는 등록되지 않은 타임라인을 의미합니다.kinetix check my-reel은 0.5초마다 샘플링하며, 에러 0개로 끝나야 합니다.- 실제 발견 사항 수정: 텍스트가 박스를 넘침, 겹침, 숨겨진 텍스트, 대비 문제.
- 의도적인 레이어링만 표시하고 실제 문제는 절대 표시하지 마세요: 문서 위의 스탬프에는
data-layout-allow-overlap, 스프라이트 위에 의도적으로 배치된 텍스트에는data-layout-allow-occlusion, 프레임 안에 잘린 스크린샷에는data-layout-allow-overflow, 장식용 배경 또는 크고 흐릿한 이모지에는data-layout-ignore. - "수정"이 보였다고 주장하기 전에, 전후 프레임을 비교하세요. 일부 발견 사항은 체커의 오탐(false positive)일 수 있습니다.
7. 효과 및 렌더링
kinetix fx leak --hue 200 -o overlays/leak-cyan.mov # 색조: 0 호박색, 70 분홍, 200 시안, 290 라임
kinetix fx stinger --colors "#c8ff3d,#5a45c9" -o overlays/stinger.mov
kinetix render my-reel -o out.mp4 --overlay overlays/[email protected]:0.8 --overlay overlays/[email protected] --poster 18.3
- Leaks:
leak-*파일은 밝게 스크린(screened)되어 텍스트가 읽기 쉽습니다. 드롭 약 0.4초 전에 leak을 시작하여 드롭에서 정점을 찍도록 하고, 로고 슬램에서 정점을 찍지 않도록 하세요. - Stingers: 컷 약 0.3초 전에 시작하여 패널이 컷을 덮도록 하세요.
- 포스터:
--poster는 가장 잘 정착된 프레임을 프레임 0으로 굽는데, 이는 X, YouTube, Slack, Discord에서 썸네일이 됩니다. 로고 카드나 핵심 장면을 선택하고, 절대 애니메이션 중간이나 플래시가 있는 프레임은 선택하지 마세요. - 최종 확인: 최종 mp4에서 프레임(프레임 0, 각 오버레이 피크, 각 영상 장면)을 추출하여 살펴보세요.
주의 사항 (모두 실제로 발생했습니다)
- 브릿지는
{ timeline }을 반환합니다, 타임라인이 아닙니다. GSAP 타임라인은 thenable이므로, async 함수에서 그것을 맨몸으로 반환하면 영원히 중단되고 모든 프레임이 빈 상태로 렌더링됩니다. - 디스플레이 글꼴의 하이라이트 박스는
line-height: 1.12가 필요합니다 (이미kinetix.css에 있음). 그렇지 않으면 글리프가 튀어나와check가text_box_overflow를 플래그합니다. - 영상은 시간이 지정되지 않은 래퍼에
<video muted data-start data-duration [data-media-start]>여야 하며, 절대 JPG 시퀀스가 아니어야 합니다. 비디오가 아닌 래퍼를 애니메이션 처리하세요. - 이미지 교체(화면 A → B)는
KinetixBridge.stackSet(img, src)를 사용하며, 변형을 미리 디코딩합니다. 렌더링 시점에src를 설정하면 디코딩되지 않은 프레임이 캡처됩니다. - 모든 명명된 글꼴에는
@font-face가 필요합니다. 시스템 이모지 글꼴의 경우src: local("Noto Color Emoji");를 선언하세요. - MusicGen 배경음: librosa의
beat_track은 펑크(phonk) 및 클럽 템포를 잘못 읽습니다(150 BPM을 "121" 및 "199"라고 부름). 이것이hypebeat가 onset 자기상관을 사용하고 스트레칭을 ±12%로 제한하는 이유입니다. musicgen-medium은 로드하는 데 약 8GB의 여유 RAM이 필요합니다. small이 기본값입니다. - 캡션: 모든 라인을 하나의
createTikTokStyleCaptions호출로 풀링하면 라인의 마지막 단어가 다음 라인으로 병합되므로, 라인별 페이지를 사용하세요(런타임이 그렇게 함). - Remotion:
--gl=swangle(소프트웨어 GL이 모든 곳에서 작동)로 렌더링하고, 알파 채널이 있는 ProRes 4444로 렌더링하세요. ffmpeg의 VP9 디코더는 알파를 드롭합니다. - 라이선스:
- MusicGen 출력은 CC-BY-NC로, 데모 및 개인 채널에는 괜찮지만 유료 작업에는 사용할 수 없습니다.
- Remotion은 개인 및 최대 3명의 회사에 무료입니다.
- 번들된 SFX는 CC0입니다.
인수인계
사용자에게 알리세요:
- mp4 파일 위치
- 포함 내용 (짧은 비트별 목록)
- 확인한 내용과 방법 (연속 사진, 확인 결과, 음량)
- 선택한 숫자나 주장
- 확인할 수 없었던 내용 (들을 수 없으므로 듣도록 요청)
게시를 제안하되, 승인 없이는 게시하지 마세요.