Communitygithub.com

Rajesh-Royal/under-the-hood

주제나 코드를 손으로 그린 듯한 애니메이션, 로컬 TTS 내레이션, 배경 음악 및 효과음이 포함된 1080p MP4 기술 설명 영상으로 변환합니다.

under-the-hood란 무엇인가요?

이 스킬은 사용자가 요청한 기술 주제나 코드를 바탕으로, 손으로 그린 듯한 라인 아트 스타일의 애니메이션 설명 영상을 제작합니다. '구글에 타이핑하면 실제로 어떤 일이 일어나는가?', 'HTTPS는 어떻게 작동하나?', 'git push를 하면 어떻게 되나?' 같은 질문에 대한 답을 30~60초 분량의 1080p MP4 영상으로 만들어 줍니다. 영상은 크림색 배경에 잉크 라인 아트로 구성되며, 요청/응답/암호화 등을 색상으로 구분하고, 단계 추적기와 자막, 패킷 애니메이션, 카메라 팬 등의 시각적 요소를 포함합니다. 내레이션은 내장된 TTS 음성 또는 사용자 자신의 음성 클론을 사용할 수 있으며, 영상에 맞춰 배경 음악이 자동으로 조절됩니다. Claude Code, Cursor, Codex 등 다양한 AI 에이전트 플랫폼에서 사용할 수 있으며, 스크립트와 설정 파일을 수정하면 모든 요소가 자동으로 동기화되어 빠르게 렌더링됩니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Rajesh-Royal/under-the-hood/tree/HEAD/skills/under-the-hood

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Under the hood

주제(또는 사용자의 코드)를 내레이션이 있는 애니메이션 설명 영상으로 바꿉니다. 따뜻하고 손으로 그린 듯한 느낌입니다:

  • 크림색 도트 그리드 '종이' 배경에 잉크 라인 아트
  • 요청은 파란색, 응답은 주황색, 암호화 또는 성공은 초록색
  • 상단에 단계 추적기, 하단에 큰 자막
  • 상자 사이를 날아다니는 패킷, '세계' 사이를 이동하는 카메라

참조 결과물은 ${CLAUDE_SKILL_DIR}/assets/example-cookie/에 있으며, 구글에 'cookie'를 입력했을 때 어떤 일이 일어나는지 보여줍니다. 복잡한 패턴이 필요할 때마다 scenes.js를 열어 참고하세요.

모든 것은 코드로 구동됩니다. 캔버스 페이지는 결정론적으로 프레임을 렌더링하고, 내레이션 클립이 각 장면의 길이를 설정하며, 음악과 효과음은 같은 타임라인에서 합성됩니다. 스크립트를 변경하면 모든 것이 다시 동기화되며, 60초짜리 영상은 약 30초 만에 렌더링됩니다.

요청된 주제: $ARGUMENTS

파일 위치

  • 스크립트: ${CLAUDE_SKILL_DIR}/scripts/ (SCRIPTS라고 부름).
  • 런타임: UTH_HOME (기본값 ~/.local/share/under-the-hood)에는 노드 모듈, TTS 가상 환경 및 저장된 음성이 있습니다. doctor.sh는 PY(TTS Python)를 포함한 정확한 경로를 출력합니다.
  • 프로젝트: 현재 작업 디렉토리의 ./explainers/<slug>/에 생성됩니다. 사용자가 다른 위치를 지정하지 않은 경우입니다. 작업 디렉토리가 홈 폴더라면 ~를 어지럽히지 않도록 위치를 물어보세요.

프로젝트 폴더 구조는 다음과 같습니다:

index.html  engine.js  scenes.js  script.json  timeline.js
narration/  (음성 클립: <id>.wav, <id>_take2.wav, 미리보기 파일 포함)
audio/      (트랙 및 mix.wav)
.shots/     (실행당 하나의 새 폴더에 스크린샷 저장)
<slug>.mp4

워크플로우

0. 설정 확인 (준비되면 한 줄 실행)

bash ${CLAUDE_SKILL_DIR}/scripts/doctor.sh          # 영상에 내레이션이 없으면 --no-tts 추가

READY가 출력되면 PY와 VOICES를 기록하고 진행합니다. MISSING 줄이 출력되면 under-the-hood-setup 스킬을 불러와 따라 한 후 doctor를 다시 실행합니다.

1. 간단한 입력 받기

$ARGUMENTS가 비어 있으면 주제를 물어보세요. 그런 다음 합리적으로 결정할 수 없는 것만 한 메시지로 물어보고, 합리적인 기본값을 제시하세요:

  • 관점: 주제가 광범위할 때만 물어봅니다. "인터넷이 작동하는 방식"은 초점이 필요하지만, "git push를 하면 어떻게 되나"는 그렇지 않습니다.

  • 음성: 항상 이 옵션을 제공하세요. 사용자들은 자신의 음성을 사용할 수 있다는 사실을 모르기 때문입니다. 다음과 같이 제시하세요:

    1. 내장 음성 (기본값, 바로 작동)
    2. 저장된 음성 (VOICES에 하나가 있는 경우)
    3. 사용자 자신의 음성: 휴대폰으로 약 20~30초를 녹음하여 파일을 보내세요. 사용자의 음성은 기기에 남습니다.
    4. 내레이션 없음 (음악과 효과음만)

    사용자가 자신의 음성을 선택하면 ${CLAUDE_SKILL_DIR}/references/voice.md를 읽고 녹음 팁과 샘플 문단을 먼저 제공하세요. 사용자는 스토리보드를 작성하는 동안 녹음할 수 있습니다.

  • 길이: 기본 30~60초, 16:9.

이것을 설문조사로 만들지 마세요. 기껏해야 두세 가지 질문입니다.

2. 주제를 이해하고 사실을 정확히 파악

사용자가 코드를 제공했다면 코드를 읽고 실제 흐름을 추적하세요. 기술 시청자는 오류를 지적할 것입니다. 따라서:

  • 이벤트 순서를 정확히 파악하세요. 예: 이미 로드된 페이지에서는 DNS와 TLS 핸드셰이크가 이미 발생했으므로, 첫 접촉 시에 배치하거나 "첫 방문"이라고 표시하세요.
  • 현대 시스템이 실제로 하는 방식을 선호하세요. 예: Chrome은 교과서적인 TCP 3-way 핸드셰이크가 아닌 QUIC 및 TLS 1.3을 통해 Google과 통신합니다.
  • 단순화할 때는 부제목에 "단순화됨"이라고 표시하세요.
  • 예시 값(예시 IP, .example 도메인, 가상 점수)을 사용하고 정확한 밀리초 수와 같은 거짓 정밀도는 피하세요.
  • 실제 제품의 로고나 픽셀 단위 UI를 재현하지 마세요. 선화 대용품이 스타일에 더 잘 맞습니다.

3. 스토리보드와 스크립트 작성 후 빌드 전 승인 받기

약 3060초 동안 48개의 번호가 매겨진 단계를 계획하고, 먼저 title 장면을, 마지막에 end 장면을 추가하세요. 각 장면에 대해 다음을 작성합니다:

  • 내레이션 (script.json): {"id", "text", "gap"}. gap은 문장 뒤의 일시 중지로, 0.25~0.45초입니다.
  • 자막 (cap): 8단어 이하, 음소거되었을 때 읽을 수 있어야 합니다. 부제목 (sub): 짧은 한 줄.
  • 시각적 비트: 무엇이 나타나고 움직이는지, 각 사운드가 무엇인지.

내레이션을 작성하기 전에 ${CLAUDE_SKILL_DIR}/references/narration.md를 읽으세요. 기사 스타일의 내레이션은 AI가 기사를 읽는 것처럼 들립니다. 사람이 친구에게 설명하는 방식으로 작성하세요.

스크립트와 스토리보드를 간단한 표로 사용자에게 보여주고 승인을 기다리세요. 지금 단어를 바꾸는 것은 자유롭습니다. 음성 생성 후에는 다시 실행해야 합니다.

내레이션이나 화면 텍스트에 em 대시나 세미콜론을 사용하지 마세요. TTS가 이상하게 읽고, 짧은 문장이 더 자연스럽습니다.

4. 프로젝트 생성

bash SCRIPTS/new_project.sh ./explainers/<slug> "<페이지 제목>"

이 명령은 engine.js, 시작용 scenes.js (작동하는 작은 "보내기" 예제) 및 script.json을 복사합니다. 비어 있지 않은 폴더는 덮어쓰지 않습니다. 시작 콘텐츠를 실제 스토리보드로 바꾸세요.

5. scenes.js 작성

먼저 ${CLAUDE_SKILL_DIR}/references/engine-api.md를 읽으세요. 시간 모델, 모든 헬퍼 함수, 레이아웃 영역, 사운드 이름 및 부트 구성을 다룹니다. 핵심 아이디어:

  • 디자인 시간을 가진 defineScenes([...])를 사용하세요. prog(t, S.id + a, S.id + b)로 디자인 시간에 애니메이션을 적용하세요. 엔진은 각 장면을 음성 클립에 맞게 늘리므로 클립 길이에 맞춰 수동 조정하지 마세요.
  • 세계를 y 150~800 안에 유지하세요. 추적기는 그 위에, 자막은 아래에 있습니다.
  • 지속되어야 하는 것(브라우저, 서버)은 한 장면에 나타나고 그 후에도 계속 그려집니다.
  • 두 번째 "장소"(예: 데이터 센터 내부)는 x + 1920에 그리고 camera(t)로 팬하세요. 팬 중에 화면이 비어 있지 않도록 팬 중에 내용을 드러내기 시작하세요.
  • 모든 눈에 보이는 이벤트에는 sfx(add)로 사운드를 추가하세요. 키 입력은 key, 날아가는 패킷은 whoosh*, 도착은 thunk 또는 pop, 성공은 chime 또는 success. 이것이 영상이 완성된 느낌을 주는 큰 요소입니다.

6. 음성 없이 미리보기, 프레임 확인

node SCRIPTS/shots.js <project>            # 각 장면의 중간, 새로운 .shots/<time>/ 폴더에 저장

모든 스크린샷을 확인하세요. 읽기 전에 크기를 줄이세요 (macOS에서는 sips -Z 960, 그 외에서는 ffmpeg -i in.png -vf scale=960:-1 out.png). 다음을 확인하세요:

  • 겹치거나 가장자리를 벗어나는 텍스트
  • 팬 중 빈 프레임
  • 뒤에 있어야 할 것 위에 그려진 요소

수정하고 다시 촬영하세요. 페이지가 부팅되지 않으면 스크립트가 페이지 오류를 출력합니다.

7. 음성

내장 음성 (--voice 없음):

$PY SCRIPTS/narrate.py --script <project>/script.json --out <project>/narration --takes 2

저장된 음성: --voice <UTH_HOME>/voices/<name>.wav를 추가하세요.

녹음에서 새 음성: ${CLAUDE_SKILL_DIR}/references/voice.md를 따르세요. prep_voice.sh, 빠른 테스트 라인 및 동의에 대해 다룹니다. 사용자 자신의 음성, 또는 사용자가 사용 동의를 확인한 음성만 복제하세요.

그런 다음 사용자에게 듣게 하세요: <project>/narration/narration-preview_take1.wav (macOS에서는 open, Linux에서는 xdg-open 사용).

  • 첫 번째 실행은 약 1GB의 모델 가중치를 다운로드합니다. 그 후 Apple Silicon 또는 GPU에서는 실시간에 가깝게, CPU에서는 더 느리게 실행됩니다.
  • 오디오를 들을 수 없습니다. 사용자에게 이 사실을 알리고, 직접 들어보고 테이크를 판단하도록 요청하세요. 라인별로 테이크를 혼합할 수 있습니다. --only <id>로 단일 라인을 다시 실행하세요.
  • Turbo는 [chuckle], [laugh], [sigh], [gasp], [surprised] 태그를 지원합니다. 영상당 최대 한두 개만 사용하세요.

내레이션 없음: 이 단계와 build_timeline.py를 건너뛰세요. 장면은 디자인 시간을 유지하고, 영상은 음악과 효과음만 있습니다.

8. 타임라인, 렌더링, 확인

python3 SCRIPTS/build_timeline.py <project> [--pick dns=2,enter=2]
node SCRIPTS/render.js <project> [--music-db -12] [--sfx-db 1] [--silent] [--audio-only]

render.js는 음성, 음악 및 효과음 트랙을 빌드하고 혼합하여 음악을 음성 아래로 덕킹하고 -16 LUFS로 정규화합니다. <slug>.partial.mp4로 렌더링하고 ffprobe가 전체 길이를 확인한 후에만 <slug>.mp4로 이름을 바꿉니다.

사용자에게 완료를 알리기 전에 실제 파일을 확인하세요:

  • ffprobe에 예상 지속 시간과 비디오 및 오디오 스트림이 표시되는지 확인
  • ffmpeg -ss <나중 시간> -frames:v 1이 올바른 장면을 보여주는지 확인
  • 음량이 약 -16 LUFS인지 확인

그런 다음 MP4와 index.html 미리보기를 엽니다. 미리보기는 챕터와 스크러빙과 함께 믹스를 동기화하여 재생합니다.

무엇을 확인했는지, 무엇을 확인할 수 없었는지(오디오 소리), 그리고 어떤 부분이 단순화되었는지 간단히 보고하세요.

작업 규칙

  • 와일드카드 삭제 금지. rm을 와일드카드와 함께 사용하거나 프로젝트 폴더에 rm -rf를 실행하지 마세요. 새 출력물은 새 폴더에 넣고 파일은 이름으로 덮어씁니다.
  • 중단된 명령이 부분적으로 실행되었을 수 있습니다. 사용자가 여러 단계 명령을 중단하면 계속하기 전에 디스크에서 변경된 사항을 확인하고 부분적인 영향에 대해 알려주세요. 절반만 교체된 클립 세트는 완성된 것처럼 보이는 짧은 부분 영상을 남길 수 있습니다.
  • 선호 힌트에 자동 전환하지 마세요. 사용자가 아직 결정 중인데 "테이크 2가 마음에 들어요"라고 말하면 다시 렌더링하기 전에 확인하세요.
  • 제안만 하고 빌드하지 마세요: 9:16 세로 버전, 30초로 자르기, 또는 더 다듬기 등을 한 줄씩 언급하세요.

문제 해결

  • PerthImplicitWatermarker에서 'NoneType' object is not callable 오류: uv pip install --python $PY "setuptools<81" 실행. Chatterbox의 워터마크 라이브러리에 pkg_resources가 필요합니다.
  • 첫 번째 TTS 실행이 느린 경우: 워밍업 및 모델 다운로드 때문입니다. 이후 실행은 더 빠릅니다.
  • 음악이 너무 크거나 작은 경우: --music-db (기본값 -12). 효과: --sfx-db (기본값 1). --audio-only를 사용하여 믹스를 빠르게 반복하세요.
  • Chrome을 찾을 수 없는 경우: CHROME_PATH를 설정하거나 under-the-hood-setup 스킬을 불러오세요.
  • Chrome의 오프라인 오디오는 실행마다 비트가 동일하지 않으므로 트랙이 렌더링 간에 약간 다릅니다. 타이밍은 정확하고 프레임은 픽셀 단위로 동일합니다.

관련 스킬