Motion explainer(영상 강화판)— 애니메이션으로 원리 설명, 사진은 증거, AI 영상은 감정 전달
이 스킬은 "인터넷 검색 → 대본 작성 → 중국어 내레이션 → 프레임별 애니메이션 제작 → 자막 → 색상 구성 → 라이선스 사진 검색 및 일러스트 생성 → AI 영상 생성 → 자체 심사 → MP4 출력"을 하나의 고정된 워크플로우로 연결합니다. 기본 버전 motion-explainer와 비교하여 섹션 7.5의 이미지 레이어, 섹션 7.6의 AI 비디오 레이어, 그리고 섹션 4의 잘못 발음된 단어 수정이 추가되었습니다. 다른 모든 단계는 동일합니다. 영상素材는 AI 생성 위주입니다: 뉴스, 홍보 영상, 스톡 비디오는 거의 저작권이 있으므로 교육 영상에 편집하지 않습니다. 이 스킬은 세 가지 요소를 기반으로 합니다:
- HyperFrames(HeyGen 오픈소스, HTML + GSAP MP4 출력) 및 공식 스킬, 특히
/hyperframes진입점과/faceless-explainer워크플로우. 방법은 공식 문서를 따릅니다. - 본 repo의
motion-design(취향 규칙: easing, 리듬, 일시 정지, 중국어 타이포그래피) 및review-loop(연속 접촉 시트를 통한 자체 심사). 시각적 품질은 이 두 가지를 기준으로 합니다. - 이 폴더
scripts/의 도구: 공식 워크플로우에서 제대로 처리하지 못하는 중국어 내레이션, 자막, 글꼴 일관성 및 3색 테마를 보완합니다.
references/lessons.md에는 실제 경험에서 얻은 교훈이 있습니다. 작업 시작 전에 반드시 읽어야 하며, 각 항목은 첫 번째 영상에서 실제로 발생했던 문제입니다.
0. 환경 점검(처음 사용 시)
- 먼저
python scripts/hw_check.py --project <프로젝트>실행: CPU, 메모리, GPU 및 디스크를 감지하고 어떤 내레이션 엔진을 사용할지,--workers를 얼마로 설정할지, sub-agent를 배치로 나눌지 제안합니다.references/hardware.md의 설명에 따라 사용자에게 알립니다. 제안은 추정치이며 벤치마크 점수가 아닙니다. - Node.js 22+, ffmpeg/ffprobe, Python 3 + Pillow + fonttools(
pip install fonttools;brotli가 설치되어 있으면 글꼴이 woff2로 출력되고, 그렇지 않으면 ttf로 출력됨). - HyperFrames CLI:
npm install -g hyperframes, 그 다음hyperframes doctor실행(Docker, Whisper, Kokoro, MusicGen은 모두 선택 사항). - 공식 스킬:
hyperframes skills update, 이런 유형의 영상을 만들려면hyperframes skills update faceless-explainer도 필요합니다. - 익명 사용 통계는 기본적으로 활성화되어 있습니다. 사용자에게
hyperframes telemetry disable을 할지 물어봅니다. - TTS(하나를 선택하고 사용자에게 물어봄):
- edge-tts(기본값):
pip install edge-tts, GPU 불필요, 생성 시 인터넷 연결 필요. 대만 억양은zh-TW-HsiaoChenNeural(여성),zh-TW-HsiaoYuNeural(여성),zh-TW-YunJheNeural(남성)이 있습니다. - Breeze TTS 2(고급): 로컬 NVIDIA GPU(약 7.7 GB VRAM, 12 GB 이상 권장; 모델 파일 약 7 GB), 텍스트 설명으로 음성을 디자인하고 음성 복제가 가능하며, 억양과 감정 제어가 가장 세밀합니다.
- 다른 엔진도 가능: 각 문장에 대해
assets/voice/raw/NN.wav를 출력할 수 있으면 됩니다. 영어 영상은 HyperFrames 내장 Kokoro/HeyGen을 사용할 수 있습니다.
- edge-tts(기본값):
1. 연구(인터넷 검색 가능 시)
- 주제에 대한 최신 데이터를 최소 두 개의 독립적인 출처에서 검색합니다. 숫자가 일치하지 않는 경우 기록하고 일관된 출처의 값을 사용합니다.
- 각 숫자는 세 가지 범주로 분류하며, 이후 화면에 반드시 표시합니다: 공식 주장 / 실측 또는 보도 / 자체 추정.
- 간단한 물리 또는 수학 추정을 직접 수행하여 시청자가 "계산 가능"하게 만듭니다. 이것이 교육 영상에서 가장 가치 있는 부분입니다. 추정은 항상 현실과 비교해야 합니다(예: "일반 자동차 최대 1.2 g"가 시판 차량 1.8초 0-100에 의해 반박될 경우 1.5 g로 수정).
- 브랜드 사진이나 로고는 사용하지 않습니다. 주인공은 직접 그린 일러스트를 사용하고 "일러스트"라고 표시합니다.
- 연구와 동시에 이미지线索(단서)를 기록합니다: "선례", "선배", "실험 사진"이 증거로 있을 수 있는지(예: NASA 역사 사진, 이미 존재하는 유사 제품). 이것들은 섹션 7.5에서 찾을 실제 사진입니다.
2. 요구 사항 인터뷰(/hyperframes의 의도 레이어를 따라 한 번에 모두 질문)
재생 플랫폼(비율 결정: 강의실/YouTube → 16:9), 길이(60–90초 권장, 내레이션 길이가 실제 영상 길이 결정), 내레이션 여부(권장), 스토리보드 사전 검토 여부, 자동화 또는 함께 조정하면서 진행할지 확인합니다.
세 가지 색상 추가 질문(이 스킬에서 새로 추가됨), 프레젠테이션 템플릿처럼:
- 배경색, 주색(텍스트 및 선 아트), 강조색(답변, 결론, 핵심 숫자, 섹션 카드에만 사용).
- 선호도가 없으면 기본값 권장: 검정 배경
#121212, 흰색 텍스트#F2F0EA, 주황색 강조#FF7A1A. - 글꼴: 영상 전체에 하나의 글꼴을 통일하여 사용합니다. 기본값은 원석흑체 두껍게(GenSeki Gothic Bold, OFL 라이선스, 중국어, 영어, 숫자, 자막 모두에 사용). 사용자가 지정한 글꼴이 있으면 변경하지만, 해당 글꼴을 자유롭게 사용할 수 있는지 확인해야 합니다.
- 색상과 글꼴은 프로젝트의
theme.json에 기록합니다(형식은templates/theme.example.json의bg/fg/accent/font참조).
요구 사항 요약을 "사용자 답변"과 "내가 추론한 것" 두 영역으로 나누어 정리하고, 사용자가 확인한 후에야 작업을 시작합니다.
3. 프로젝트 생성 및 스토리보드
hyperframes init videos/<kebab-name> --non-interactive --example=blank --skill=faceless-explainer실행, 그 다음BRIEF.md를 작성하고/faceless-explainer의 Step 0–2를 따릅니다(capture/extracted/, frame preset 하나 선택하여frame.md생성).- preset 선택 시 선 아트가 명확한 것을 우선 선택(예:
cobalt-grid). 이 preset은 "소스 색상"일 뿐이며, 최종적으로theme.py에 의해 사용자의 세 가지 색상으로 대체됩니다. frame.md에 번체 중국어 재정의(글꼴, 굵기, 자간, 행간, 프로젝터 최소 글자 크기)를 추가합니다. 내용은motion-design섹션 5를 따릅니다.bash scripts/fetch_fonts.sh <project>실행, 원석흑체 두껍게(공식 GitHub 릴리스에서 다운로드), frame worker 제작에 사용되는 라틴 글꼴 및 Noto TC를 모두assets/fonts/에 넣습니다. Google Fonts 온라인 로딩에 의존하지 마십시오.STORYBOARD.md와SCRIPT.md를 작성합니다(형식은 공식 storyboard-format / script-format 따름). 내레이션은 "절" 단위로 자릅니다. 각 쉼표는 화면이 공개되는 시점입니다. 숫자는 한자(예: "영점 팔 일 초")로 써서 TTS가 잘못 읽지 않도록 합니다.
4. 내레이션
assets/voice/raw/NN.wav생성(각 문장당 하나의 파일, NN은 스토리보드 프레임 번호):- edge-tts:
python scripts/edge_tts_voice.py --project <p> --voice zh-TW-HsiaoChenNeural [--rate -5%]. 영상 전체에 동일한 voice를 사용하여 자연스럽게 일관성을 유지합니다.--list zh-TW로 모든 음성을 나열할 수 있습니다. - Breeze TTS 2:
python scripts/breeze_voice.py --project <p> --breeze-repo … --model … --voice "<음성 설명>" --only-ref, 먼저 하나의 참조 음성을 디자인하여 사용자가 듣게 하고, 확인 후--only-ref를 제거하고 모든 문장을 생성합니다(각 문장이 이 참조 음성을 복제). 배치 러너가 있는 경우scripts/tts_jobs.py를 사용하여 작업 목록을 생성합니다. - 사용자가 아직 설치하지 않았거나 어떤 것을 선택할지 확신할 수 없는 경우:
references/tts-setup.md에 따라 조언을 제공하고, 단계별로 확인하며 임의로 설치하지 마십시오.
- edge-tts:
- 먼저 사용자가 처음 한두 문장을 미리 듣게 합니다. 억양과 감정은 사용자가 귀로 결정하며, 점수로 대체하지 않습니다. 만족스럽지 않으면 다른 voice로 변경하거나 속도를 조정하고, 이전 WAV를 삭제한 후 다시 생성합니다.
- 영상 전체를 완성한 후 특정 단어 발음이 잘못된 것을 발견한 경우(예: 영어 브랜드명, 다의어): 문장 전체를 다시 녹음하지 마십시오. 그렇지 않으면 해당 프레임의 애니메이션 타이밍이 모두 틀어집니다. 대신: 동일한 음성, 동일한 문장으로 4–6개의 후보를 생성합니다. seed를 변경하거나 철자를 변경할 수 있습니다(예:
Road-ster또는 동음동조 한자). 자막은 원문을 유지합니다.assets/voice/fix/cand/NN_X.wav에 넣습니다. 그런 다음python scripts/fix_voice.py --project . audition --line N --clauses <해당 단어가 있는 절>을 실행하여 키 부분을 연결하여 사용자가 귀로 선택할 수 있는 미리 듣기 파일을 만듭니다. 선택 후apply --line N --take NN_X를 실행하면 새 문장을 전체 비율로 원래 길이에 맞게 늘리고, 음량을 원래 문장에 맞추며, 해당 문장의 자막 타이밍을 다시 계산하여 각 프레임의 길이는 변경되지 않습니다. 그런 다음 자막 재구축 →patch_captions.py→.hyperframes/pre-theme/compositions/captions.html삭제(theme.py가 이전 자막으로 되돌리지 않도록) →theme.py→place_media.py→ 다시 출력합니다. 다시 녹음한 문장을 일시 중지에 따라 절로 자르고 타이밍을 맞추지 마십시오: 다시 녹음한 문장의 일시 중지 위치가 달라 절단 지점이 단어 중간에 위치하여 단어 누락 또는 중복이 발생할 수 있습니다(실제 발생 사례). ASR은 명백히 잘못된 것만 필터링하는 데 사용할 수 있습니다. 성조가 맞는지 ASR은 감지할 수 없습니다(실례: "타이어" ASR은 올바른 것으로 판단했지만 사용자는 잘못된 것으로 들림).
- 영상 전체를 완성한 후 특정 단어 발음이 잘못된 것을 발견한 경우(예: 영어 브랜드명, 다의어): 문장 전체를 다시 녹음하지 마십시오. 그렇지 않으면 해당 프레임의 애니메이션 타이밍이 모두 틀어집니다. 대신: 동일한 음성, 동일한 문장으로 4–6개의 후보를 생성합니다. seed를 변경하거나 철자를 변경할 수 있습니다(예:
python scripts/voice_meta.py --project <p>: 앞뒤 묵음 제거, 각 절의 시간 측정,audio_meta.json작성.node <faceless-explainer>/scripts/audio.mjs sync-durations --audio-meta ./audio_meta.json --storyboard ./STORYBOARD.md- 음량: 최종 영상은 약 -14 LUFS, true peak ≤ -1 dBFS여야 합니다. 내레이션이 너무 작으면 동일한 게인을 균일하게 적용하고 리미터를 추가하며, 각 문장 간의 상대적 음량은 유지합니다.
5. 카메라 디자인(Step 4)
shots.json(templates/shots.example.json참조)에서 각 프레임에 대해 "몇 번째 절 → 화면에 무엇이 나타나는지"를 작성하고,python scripts/apply_shots.py --project <p>를 실행하여 실제 초 단위로 변환한 후STORYBOARD.md에 다시 씁니다.blueprint필드는<id> (Adapt),<id> (Reproduce)또는compose만 가능하며, 설명은 별도로note에 넣습니다.- 먼저
hyperframes catalog --query를 사용하여 기존 컴포넌트를 찾고, 찾을 수 없으면 직접 그립니다. - 여러 프레임에 반복해서 나타나는 주인공(자동차, 사람, 기기)은 먼저 공유 SVG로 그립니다. 각 구성 요소의 좌표를 고정하고 모든 worker가 반드시 그대로 따라야 합니다. 그렇지 않으면 각 프레임의 주인공이 다르게 보입니다.
6. 각 프레임 병렬 제작
node <faceless-explainer>/scripts/frame-packets.mjs --project <p> --storyboard <p>/STORYBOARD.mdtemplates/dispatch_context.md를.hyperframes/frame-packets/_dispatch_context.md에 복사하고 프로젝트 값(비디오 방향, 공유 자산, 타이밍 규칙, 글꼴)을 채웁니다.- 각 프레임을 sub-agent에 할당하고 모두 병렬로 실행합니다. prompt는 순서대로 읽습니다:
_role.md→_dispatch_context.md→ 해당 프레임 packet →frame.md→ 공유 자산. - 인접 프레임이 동일한 화면을 이어갈 때(예: 동일한 눈금자), 먼저 완료된 프레임이 보고한 정확한 기하학 정보를 아직 작업 중인 프레임에 즉시 전달합니다.
- 모두 완료된 후:
python scripts/unify_frames.py --project <p>, 글꼴 및 헤어라인 위치 통일.
7. 조립, 자막, 색상 구성
node <fe>/scripts/assemble-index.mjs --storyboard ./STORYBOARD.md --hyperframes .
node <fe>/scripts/captions.mjs build --storyboard ./STORYBOARD.md --audio-meta ./audio_meta.json --hyperframes . --out ./caption_groups.json
python scripts/patch_captions.py --project . # 중문 자막 글꼴 및 굵기(기본 Bold 700)
python scripts/theme.py --project . # theme.json의 세 가지 색상 및 글꼴 적용(index, 각 프레임, 자막)
node <fe>/scripts/transitions.mjs inject --storyboard ./STORYBOARD.md --hyperframes .
node <fe>/scripts/transitions.mjs verify --storyboard ./STORYBOARD.md --index ./index.html
hyperframes lint && hyperframes check
(<fe> = 설치된 faceless-explainer skill 폴더.) 자막을 재구축할 때마다 patch_captions.py를 다시 실행한 다음 theme.py를 다시 실행해야 합니다. theme.json의 accents는 각 프레임에서 어떤 요소가 강조색(block/fill/text)을 사용할지 지정합니다. font는 각 프레임과 자막의 모든 텍스트를 동일한 글꼴과 굵기로 변경하여 worker가 원래 설정한 글꼴 설정을 덮어씁니다. 글꼴 변경 후 텍스트가 더 넓어지므로 hyperframes check를 다시 실행하여 오버플로나 겹침이 있는지 확인합니다.
마지막 단계에서 글꼴을 경량화합니다: python scripts/subset_fonts.py --project .. 영상에 사용된 한자만 남기고(CJK 글꼴이 12–17 MB에서 수백 KB로 감소), 각 프레임의 @font-face를 경량화된 파일을 가리키도록 변경합니다. 텍스트, 자막 또는 색상을 변경하는 작업 후에는 항상 다시 실행해야 합니다: theme.py는 매번 색상 적용 전 원본 파일에서 다시 색상을 적용합니다. 원본 파일은 전체 글꼴을 가리키므로, 새로 추가된 문자가 경량화 파일에 없으면 시스템 글꼴로 대체됩니다.
7.5 이미지 레이어(이 스킬에서 새로 추가됨)
전체 규칙은 references/images.md를 참조하십시오. 핵심 사항:
- 계획: 영상당 3–5장. 실제 사진은 증거 카드("실제로 누군가 만들었다"), Codex 생성 이미지는 오프닝 및 클로징의 분위기 배경으로 사용합니다. 애니메이션이 주체이며, 이미지가 선으로 설명하는 원리를 가리지 않아야 합니다.
- 사진 찾기:
python scripts/find_images.py search "<키워드>"→get "File:…" --name <짧은 이름> --project .. 공개 도메인, CC0, CC BY, CC BY-SA만 허용하며, 출처는 자동으로assets/images/web/CREDITS.md에 기록됩니다. 다운로드 후 직접 한 번 확인하고,行人(지나가는 사람), 다른 브랜드의 로고, 워터마크는 잘라냅니다. - 일러스트 생성: prompt를
gen_prompts.json(templates/gen_prompts.example.json참조)에 작성하고python scripts/codex_images.py --project .를 실행합니다. 로컬에 로그인된 Codex CLI가 필요하며, 내장 image_gen을 사용하고 API key는 필요하지 않습니다. 생성 후 직접 확인하여 텍스트나 로고가 나타나는지 검사합니다. Codex가 없으면 사용자에게 다른 이미지 생성 도구를 사용하고 PNG를assets/images/gen/에 넣도록 알릴 수 있습니다. - 색상 적용:
media.json에 각 이미지의 자르기, 크기 및 모드(사진은duotone, 생성 이미지는keep)를 작성하고python scripts/treat_images.py --project .를 실행합니다. - 배치: 각 프레임이 확정된 후 contact sheet를 보고 실제로 비어 있는 영역을 찾아
media.json의placements에frame,mode(card/background),box,at,label,credit를 작성합니다. 원래 선을 사진으로 교체하려면hide를 사용합니다. 그런 다음theme.py이후python scripts/place_media.py --project .를 실행합니다. - 화면 표시: 사진에는 "Photo: 저작자 · 라이선스 · 출처", 생성 이미지에는 "AI 생성 일러스트"라고 씁니다.
hyperframes check실행(사진 위의 텍스트 대비, 겹침), 마지막으로subset_fonts.py를 실행합니다. 이미지 설명과 출처에도 텍스트가 있기 때문입니다.
7.6 AI 비디오 레이어(이 스킬에서 새로 추가됨)
전체 규칙은 references/ai-video.md를 참조하십시오. 핵심 사항:
- 계획: 영상당 2–4개 구간. 오프닝 훅, 촬영할 수 없지만 내레이션과 맞는 동작(예: "한 번만 점프할 수 있다" → 자동차 착지), 클로징 감정에 사용합니다. 정확한 숫자나 힘의 방향이 필요한 화면은 여전히 선으로 그립니다.
- 첫 번째 프레임은 Codex 정적 이미지 사용: 먼저 섹션 7.5에 따라 주제 색상 구성에 맞는 이미지를 생성하고, H3는 이 이미지에서 움직이기 시작하여 영상과 클립의 스타일이 일관되도록 합니다.
- 스펙 작성:
assets/videos/gen/specs/<name>.json(예제는templates/video-specs/에 있음). 각 구간은 4–15초, 주체는 "브랜드 없음, 텍스트 없음", 동작은 명확한 이벤트 하나로 작성하고, 카메라 움직임과 사운드 설명을 추가합니다. - 생성:
python scripts/ai_video.py prompt --project .(공식 6단계 형식) →run(video_config.json의 runner 필요,templates/video_config.example.json참조). runner가 없으면 사용자에게prompt.txt와 첫 번째 프레임을 제공하고 ComfyUI의 공식 MiniMax H3 R2V 템플릿을 사용하여assets/videos/gen/<name>/clip.mp4로 저장하도록 안내합니다. - 검사:
python scripts/ai_video.py check --project .를 실행하고, 각check-1.png를 직접 확인합니다: 변형, 부품 추가, 텍스트나 로고, 동작 타이밍이 내레이션과 일치하는지 확인.不合格(부적격) 시 seed를 변경하여 다시 실행합니다. - 배치:
media.json의placements에서"video": "assets/videos/gen/<name>/clip.mp4"를 사용하고duration을 추가하며, 필요시out(영상 종료 전에 카드 페이드 아웃)을 추가합니다.theme.py후place_media.py를 실행한 다음hyperframes lint(video는 id가 있어야 하고 타이밍 요소 안에 배치 불가)와hyperframes check를 실행합니다. - 화면 표시 "AI 생성 영상(H3)"; 영상은 항상 음소거하며, 사운드는 내레이션만 사용합니다.
8. 심사(review-loop)
- 먼저
hyperframes check를 실행하고, draft 품질로 전체 영상을 출력합니다(hyperframes render --quality draft --workers <hw_check 권장 값>; 심사 단계에서는 항상 draft 사용). 각 절 종료 0.15초 전에 한 프레임을 캡처(최종 상태)하고review-loop/scripts/sheet.py --video … --at …를 사용하여 contact sheet를 만듭니다. 각 프레임을 직접 확인합니다. references/lessons.md의 체크리스트를 항목별로 비교하고, 수정 후 다시 출력하고 다시 확인하며, 한 라운드에서 문제가 없을 때까지 반복합니다.- 확인 후 최종 버전 출력:
hyperframes render --skill=faceless-explainer --quality high --output renders/video.mp4, 그런 다음 다시 음량을 측정합니다.
9. 납품
MP4 경로, 영상 길이, 전체 개요 contact sheet를 제공하고 다음을 나열합니다: 사용된 출처, 주장된 숫자, 추정된 숫자, 요구 사항과 다른 점(예: 영상 길이 초과), 수행되지 않은 작업(예: 배경 음악 없음).