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. 제작
bash SKILL/scripts/new_video.sh mascot-explainer <short-name>는 예제를~/faceless-shorts/<short-name>/에 복사합니다.script.json을 작성합니다(줄 + 캡션 + 간격; STYLE.md 참조). 먼저 마스코트를 만듭니다(mascot.json, STYLE.md §2), 포즈 시트를 렌더링하고 샷을 작성하기 전에 사용자의 승인을 받습니다.- 타이밍:
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>). src/shots.js를 다시 작성합니다: 한 줄에 하나의 샷(또는 긴 줄의 경우 두 개), 각각은cut(i)로 배치하고 키 모멘트는Wd('word', line)로 단어에 배치합니다. 키트(src/core/kit.js)를 재사용하고, 새 구성 요소는 스타일 룩에 따라 그곳에 추가합니다.- 프로젝트에서:
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.*로 실행하십시오(일반 도구로 호출하지 마십시오). 실제 업로드에서 한 번 검증되었으며, 아래 값은 정확합니다.
- 연결.
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을 반환합니다. - 파일 호스팅. 액션의
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을 절대 신뢰하지 마십시오. - 사용자에게 이 작업으로 인해 비디오가 자체적으로 만료되는 공개 임시 호스트에 올라간다고 알리십시오.
- a. litterbox(1시간~72시간 만료, 최대 1GB):
- 먼저 확인. 이것은 사용자의 실제 채널에 쓰기 작업이므로 실행 전에 다음을 확인하십시오: 제목, 공개 범위(비공개/미등록/공개) 및 카테고리.
필요한 경우
inspect_zapier_actions({ tool_name: "youtube_upload_video", enum_property: "category_id" })로category_id를 확인하십시오. 교육 = 27(방법 숏의 기본값), 코미디 = 23, 방법 및 스타일 = 26. - 업로드.
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" } }) - 보고. 결과에는
id가 포함됩니다. 링크는https://www.youtube.com/watch?v=<id>입니다. 세로형 비디오가 60초 이하이면 자동으로 Shorts가 됩니다(추가 필드 불필요). 사용자를 위해 로컬 파일을 엽니다(tools.browser.preview({ path: "renders/<name>.mp4" })) 그리고 텍스트로 YouTube URL을 제공합니다. 앱 내 브라우저는 종종 ERR_ABORTED와 함께 youtube.com 로드에 실패합니다. 이는 업로드 실패가 아닙니다. - 썸네일. 미등록 업로드는 이 액션을 통해 사용자 지정 썸네일을 받지 않습니다. 사용자가 나중에 비디오를 공개하는 경우 저장된 커버 프레임을 제공하십시오.
절대 하지 말 것
AI로 이미지나 비디오를 생성하지 마십시오. 사용자의 돈이나 크레딧을 사용하지 마십시오. 사용자가 요청하고 확인하지 않고 YouTube 또는 어떤 호스트에도 업로드하지 마십시오. 다른 크리에이터의 스크립트, 샷 또는 프레임을 복사하지 마십시오. 사용자의 프로젝트를 묻지 않고 덮어쓰지 마십시오. 확인하지 않은 프레임을 전달하지 마십시오.