Communitygithub.com

nestedbit/faceless-shorts

마스코트 설명 영상 / YouTube Shorts / TikTok을 코드로만 제작합니다. 사용자 사진 한 장으로 만든 플랫 만화 마스코트(리깅, 립싱크)가 번호가 매겨진 단계별 카드를 제시하며, 번호 타일이 모서리 배지로 슬램, 라이브 체크리스트, 단어별 헤드라인 캡션과 모든 히트에 사운드가 들어갑니다. 로컬 AI 음성 및 단어 타이밍을 무료로 제공하며, Claude 요금 외 추가 비용이 없습니다. 누군가가 마스코트/만화 나/아바타 설명 영상을 원할 때 사용하세요.

faceless-shorts란 무엇인가요?

이 스킬은 사용자가 하나의 주제로 완성된 세로형 숏 영상(스크립트, 음성, 단어 동기화 캡션, 애니메이션 샷, 사운드, 음악)을 MP4로 렌더링하게 해줍니다. 모든 작업은 코드로만 이루어집니다. 캔버스 드로잉, 헤드리스 Chrome 캡처, ffmpeg, 로컬 Kokoro 음성 엔진, 로컬 Whisper 단어 타이밍, numpy 사운드 처리를 사용하며, AI 이미지나 비디오, API 키, 추가 크레딧이 전혀 필요 없습니다. 주 스타일은 'Mascot Explainer'로, 사용자 사진 한 장으로 만든 플랫 만화 마스코트가 리깅되고 립싱크되어 'N개의 빠른 단계'를 제시합니다. 각 샷은 카드, 번호 타일, 체크리스트, 단어별 캡션, 카메라 흔들림, 히트 사운드로 구성됩니다. Chrome, Node 22+, ffmpeg, Python 가상 환경(Whisper, Kokoro)을 로컬에 설치하면 바로 사용 가능하며, 스크립트 작성, 음성 생성, 마스코트 디자인, 샷 코딩, 캡처, 믹싱, QA의 전체 워크플로우를 자동화합니다. 사용자가 요청할 경우 Zapier를 통해 YouTube 업로드도 지원합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nestedbit/faceless-shorts/tree/HEAD

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

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

문서

Faceless Shorts

주제 하나로 완성된 세로형 숏 영상(스크립트, 음성, 단어 동기화 캡션, 애니메이션 샷, 사운드, 음악)을 MP4로 렌더링합니다. 모든 것이 코드입니다: 캔버스 드로잉, 헤드리스 Chrome 캡처, ffmpeg, 로컬 Kokoro 음성, 로컬 Whisper 단어 타이밍, numpy 사운드. AI 이미지나 비디오, API 키, 추가 크레딧이 필요 없습니다. SKILL = 이 파일이 있는 폴더입니다. 프로젝트는 ~/faceless-shorts/<short-name>/에 저장됩니다.

한 가지 스타일: Mascot Explainer(mascot-explainer). 여러분이 플랫 만화 마스코트(사진 한 장으로 코드로 그리고, 리깅하고, 립싱크하여) "N개의 빠른 단계"를 제시합니다. 한 번에 하나의 카드, 모서리 배지로 슬램되는 번호 타일, 라이브 체크리스트, 단어별 헤드라인 캡션, 모든 히트에 카메라 흔들림 + 사운드. 30~45초 · 9:16. 사용 방법, 팁, "N단계로…", 기술/금융/생산성 설명 영상에 가장 적합하며, 크리에이터 자신이 브랜드입니다.

스타일 = styles/mascot-explainer/style-sheet.png(자체 코드로 그린 하나의 이미지로 표현된 룩) + STYLE.md(규칙 + 엔진 매뉴얼) + example/(즉시 렌더링되는 완전한 프로젝트)입니다. 계획을 세우기 전에 STYLE.md를 전체 읽으십시오.

0. 컴퓨터에서 처음 사용

bash SKILL/scripts/setup.sh가 All set을 출력할 때까지 실행합니다(Node 22+, ffmpeg, Chrome 확인; ~/.faceless-shorts/venv 구축; Kokoro 음성 ~340MB 및 Whisper small.en ~0.5GB 다운로드). 누락된 항목을 무료 공식 방법으로 설치하고, 비밀번호가 필요한 경우 먼저 물어보십시오. 그런 다음 bash SKILL/scripts/selftest.sh가 SELFTEST PASSED를 출력해야 합니다: 연락처 시트를 열고 이름을 확인합니다.

1. 입력 (한 번에, 기본값이 채워짐)

알려지지 않은 것만 한 번에 물어보십시오: 주제(또는 "당신이 3가지 아이디어 고르기"), 마음에 드는 숏 영상 링크(선택 사항), 길이(기본 ~30초), 음성(SKILL/scripts/py SKILL/scripts/voice.py --list; 기본 am_michael), 내레이션 모드: AI 음성(기본) · 자신의 녹음(스크립트를 본 후 녹음; words.py --audio) · 캡션만(아직 음성 없음; estimate.py), 음악(내장 배경음 · 없음 · 자신의 로열티 프리 파일), 종료 문구/핸들, 그리고 선명한 정면 사진 한 장(선택 사항)과 복장, 또는 ~/faceless-shorts/_mascots/에 저장된 마스코트 이름. "그냥 진행" = 기본값.

2. 계획 (한 화면에, 그다음 대기)

표시: 제목 · 컷별 전체 내레이션(캡션 청크 포함, 예: 1. 실제 | *보낸 사람 주소 확인) · 샷 목록(각각 한 줄: 보이는 것, 움직이는 것, 해당하는 단어) · 키트에 새로 추가할 구성 요소(있는 경우) · 사실 및 출처. **"만들까요?"**라고 묻고 기다리십시오.

스크립트 규칙. 사람이 실제로 친구에게 말하는 방식으로 작성하십시오: 연결 단어("글쎄요,", "여기서", "하지만", "그래서", "즉")가 포함된 완전하고 흐르는 문장, 짧은 캡션 같은 진술 목록이 아닙니다. 35초 기준 약 90110단어. 한 줄은 컷(CUT)이며, 문장이 아닙니다: 각 문장을 자연스러운 휴지(쉼표, "그리고", "여기서")에서 13줄로 나누어, 음성은 계속 흐르는 동안(voice.py는 각 문장을 한 번에 말함) 1.53.5초마다 그림이 바뀌도록 합니다. 형태: 실제 출처가 있는 숫자가 포함된 훅, 한 줄 약속, "첫째,…"로 시작하는 36단계, 명확한 종료 동작 하나. 숫자는 말하는 대로("seven") 작성하십시오. 머릿속으로 소리 내어 읽으십시오: 캡션처럼 들리면 다시 작성하십시오. 독창적인 작성만: 마음에 드는 형식을 취하되, 다른 크리에이터의 스크립트나 샷을 사용하지 마십시오. 모든 사실은 신뢰할 수 있는 출처(script.json "sources"에 나열)와 대조합니다.

3. 제작

  1. bash SKILL/scripts/new_video.sh mascot-explainer <short-name>는 예제를 ~/faceless-shorts/<short-name>/에 복사합니다.
  2. script.json을 작성합니다(줄 + 캡션 + 간격; STYLE.md 참조). 먼저 마스코트를 만듭니다(mascot.json, STYLE.md §2), 포즈 시트를 렌더링하고 샷을 작성하기 전에 사용자의 승인을 받습니다.
  3. 타이밍: SKILL/scripts/py SKILL/scripts/voice.py <proj> 그런 다음 SKILL/scripts/py SKILL/scripts/words.py <proj>(자신의 녹음: words.py <proj> --audio their.m4a; 캡션만: estimate.py <proj>).
  4. src/shots.js를 다시 작성합니다: 한 줄에 하나의 샷(또는 긴 줄의 경우 두 개), 각각은 cut(i)로 배치하고 키 모멘트는 Wd('word', line)로 단어에 배치합니다. 키트(src/core/kit.js)를 재사용하고, 새 구성 요소는 스타일 룩에 따라 그곳에 추가합니다.
  5. 프로젝트에서: node tools/capture.mjs check(CHECK OK가 나와야 함) → node tools/capture.mjs cues → SKILL/scripts/py tools/mix.py . → QA(섹션 4) → node tools/capture.mjs video renders/<name>.mp4. 하나의 샷을 반복할 때: node tools/capture.mjs frames review/f "4.2,4.6"을 실행하고 확인합니다.

4. QA: 확인하지 않은 프레임은 절대 보여주지 마십시오

node tools/capture.mjs sheet review/all.jpg 0.5 10(0.5초마다 타임스탬프가 찍힌 프레임)을 실행하고 전체 시트를 읽은 다음, 주요 프레임을 전체 크기로 확인합니다. 모든 프레임에 대해 다음을 질문하십시오:

  • 의미가 있는가? 한 번에 하나의 카드; 마스코트 포즈가 줄과 일치함; 소품은 그것을 잡고 있는 것과 함께 움직임. 원인보다 먼저 나타나는 것은 없음.
  • 그 순간의 내레이션과 일치하는가? 그림은 해당 줄 직전에 바뀜; 드러남은 해당 단어에 맞춰 나타남.
  • 충돌하는 것은 없는가? 팔, 스탬프, 버스트가 헤드라인, 카드, 배지, 체크리스트 또는 서로와 우연히 교차하지 않음.
  • 캡션: 1~4단어, 최대 하나의 보라색 강조 단어, 철자가 정확함, 단어가 말해지기 전에 절대 표시되지 않음.
  • 스타일 시트: 팔레트만 사용, 평평한 모양, 단단한 잉크 그림자, 위험에만 빨간색 사용.
  • 사운드: 음악 위로 음성이 또렷함; 효과는 부드러움(거친 틱이나 비프음 없음). 수정하고, 시트를 다시 렌더링하고, 다시 확인하십시오. 발견하고 수정한 사항을 사용자에게 알리십시오.

5. 전달

사용자를 위해 MP4를 엽니다. 또한 제공: 35MB를 초과하는 경우 공유용 복사본(ffmpeg -i in.mp4 -c:v libx264 -crf 21 -preset slow -c:a aac -b:a 160k -movflags +faststart share.mp4), 최고의 커버 프레임(capture.mjs frames), 제목, 캡션 및 5~8개의 해시태그. 자신의 녹음 모드의 경우, 각 줄의 타이밍이 표시된 스크립트도 제공하여 읽으면서 녹음할 수 있도록 합니다. 한 번의 정밀한 변경과 변경된 부분만 다시 렌더링하는 것을 제안합니다.

5b. Zapier를 통해 YouTube에 게시(사용자가 업로드를 요청한 경우에만)

모든 호출은 Code Mode 도구입니다: execute 내에서 tools.zapier.*로 실행하십시오(일반 도구로 호출하지 마십시오). 실제 업로드에서 한 번 검증되었으며, 아래 값은 정확합니다.

  1. 연결. list_zapier_skills에 업로드용 저장된 스킬이 있으면 사용하십시오. 그렇지 않으면 YouTube 앱이 활성화되어 있는지 확인하십시오: discover_zapier_actions({ app: "YouTube" }) → enable_zapier_action({ selected_api: "YouTubeV4CLIAPI", app_display_name: "YouTube", action: "upload_video" }). 아직 연결이 없으면 manage_zapier_connections({ selected_api: "YouTubeV4CLIAPI" })가 사용자를 위한 연결 URL을 반환합니다.
  2. 파일 호스팅. 액션의 video/thumbnail 매개변수는 Zapier 서버가 가져올 수 있는 URL이 필요합니다. 로컬 경로는 조용히 실패합니다. MP4를 임시 호스트에 올리십시오. 다음 순서로(모두 2026-11-03에 테스트됨; Windows에서는 curl.exe 사용):
    • a. litterbox(1시간~72시간 만료, 최대 1GB): curl -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@renders/<name>.mp4" https://litterbox.catbox.moe/resources/internals/api.php → 직접 URL을 일반 텍스트로 반환.
    • b. uguu.se(약 3시간 만료, 35MB 미만의 숏에 적합): curl -F "files[]=@renders/<name>.mp4" https://uguu.se/upload → JSON 반환; files[0].url(d.uguu.se/... 링크) 사용.
    • c. catbox(영구, 만료 없음): (a)와 동일한 호출에서 -F "time=1h" 제외. 공개적으로 영구 보관되므로 사용자의 동의가 있는 경우에만 사용.
    • 다음은 건너뛰십시오(2026-11-03에 손상 확인됨, 재시도 낭비하지 마십시오): 0x0.st(업로드 비활성화), tmpfiles.org(링크는 뷰어 페이지이며 원시 파일이 아님), gofile.io(원시 다운로드에 계정 토큰 필요), file.io(curl API가 웹 앱으로 리디렉션), bashupload.com, temp.sh(죽음).
    • 사용하기 전에 항상 URL을 확인하십시오: curl -sSI <url>이 비디오 콘텐츠 유형과 함께 200/206을 반환해야 합니다. 확인 없이 호스트의 JSON을 절대 신뢰하지 마십시오.
    • 사용자에게 이 작업으로 인해 비디오가 자체적으로 만료되는 공개 임시 호스트에 올라간다고 알리십시오.
  3. 먼저 확인. 이것은 사용자의 실제 채널에 쓰기 작업이므로 실행 전에 다음을 확인하십시오: 제목, 공개 범위(비공개/미등록/공개) 및 카테고리. 필요한 경우 inspect_zapier_actions({ tool_name: "youtube_upload_video", enum_property: "category_id" })로 category_id를 확인하십시오. 교육 = 27(방법 숏의 기본값), 코미디 = 23, 방법 및 스타일 = 26.
  4. 업로드. execute_zapier_write_action({ selected_api: "YouTubeV4CLIAPI", action: "upload_video", tool_name: "youtube_upload_video", params: { video: "<임시 URL>", title, description(끝에 #shorts 포함), tags: [5-8개의 해시태그, # 없이], category_id: "27", privacy_status, made_for_kids: false, embeddable: true, notify_subscribers: true, default_language: "en", license: "youtube" } })
  5. 보고. 결과에는 id가 포함됩니다. 링크는 https://www.youtube.com/watch?v=<id>입니다. 세로형 비디오가 60초 이하이면 자동으로 Shorts가 됩니다(추가 필드 불필요). 사용자를 위해 로컬 파일을 엽니다(tools.browser.preview({ path: "renders/<name>.mp4" })) 그리고 텍스트로 YouTube URL을 제공합니다. 앱 내 브라우저는 종종 ERR_ABORTED와 함께 youtube.com 로드에 실패합니다. 이는 업로드 실패가 아닙니다.
  6. 썸네일. 미등록 업로드는 이 액션을 통해 사용자 지정 썸네일을 받지 않습니다. 사용자가 나중에 비디오를 공개하는 경우 저장된 커버 프레임을 제공하십시오.

절대 하지 말 것

AI로 이미지나 비디오를 생성하지 마십시오. 사용자의 돈이나 크레딧을 사용하지 마십시오. 사용자가 요청하고 확인하지 않고 YouTube 또는 어떤 호스트에도 업로드하지 마십시오. 다른 크리에이터의 스크립트, 샷 또는 프레임을 복사하지 마십시오. 사용자의 프로젝트를 묻지 않고 덮어쓰지 마십시오. 확인하지 않은 프레임을 전달하지 마십시오.

관련 스킬