Talking Explainer (말하는 설명 영상)
목소리가 시간의 기준입니다. 발표자가 말합니다(립싱크). 모든 아이디어는 먼저 일상적인 그림으로 제시되며, 모든 장면에는 줌과 강조 순간이 있습니다. 디자인은 Apple 스타일이며, 영상에는 사용자의 브랜드가 포함됩니다. 작업 예시: "REA - Reverse Engineer Anything" (129.0초, 12개 장면) - references/example/ (SCRIPT, STORYBOARD, RETIME).
아래에서 사용되는 경로:
<skill>= 이 스킬의 폴더.<kit>=<skill>/../explainer-kit.<engine>=<skill>/../spatial-film.<home>=TALKING_EXPLAINER_HOME또는~/.talking-explainer; 프로필 =<home>/profile/(explainer-kit과 공유).<py>=<home>/config.json에 setup-check가 저장한python명령어 (Windows는py -3.12, macOS는python3).
모든 영화 스크립트는 영화 프로젝트 루트 디렉토리에서 실행하세요. 스크립트는 검증된 코드이므로 실행만 하고 절대 재생성하지 마세요. 장면은 콘택트 시트(contact sheets)로 평가하고, 메인 세션에서 장면 HTML을 읽어서 평가하지 마세요. 작업자는 파일 경로를 전달받습니다.
설정 (최초 실행 시)
<home>/profile/brand.json이 없으면 = explainer-kit의 Phase S를 실행하세요 (setup-check, brand 인터뷰 + profile.mjs init, voice.md, music). 브랜드 인터뷰에서 발표자 이름(--presenter)을 설정합니다. 이 스킬을 위해 같은 인터뷰에서 추가로 두 가지를 더 질문합니다:
- 오프너와 클로저 대사:
voice.md에 정확한 단어 그대로, 사용자의 이름과 함께 (훅 오프너는 "<주장>? 사실인가요? <이름>입니다, <브랜드>에서... 자세히 알아보죠.") - 발표자: 번들로 제공되는 말하기 데모(무표정한 만화 캐릭터, 안경 착용) 또는 사용자만의 캐릭터 - 아래 "사용자만의 말하는 캐릭터" 참고.
기본값 (다시 묻지 않음)
- 내레이션: 프로필 언어,
voice.md의 사용자 스타일. 화면 텍스트: 짧은 기본 영어 (헤드라인 줄당 ~6단어). 메시지가 전달되면 길이는 자유 (~150-160 wpm, 자연스러운 녹음 기준). - 사용자가 직접 녹음: 스크립트를 보고 녹음 (ElevenLabs 음성 클론 또는 직접 마이크). Phase 1은 스크립트를 붙여넣기 가능한 문단으로 제공하고 MP3 파일을 기다립니다. API를 통한 생성(
<engine>/scripts/el-tts.py, 키는 envEL에 저장, 절대 디스크에 저장하지 않음)은 사용자가 요청할 때만 사용합니다. - 오프너 = 훅 우선: 주제에 대한 가장 놀라운 주장을 질문으로 열고, 이어서
voice.md의 오프너 대사. 주제의 이름은 2번째 문단에 등장. 클로저 =voice.md의 클로저 대사 + 프로필의cta. - 개념 주제: 하나의 일상적인 비유를 문자 그대로 설명 (REA 예시: 카페의 비밀 라떼 레시피). 사용자 자신의 도구나 시스템에 대한 "작동 방식" 주제: 실제 제품 워크스루로 대체 -
references/real-apps.md참고. 타사 도구 및 플랫폼도 동일: 실제 제품 이름을 명시하고, 실제 요청 흐름을 설명하며, 플랫폼의 자체 카피, 설정 및 라이브 페이지에서 읽은 숫자를 사용. 기술 주제는 기본적으로 워크스루 방식을 사용. - 짧은 영상 (<= 30초): ~2.6단어/초, 4개 문단 = 4개 프레임 (훅 + 신원 / 이름 / 하나의 그림 / 클로즈), 한 줄 클로저, 2명의 작업자 x 2개 장면.
- 이슈 / 뉴스 주제: 먼저 라이브 보도 조사 (지역 매체 + 심층 기사 하나), 균형 있게 작성: 모든 주장은 출처를 명시 ("해당 기관에 따르면...", "비판론자들은..."), 두려움은 실제 규모를 제시한 후, 공식 성명이 서로 모순되거나 핵심 세부사항이 공개되지 않은 부분을 번호가 매겨진 회색 영역으로 제시, 공정한 긍정적 측면 문단, 그리고 결론 대신 질문할 점들을 제시 - 절대 판단을 내리지 마세요. 검색 요약만으로 얻은 정보(실제 페이지 로드 실패)는 SCRIPT.md의 사실 블록에 "미검증, 내레이션에 포함되지 않음"이라고 표시. 이러한 경우 16프레임 / ~700단어도 가능.
- 붙여넣은 대본에서 스크립트 작성: 원본의 사실과 아이디어 순서는 유지하고, 모든 줄을 내레이터의 목소리로 다시 작성 (절대 직역하지 않음). 원본 발표자의 부분("제가 만들었습니다...", 코드 데모, 이름 등)은 제거. 긴 텍스트는 약 50,000자에서 잘림: SCRIPT.md에 잘린 위치를 명시하고, 표준 메커니즘을 사용하여 누락된 부분을 다른 주장과 동일하게 검증하여 채움. 첫날에 붙여넣은 텍스트를
references/source-transcript.txt에 저장하고, 원본의 명시된 인물과 주요 이정표를 유지. - 실제 인물 = 인물 카드, 이름 태그 사용 금지: 초상화 (이중톤 사진 또는 그림체 초상화) + 이름 + 한 줄 역할 + 연도. SCRIPT.md에 등장하는 모든 명명된 인물과 해당 장면을 "화면 속 인물" 아래에 나열.
- 비주얼 = Apple: 흰색 배경 (
#F5F5F7그라운드), 크기별 트래킹이 있는 Geist 폰트, 가짜 유리 효과 (.ap-glass- 3D 리그 내에서backdrop-filter금지),.ap-window/.ap-dark패널, 임계 감쇠sp()스프링 (back.*금지), 절제 (프레임당 하나의 아이디어, 펄스 <= 1.1), 블루 LENS 스파인. 색상 = 의미, 영화마다 재정의. 스캐폴드가 모든 것을 설정. - 아이콘 = Solar (480 Design, https://solar-icons.vercel.app) - 히어로 아이콘은 bold-duotone, UI 크롬은 linear,
references/icons-solar.html에서 참조. Lucide 또는 Phosphor 사용 금지. 아트워크는 CC BY 4.0: 모든 전달 시 사용자에게 비디오 설명에 "Icons: Solar by 480 Design (CC BY 4.0)" 문구를 포함하도록 안내. - 모션: 단어가 나타나는 헤드라인 (상승 + 블러 -> 0, 스프링), 도구에 대한 UI 애니메이션, 설명 다이어그램, PLUS 모든 장면에 카메라 푸시인 (ZOOM) 및 강조 비트 (EMPH: 펄스, 마커 스윕, 밑줄 그리기, 포커스 풀, 숫자 펀치인). 60fps 부드러움의 법칙.
- 1920x1080, 60fps. 훅에 브랜드 로고, 중간에 코너 로고, 엔드 카드 = 로고 +
cta.
단계
| # | 단계 | 수행 작업 | 게이트 (조건) |
|---|---|---|---|
| 1 | 대본 + 녹음 | 주제 조사 (실제 사실, 출처 포함). <kit>/references/voice-script.md + <home>/profile/voice.md 로드. 위의 훅 우선 오프너 + 클로저, "!" 사용 금지, 하나의 비유 (또는 워크스루), 12개 문단 = 12개 프레임 (형태: references/example/SCRIPT.md). 문자로 발음되는 이름은 철자 표기 ("R-E-A"). AI가 "할 수 없는" 일에 대한 주장은 오늘날 모델에 대해 사실이어야 함. 전문 용어 숫자 금지 (페이지, 토큰 아님; 반올림된 수치). <film>/SCRIPT.md 작성, 사용자에게 문단을 일반 텍스트로 전달 (코드 블록 없음, 마지막 문단 이후 아무것도 없음 - 사용자가 전체 메시지를 ElevenLabs에 붙여넣음; 녹음 팁은 이전 메시지로 전송), MP3 대기; ffprobe로 길이 확인 | 녹음 파일 확보, 길이 확인 완료 |
| 2 | 스캐폴드 + 타이밍 | node <skill>/scripts/new-talking-explainer.mjs <film> --name <slug> --mp3 <take.mp3>; <py> <kit>/scripts/transcribe.py assets/audio/vo.mp3 src/timing --lang <code> --prompt "<이름들, 전문 용어>"; <py> <kit>/scripts/words.py src/timing/vo-words.json (큐 시트) | 전사본이 대본과 일치 |
| 3 | 스토리보드 | STORYBOARD.src.md를 전역 시간(아래 참고)으로 references/example/STORYBOARD.md 형식에 맞춰 작성: 문단당 한 프레임, 문장 쉼표에서 컷 (합계 = 음성 끝 + 2.8초), 헤더는 한 줄에 한 필드 (- start: / - duration: / - src:), 모든 블록은 큐 워드에 ZOOM 및 EMPH 비트 표시, 색상 = 의미, 실제 사실 + 가상의 추가 요소, 두 장면이 히어로 오브젝트를 공유하는 경우 STAGE POSE 이음새 표시. <py> src/storyboard-local.py -> STORYBOARD.md. 사용자에게 프레임 목록(각 한 줄) 표시 | 사용자의 "진행" 승인 |
| 4 | 계약 + 발표자 + 오디오 | src/set-film.py 편집 및 실행 (장면 + 음성 길이). src/set-presenter.py 편집 및 실행 (포즈는 큐 워드 약 0.1초 전에; 생각/걷기는 입 움직임 없음 - 음성이 말하는 동안 절대 입 움직임 없음). 배경 음악: <py> <engine>/scripts/bgm-cut.py assets/audio/bed.mp3 assets/audio/bgm-edit.wav --len <total> --a 0 <total+3> --fade-out 2.6 (영상이 배경 음악보다 길면 본문 반복: --a 0 <len> --b <bar> <len> --b ... --xfade 0.3) -> <py> <kit>/scripts/master-audio.py --len <total> -> <py> <engine>/scripts/build-presenter.py (출력: "lip sync: N poses") -> <py> <kit>/scripts/build-brand.py (출력: 코너 로고 윈도우). frame.md의 모든 [FILM] 부분을 하나의 <engine>/scripts/patch_exact.py 스크립트로 재작성. src/set-cues.py 편집 및 실행. <py> <engine>/scripts/make-harness.py; <py> <skill>/scripts/make-packets.py; node <engine>/scripts/test-scene.mjs m-presenter "<5회>" | 발표자 시트: 음성에 입 열림, 큐에 포즈 |
| 5 | 장면 | references/workers.md: 6명의 Sonnet 작업자 x 2개 장면, 최대 4명 동시 실행 (수정 라운드는 개수 계산), 프롬프트 템플릿 (영역 법칙 포함: 푸시 피크, 0.12 클램프, Solar 전용, Apple 바, 숫자 절대 생성 금지). 중간 결과물 직접 검토; 동일한 작업자에게 수정 라운드 전송 | 모든 시트가 해당 블록과 일치하며, 시트 축소판에서 읽을 수 있음 |
| 6 | 출시 | <py> <engine>/scripts/fromto-scan.py compositions/s*.html (0) -> <py> <engine>/scripts/assemble.py -> npx hyperframes@<film.json hyperframes> lint . + check . -> <py> <engine>/scripts/seam-check.py + node <kit>/scripts/seam-diff-all.mjs -> node <engine>/scripts/render-final.mjs <slug>-1080p60 (백그라운드; 플래시 스캔으로 종료) -> 렌더를 .hyperframes/work/sync에 전사 + <py> <kit>/scripts/sync-check.py src/timing/vo-words.json .hyperframes/work/sync/vo-words.json -> <py> <skill>/scripts/frames.py renders/<slug>-1080p60.mp4 frames.jpg --at <장면당 하나> 및 --zone --at <모든 ZOOM 피크> -> node <engine>/scripts/encode-web.mjs renders/<slug>-1080p60.mp4 renders/web --name <slug> --poster <t> -> 경로 + Solar 크레딧 문구 전달 | lint/check 0 에러, 이음새 발표자 박스 외부 0.00%, 플래시 0개, 싱크 중앙값 ~0.000초, 모든 피크에서 적색선 잔여 없음 |
시간을 한 번만, 전역 초 단위로 작성
20개 장면의 단어 시간을 수동으로 장면 로컬 시간으로 변환하면 오류가 발생합니다. STORYBOARD.src.md에서 각 프레임에 - start: <global>을 제공하고 큐 워드를 "word"@g<global>로 표시하세요. ZOOM 범위 및 "종료 시간"은 일반 전역 숫자로 표시해도 됩니다. <py> src/storyboard-local.py는 STORYBOARD.md를 작성하면서 모든 시간을 로컬로 변환하고, 시작 시간 체인과 각 큐가 해당 장면에 속하는지 확인하며, set-film.py를 위한 장면 목록을 출력합니다. SFX (src/set-cues.py) 및 발표자 (src/set-presenter.py)도 전역 초 단위로 작성합니다.
빌드 후 음성/언어/오프너 교체 (재구축 없음, 리타이밍)
새 음성 -> compositions/, film.json, STORYBOARD.md, src/를 .hyperframes/work/<old>/에 백업, 이전 렌더를 renders/<old>/로 이동 -> 새 음성을 assets/audio/vo.mp3에 복사 -> 전사 -> set-film.py에서 새 컷 적용 -> 발표자 포즈, 배경 음악, 마스터 오디오, build-presenter, build-brand, set-cues, make-harness -> RETIME.md 작성 (장면별: 각 비트 -> 새로운 큐 워드 @ 로컬 시간; 새로운 내용이 있는 장면은 전체 블록 작성; 형식 references/example/RETIME.md; "이 파일이 STORYBOARD.md 시간보다 우선함") -> frame.md 지속 시간 / 로고 윈도우 / 이음새 패치 -> 각 동일한 작업자에게 RETIME 섹션 전송 (한 번에 4명). 더 빠른 음성의 경우 장면이 짧아짐: 작업자에게 비트를 떨어뜨리기 전에 스프링을 단축하도록 지시.
세로 / TikTok / Reels / Shorts 컷 (재구축 없음, 포팅)
<py> <skill>/scripts/port-portrait.py <film> <film>-9x16- 새로운 폴더 (16:9 영화는 그대로 유지): 소스 + 오디오 복사, 출시된 장면을references/src-16x9/로 이동 (작업자 사양), 세로 계약 작성 (frame.md의 TikTok UI 영역, 작업자 브리프, 1080x1920 스타터, set-film 크기), 발표자를 왼쪽 아래로 이동 (스케일 x0.9, y 1640).- 새 루트에서:
<py> src/set-film.py->build-presenter.py->build-brand.py(세로 로고 = y 150의 상단 중앙, 플랫폼 탭 아래) ->make-harness.py->test-scene.mjs m-presenter(발표자 x ~26-556, y ~1074-1640). - 작업자: 동일한 쌍, 프롬프트 = "PORT" (16:9 소스에서 시작, 카피/비트/큐/색상/아이콘/이음새 포즈 유지, 레이아웃 + 카메라만 재구성) + 세로 영역 법칙: 헤드라인 y 260-500, 스테이지 x 60-1020 / y 520-1060 (텍스트 x <= 920, y 680 이하), 오른쪽 아래 x 580-920 / y 1080-1520, 발표자 x 20-560 / y 1060-1660, y 250 위 또는 y 1540 아래에는 아무것도 배치 금지. 다른 쌍의 오브젝트를 복사하는 쌍은 마지막에 실행.
- Phase 6과 동일하게 출시,
render-final.mjs <slug>-1080x1920p60사용;frames.py --zone은 세로를 감지하여 발표자 박스 + 플랫폼 UI 라인을 그림. 1080p60 마스터는 그대로 TikTok에 업로드. 첫 번째 패스 문제점: 히어로 오브젝트가 오른쪽 아래로 밀려남 (비트를 스테이지의 히어로로 만들고, 디스플레이 텍스트 크기를 줄임); 푸시 중 상승하는 스택과 충돌하는 2줄 헤드라인 (피크에서 최소 40px 간격 유지); 푸시에 의해 y 1540 아래로 끌려간 보조 카드 (해당 푸시 동안 후퇴/어둡게 처리).
실제 앱 + 실제 로고
사용자 자신의 설정에 관한 영화는 실제 앱을 보여줌: 소스의 로고, 앱 자체 CSS의 앱 색상 (scripts/app-tokens.py), 사용자의 실제 폴더 이름 및 숫자, 모든 작업자 시작 전 개인정보 목록. 레시피: references/real-apps.md. frame.md는 "타사..." 없이 설정.