애니메이션 릴
입력: 스크립트 + 각 줄에 하나의 음성 MP3 (사용자가 둘 다 첨부). 출력: 9:16 릴과 16:9 복사본, 각각 원본 오디오 포함, 그리고 WhatsApp용 20MB 미만 720p 복사본.
엄격한 규칙 (매 실행마다)
- 모든 것을 코드로 그리기: HTML 캔버스, 헤드리스 Chrome에서 프레임별로 렌더링, ffmpeg로 인코딩. 스톡 푸티지, 이미지 생성기 사용 금지.
engine/을 베이스로 사용하고, 확장하되 대체하지 않아 외형이 항상 동일하게 유지되도록 함. - 모든 단어를 강제 정렬(torchaudio MMS_FA,
scripts/align.py사용)로 시간 맞추기. 절대 타이밍을 추측하지 않음. 정렬이 실패하면 중단하고 사용자에게 이유를 알림; 균등 간격으로 대체하지 않음. - 전체 렌더링 전에 스틸 컷 연락처 시트를 보여주고 승인을 기다림.
- 기존 파일을 덮어쓰기 전에 물어봄.
encode.sh는 덮어쓰기를 거부하고 종료 코드 2를 반환하므로, 이를 사용자에게 전달. - 최종 MP4에서 원본 오디오를 그대로 유지 (음성 라인은 타임라인에만 배치하고 재처리하지 않음). 사용자가 요청하지 않으면 배경 음악 없음.
방법
- 설정.
bash scripts/check_setup.sh실행 (ffmpeg, Node, puppeteer, torch/torchaudio, uroman). 누락된 항목이 있으면 수정 후 계속.bash scripts/sfx.sh <project>/sfx를 실행하여 ffmpeg로 히트/휘파람/충격/팝 효과음을 합성. - 스크립트를 샷으로 분할. 음성 라인당 하나의 샷. 각각에 대해
id,speaker,text(MP3가 말하는 내용과 정확히 일치),audio경로,place(rooftop, office, street, bedroom, sky, 또는 새drawPlace분기 추가),camera(static|push|pull|pan+amount),cast,slots(left/center/right),fx를 작성.shots.json으로 저장 (스키마는scripts/build_timeline.py참조). 샷 목록을 보여주고, 모호한 경우 사용자가 수정할 수 있도록 함. - 캐릭터. 각 캐릭터를
characters에 정의 (name, skin, hair, hairStyle spiky|bob|long|short, eye, outfit, accent,color= 해당 캐릭터의 캡션 색상). 반드시 오리지널이어야 하며, 기존 애니메이션에서 복사하지 않음. 애니메이션 스타일: 크고 하이라이트가 있는 눈, 두껍고 깔끔한 외곽선, 평면 색상 + 정확히 하나의 음영. 캐릭터 시트를 렌더링하고 JSON을 단일 진실 공급원으로 유지하여 샷 간에 캐릭터가 변경되지 않도록 함:node scripts/render_frames.mjs sheet timeline.json landscape out/character_sheet.png - 정렬 및 립싱크.
python3 scripts/build_timeline.py shots.json timeline.json work는 MMS_FA를 각 라인에 대해 실행(단어 타이밍)하고, 각 캐릭터의 입 열림 곡선을 해당 음성 라인의 음량(mouth.py)으로부터 구성. 깜박임과 유휴 동작은 엔진에 내장됨. 영어가 아닌 라인의 경우,align.py는 uroman으로 로마자 변환하지만 화면에는 원래 철자를 유지. - 주요 라인의 애니메이션 트릭 (
fx에 추가, 시간은 샷 시작부터 초 단위):speedlines는 공개 및 결의 장면에,impact(흰색/검정 플래시 프레임, `sfx: