video-flow: 코드 렌더링 범용 설명 영상 워크플로우
한 마디로: '무엇을 가르칠 것인가'를 먼저 명확히 하고, 이를 계산 가능한 타임라인으로 변환한 후, 마지막으로 브라우저가 프레임별로 그려내도록 한다. 결과물 = Canvas/HTML의
render(t)+ Headless Chrome 프레임별 스크린샷 + FFmpeg + 선택적 TTS/배경음악/자막.
이 스킬은 '하나의 동영상'을 8개의 검증 가능한 단계로 나눕니다. 각 단계마다 산출물과 검증 포인트가 있으며; 어느 단계에서든 조건을 충족하지 못하면 다음 단계로 넘어가지 않습니다.
0. 사용 시기 / 사용하지 않을 시기
사용
- PDF / PPT / DOCX / 기사 / 웹페이지 / 영상 / 주제를 1~5분 분량의 설명 동영상으로 만들 때
- '문자가 명확하고, 데이터가 정확하며, 한 프레임을 수정할 수 있고, 재현 가능한' 동영상이 필요할 때 (코드 렌더링은 비디오 생성 모델 대비 구조적 이점이 있음)
- 세로/정사각형/가로 등 여러 버전 또는 다국어 버전이 필요할 때
- 내레이션, 자막, 배경 음악이 필요하고, 전체 프로세스가 반복 가능하기를 원할 때
사용하지 않음
- 실제 인물/실사/사실적인 장면이 필요한 경우 → 비디오 생성 모델 또는 실사 촬영 사용. 이 스킬은 '코드 계층'만 담당합니다.
- 기존 자료를 단순히 편집하는 경우 → 편집 도구/Agent 사용.
- 스토리보드와 스크립트를 정하지 않고 단순히 MP4 파일만 생성하려는 경우 → 결과물이 템플릿처럼 보일 수 있으므로 1~2단계를 먼저 수행하는 것이 좋습니다.
1. 엄격한 규칙 (위반 시 재작업)
- 화면은 시간의 순수 함수: 페이지는
window.render(t)를 노출해야 합니다. 주어진t에 대해 화면은 유일하게 결정됩니다.Date.now(), 시드 없는 랜덤,requestAnimationFrame기반 상태, CSStransition/animation, 프레임 간 캐시를 금지합니다.- 누적형 애니메이션(파티클/수면)은 0부터
t까지 고정된 스텝으로 진행하거나 해석적 공식으로 대체합니다.
- 타임라인이 유일한 진실 공급원: 스토리보드, 내레이션, 배경 음악, 음향 효과, 자막은 모두 동일한
timeline.json에서 파생됩니다. - 스토리보드 우선, 코드 나중:
storyboard.md와script.json이 없으면 장면 코드를 작성하지 않습니다. - 원문 사실을 지어내지 않음: 숫자, 연도, 인명, 공식은 반드시 원본 자료에서 가져와야 합니다. 불확실한 경우
[확인 필요]로 표시하고 납품 시 별도로 나열합니다. - 기본적으로 브랜드/워터마크 없음: 사용자가 로고/브랜드명을 제공하지 않는 한 기본 페이지 하단에는 강의/주제 정보만 표시합니다.
- 단일 인코딩: 오디오는 WAV 단계에서 믹싱과 라우드니스 처리를 완료하고, 최종적으로 한 번만 AAC 인코딩합니다. 반복적인 트랜스코딩을 금지합니다.
- 납품 전 반드시 QA 통과: 결함 프레임, 검은 프레임, 라우드니스, 길이, 자막, 오디오-비디오 동기화 확인 (8단계 참조).
2. 입력 및 산출물
입력 (선택 사항, 혼합 가능)
| 유형 | 처리 방식 |
|---|---|
scripts/ingest.py로 텍스트 추출; 스캔본/깨짐 시 자동으로 PNG로 래스터화하여 모델이 '페이지를 보도록' 함 | |
| PPTX | 페이지별 제목, 본문, 메모 추출; 필요 시 주요 페이지를 이미지로 내보내기 |
| DOCX / Markdown / TXT | source/source.md로 직접 추출 |
| 웹페이지 URL | 본문 가져오기; 출처 링크 유지 |
| 영상 | ffprobe 메타데이터 + 특정 지점 프레임 캡처; ASR 없을 시 사람이 내용 보충 |
| 순수 주제 | 사용자가 제공한 한 문장/개요; 먼저 사용자에게 '반드시 등장해야 할 사실'을 확인 |
각 프로젝트의 디렉토리 규약
<project>/
project.json # 메타 정보: 제목/대상/목표/화면비율/스타일/음성/음악/브랜드
source/ # 원본 자료 (source.md, pages/*.png, meta.json)
storyboard.md # 스토리보드 표: 각 장면이 설명할 내용, 화면, 길이, 내레이션, 확인 사항
script.json # 기계 판독 가능: scenes[] (type/대본/시각적 설명/vo/길이)
build/ # index.html + lib.js + theme.js + scenes.js + timeline.js
audio/ # vo/*.wav, bgm, mix.wav
frames/ # 프레임별 JPEG
out/ # final.mp4 / final.srt / poster.png
qa/ # report.md + contact sheets + 결함 프레임
scripts/init_project.py를 사용하여 한 번에 기본 구조를 생성합니다.
3. 워크플로우 (8단계)
0단계: 환경 확인
python scripts/check_env.py
필수: Python 3.10+, FFmpeg/ffprobe, Chromium 기반 브라우저, numpy/scipy.
권장: edge-tts (온라인 신경망 음성), pypdf, python-pptx, python-docx, Pillow.
부족한 항목은 출력된 안내에 따라 설치; 설치가 불가능하면 기능 축소 (내레이션 없음 / 시스템 음성 / 수동 오디오).
1단계: 원본 자료 읽고 '교수 구조' 도출
먼저 5가지 질문에 답변 (project.json의 brief에 작성):
- 대상은 누구인가? 그들은 무엇을 이미 알고 있는가?
- 시청 후 말하거나/할 수 있어야 하는 것은 무엇인가? (1~3개의 검증 가능한 목표)
- 가장 오해하기 쉽거나/어려운 점은 무엇인가?
- 반드시 등장해야 할 사실/공식/데이터는 무엇인가? 출처는 각각 어디인가?
- 길이와 화면비율은? 플랫폼은? (강의실/모바일/소셜미디어)?
원문 페이지 순서대로 설명하지 마십시오. references/storytelling.md의 4가지 구조 중 하나를 사용하여 재구성하십시오:
- 인과 관계 체인 (이과/공학에 권장);
- 문제 → 해결책 → 검증;
- 오해 → 바로잡기 → 전이;
- 타임라인/프로세스.
2단계: 스타일 및 화면비율 결정
references/styles.md에서 1개의 스타일 (silicon / paper / blueprint / neon / swiss)을 선택하고, references/formats.md에서 화면비율을 결정합니다.
규칙:
- 내용이 '칩/공학/데이터' 위주 → silicon / blueprint;
- '인문/생물/역사' 위주 → paper;
- '발표/마케팅/젊은 감각' 위주 → neon / swiss;
- 한 화면에 한 가지 주제만 표시; 세로 화면은 반드시 레이아웃을 재구성해야 하며, 가로 화면을 그냥 잘라내지 마십시오.
3단계: 스토리보드 및 스크립트 작성
산출물: storyboard.md (사람용) 및 script.json (기계용). 각 장면은 반드시 다음을 포함해야 합니다:
type(title/concept/process/compare/formula/bars/quote/recap/custom)kicker(소제목),headline(한 줄 결론),points(≤3개)vo(내레이션, 1~2문장; 녹음이 없으면 비워둠)visual(그림/표/프로세스/공식의 구체적인 데이터)duration(비울 수 있음, 내레이션 길이에 따라 자동 결정)
스크립트 작성 5가지 엄격한 규칙:
- 화면 텍스트 ≠ 내레이션 대본: 화면에는 키워드/결론만 남기고, 내레이션이 설명을 담당합니다.
- 한 화면에는 최대 1개의 결론 + 3개의 근거; 제목은 18자 이내, 본문은 줄당 22자 이내.
- 2~4초마다 변화가 있어야 함 (요소/장면/강조). 단, 파티클 폭발은 피하십시오.
- 먼저 '금지 목록'을 작성: 그라데이션 배경 + 중앙 큰 글자, 모든 요소 페이드 인, 화면 가득 작은 글자, 무의미한 광채 효과.
- 사실 문장은 출처를 별도로 표시; 불확실한 것은
[확인 필요]추가.
4단계: 내레이션 및 타임라인 생성
# 선택 사항: 녹음이 없으면 건너뛰고 각 scene에 duration 직접 입력
python scripts/tts.py --project . --voice zh-CN-XiaoxiaoNeural --rate +3%
python scripts/timeline.py --project .
tts.py는audio/vo/<id>.wav(48 kHz)를 출력하며, 자동으로 가벼운 EQ/압축 수행;--from-dir옵션으로 실제 사람 녹음 지원.timeline.py는 실제 측정된 내레이션 길이를 사용하여build/timeline.js와timeline.json생성:scene.duration = head + voDuration + tail, 내레이션이 없는 장면은 명시적duration사용.- 이후에는 script.json만 수정하고 이 두 단계를 다시 실행하십시오. 타임라인을 직접 수정하지 마십시오.
5단계: 페이지 구축 및 장면 구현
템플릿 사용:
python scripts/init_project.py --dir my-video --title "..." --format 16:9 --style silicon
# build/content 편집은 timeline.py가 생성; 범용 장면은 이미 구현되어 있으므로 script.json만 수정
- 범용 장면 (8가지 유형)은
build/scenes.js에 있으며,CONTENT를 읽어 렌더링; 대부분의 설명 영상에서 충분합니다. - 전문적인 그림 (칩/회로/해부학/지도/분자)이 필요한 경우
build/custom.js작성:window.CUSTOM['s3'] = function(u, D, sc, ctx){ /* lib.js의 helpers를 사용하여 그림 */ };script.json에서 해당 장면의type을custom으로 설정. - 한 번에 하나의 장면만 작업: 먼저 3개의 정적 프레임 렌더링 (
scripts/render.py --still 1.2,2.4,3.6), 텍스트 넘침/겹침/주요 요소 크기 확인 후 계속.
6단계: 렌더링
python scripts/render.py --project . --fps 30
# 특정 구간만 렌더링: --start 8 --duration 4
# 기존 Chrome 재사용: --cdp http://127.0.0.1:9333
# 스크립트가 Chrome 실행하도록: --launch-chrome
출력: frames/f00000.jpg..., 중단 후 재개 가능 (이미 존재하고 2KB 이상인 프레임은 건너뜀).
Headless Chrome과 샌드박스: 실행 환경이 Chrome의 IPC/파이프를 금지하는 경우, 허용된 환경에서 실행하거나
--cdp로 이미 실행 중인 Chrome에 연결하십시오.
7단계: 배경 음악, 음향 효과, 믹싱, 자막
python scripts/audio.py --project . # BGM 합성 + 내레이션 배치 + duck + 마스터링
python scripts/srt.py --project . # out/final.srt 생성
- 내레이션 없음:
audio.py --no-bgm또는 사용자가 제공한 음악만 사용. - 사용자가 음악 제공:
audio/music.*에 배치,audio.py가 자동으로 반복/자르기 및 duck 수행. - 목표 라우드니스 기본값 −14.2 LUFS, 실제 피크 ≤ −1.5 dBFS; 오디오는 한 번만 인코딩.
8단계: 인코딩 + QA + 납품
python scripts/encode.py --project . # frames+mix+srt → out/final.mp4
python scripts/qa.py --project . # qa/report.md + 결함 프레임 모자이크
QA는 모두 통과해야 함 (references/qa.md 참조):
- 길이/화면비율/프레임레이트/오디오 트랙/자막 스트림 정확;
- ≥0.25초 검은 프레임 없음; 결함 프레임에 공백/텍스트 겹침/넘침 없음;
- 라우드니스 목표 ±1 LU 이내, 실제 피크 ≤ −1.5 dBFS;
- 첫 프레임이 완전 검은색이 아님; 마지막 장면이 마무리됨;
- 사실 목록이 원본 자료와 일치;
[확인 필요]항목은 별도 목록화.
납품: out/final.mp4, out/final.srt, poster.png, storyboard.md, script.json, qa/report.md, 렌더링 소요 시간 및 알려진 문제점.
4. 범용 장면 유형 (템플릿에 구현됨)
| type | 용도 | 주요 필드 |
|---|---|---|
title | 오프닝/챕터 | title/subtitle/kicker |
concept | 하나의 개념 + 3가지 요점 | headline/points/visual |
process | 프로세스/단계 (3~5단계) | steps[] |
compare | 양측 비교 | left/right |
formula | 공식 + 설명 | formula/notes[] |
bars | 데이터 비교 | items[{label,value}] |
quote | 명언/결론 | quote/author |
recap | 요약 지도 | nodes[]/takeaway |
custom | 전문 그림 | 직접 custom.js 작성 |
새 유형이 필요할 때: scenes.js에 window.SCENES_IMPL['type']을 추가하고 references/pipeline.md에 데이터 계약을 기록하십시오.
5. 화면비율 및 안전 영역
| 화면비율 | 크기 | 안전 영역 | 제목 글꼴 크기 | 본문 글꼴 크기 |
|---|---|---|---|---|
| 16:9 | 1920×1080 | 좌우 96 / 상하 64 | 72–120 | 28–40 |
| 9:16 | 1080×1920 | 좌우 64 / 상하 160 | 64–96 | 32–44 |
| 1:1 | 1080×1080 | 사방 72 | 56–88 | 28–40 |
| 4:5 | 1080×1350 | 사방 80 | 60–92 | 30–42 |
세로 화면은 레이아웃을 재구성해야 함: 제목은 상단, 그림은 중간, 결론은 하단; 가로로 압축하지 마십시오. 템플릿은 layout()을 사용하여 화면비율에 따라 전환합니다. references/formats.md 참조.
6. 일반적인 실패 → 해결 방법
| 현상 | 근본 원인 | 해결 방법 |
|---|---|---|
| 검은 화면/흰 화면 | JS 오류, render 미정의, 캔버스 크기 0 | render.py --still 로 콘솔 확인; 캔버스에 명시적 너비/높이 지정 |
| 폰트 오류/첫 프레임 대체 폰트 | 폰트 로드 안 됨 | document.fonts.ready를 기다려 READY=true 설정; CJK는 시스템 대체 문자열 사용 |
| 동일 t에서 두 번 다름 / 병렬 깜빡임 | rAF/타이머/랜덤/프레임 간 상태 사용 | 순수 함수로 변경; hash(seed); 폐쇄형 스프링 |
| 텍스트 겹침/넘침 | 장면별 정적 프레임 확인 안 함 | 장면당 3개의 정적 프레임 + 세로 화면 360px 너비 프레임 캡처 |
| 오디오-비디오 불일치 | 오디오가 0부터 시작 vs 비디오가 start부터; TTS 문장별 연결 | 동일 타임라인; 전체 TTS; -ss를 -i 앞에 배치 |
| 라우드니스 급변 | 여러 번의 loudnorm/트랜스코딩 | WAV 단계에서만 정적 게인; 한 번의 AAC |
| 렌더링 너무 느림 | 4K/서브프레임/브러시/WebGL | 먼저 960×540으로 작은 샘플; 서브프레임은 빠른 동작에만; 병렬 워커 |
| Chrome 실행 안 됨 | 샌드박스가 IPC/파이프 제한 | 허용된 환경에서 실행하거나 --cdp로 실행 중인 Chrome에 연결 |
7. 확장 포인트
- 새 스타일:
templates/styles/*.json을 복사하여 색상 팔레트/폰트/배경 유형 변경;styles.md에 추가. - 새 장면:
build/scenes.js에 등록; 또는build/custom.js에 전문 그림 작성. - 실제 사람 녹음: 녹음을
<scene-id>.wav형식으로audio/vo_human/에 배치;tts.py --from-dir로 리샘플링/가벼운 처리만 수행. - 다국어:
script.<lang>.json+ 해당 TTS 음성; 타임라인은 동일한 화면 세트 재사용 가능 (텍스트 길이 차이 주의). - 다중 화면비율: 동일한
script.json을 다른project.format으로 init/render 재실행; 레이아웃은layout()이 적응. - 브랜드:
project.json.brand로 로고 텍스트/색상/페이지 하단 제공; 기본값은 비활성화.
8. 참조 문서
references/pipeline.md: 전체 기술 파이프라인,render(t)계약, CDP 렌더링, FFmpeg 매개변수, 타임라인 데이터 모델.references/inputs.md: PDF/PPT/DOCX/URL/영상 추출 및 OCR 대비책.references/storytelling.md: 4가지 교수 구조, 리듬 표, 스크립트 규칙.references/styles.md: 5가지 스타일의 색상 팔레트/폰트/모션 효과/적용 주제.references/formats.md: 화면비율, 안전 영역, 세로 화면 재구성 규칙.references/audio.md: TTS 옵션, 실제 사람 녹음, 배경 음악 합성, ducking, 라우드니스, 단일 인코딩.references/qa.md: 검증 체크리스트 및 자동 검사 명령어.