Communitygithub.com

lian4211/video-flow

任意 콘텐츠(PDF/PPT/DOCX/Markdown/웹페이지/영상/주제)를 '코드 렌더링' 방식의 시각적 설명 영상으로 제작합니다. 교수 설계, 스토리보드 및 내레이션 작성, Canvas/HTML 기반 `render(t)`로 장면별 프레임 생성, Headless Chrome 스크린샷, FFmpeg 인코딩, TTS 내레이션 및 배경음악, 소프트 자막, 품질 검사 보고서 등을 지원합니다.

video-flow란 무엇인가요?

이 AI 에이전트 스킬은 PDF, PPT, DOCX, 웹페이지, 영상 등 다양한 입력 소스를 '코드 렌더링' 방식의 전문적인 설명 동영상으로 변환하는 완전 자동화 파이프라인입니다. 사용자가 '이 PDF를 강의 영상으로 만들어 줘', '과학 설명 영상', '제품 소개 영상', 'explainer video' 등과 같이 요청하면, 먼저 효과적인 교수 구조를 설계하고 각 장면을 정의합니다. 그런 다음 Canvas/HTML의 `render(t)` 함수가 시간 `t`에 따라 완전히 결정적인 화면을 생성하고, Headless Chrome이 이를 한 프레임씩 캡처하며, FFmpeg이 최종 MP4 파일로 인코딩합니다. 선택적으로 신경망 TTS(edge-tts), 배경 음악, 자막(SRT) 및 상세한 품질 검사(QA) 보고서를 제공합니다. 이 스킬의 핵심 철학은 '영상은 시간의 순수 함수'이며, 모든 것이 단일 타임라인과 결정론적 렌더링에 의해 제어됩니다. 이 접근 방식은 기존 비디오 생성 모델(Sora 등)과 달리 완벽한 재현성, 프레임 단위 편집 가능성, 프레젠테이션 정확성을 보장합니다. 클로드 코드, Cursor, Codex 등 AI 코딩 에이전트와 함께 사용하도록 설계되었으며, `scripts/` 디렉토리의 Python 스크립트, 명확한 디렉토리 구조, 체계적인 8단계 워크플로우를 통해 사용자를 안내합니다. 16:9, 9:16, 1:1, 4:5 등 다양한 종횡비를 지원하며, 5가지 시각적 스타일과 8가지 범용 장면 유형을 내장하여 교육, 마케팅, 제품 시연 등 다양한 용도에 적합합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add lian4211/video-flow

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

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

문서

video-flow: 코드 렌더링 범용 설명 영상 워크플로우

한 마디로: '무엇을 가르칠 것인가'를 먼저 명확히 하고, 이를 계산 가능한 타임라인으로 변환한 후, 마지막으로 브라우저가 프레임별로 그려내도록 한다. 결과물 = Canvas/HTML의 render(t) + Headless Chrome 프레임별 스크린샷 + FFmpeg + 선택적 TTS/배경음악/자막.

이 스킬은 '하나의 동영상'을 8개의 검증 가능한 단계로 나눕니다. 각 단계마다 산출물과 검증 포인트가 있으며; 어느 단계에서든 조건을 충족하지 못하면 다음 단계로 넘어가지 않습니다.


0. 사용 시기 / 사용하지 않을 시기

사용

  • PDF / PPT / DOCX / 기사 / 웹페이지 / 영상 / 주제를 1~5분 분량의 설명 동영상으로 만들 때
  • '문자가 명확하고, 데이터가 정확하며, 한 프레임을 수정할 수 있고, 재현 가능한' 동영상이 필요할 때 (코드 렌더링은 비디오 생성 모델 대비 구조적 이점이 있음)
  • 세로/정사각형/가로 등 여러 버전 또는 다국어 버전이 필요할 때
  • 내레이션, 자막, 배경 음악이 필요하고, 전체 프로세스가 반복 가능하기를 원할 때

사용하지 않음

  • 실제 인물/실사/사실적인 장면이 필요한 경우 → 비디오 생성 모델 또는 실사 촬영 사용. 이 스킬은 '코드 계층'만 담당합니다.
  • 기존 자료를 단순히 편집하는 경우 → 편집 도구/Agent 사용.
  • 스토리보드와 스크립트를 정하지 않고 단순히 MP4 파일만 생성하려는 경우 → 결과물이 템플릿처럼 보일 수 있으므로 1~2단계를 먼저 수행하는 것이 좋습니다.

1. 엄격한 규칙 (위반 시 재작업)

  1. 화면은 시간의 순수 함수: 페이지는 window.render(t)를 노출해야 합니다. 주어진 t에 대해 화면은 유일하게 결정됩니다.
    • Date.now(), 시드 없는 랜덤, requestAnimationFrame 기반 상태, CSS transition/animation, 프레임 간 캐시를 금지합니다.
    • 누적형 애니메이션(파티클/수면)은 0부터 t까지 고정된 스텝으로 진행하거나 해석적 공식으로 대체합니다.
  2. 타임라인이 유일한 진실 공급원: 스토리보드, 내레이션, 배경 음악, 음향 효과, 자막은 모두 동일한 timeline.json에서 파생됩니다.
  3. 스토리보드 우선, 코드 나중: storyboard.md와 script.json이 없으면 장면 코드를 작성하지 않습니다.
  4. 원문 사실을 지어내지 않음: 숫자, 연도, 인명, 공식은 반드시 원본 자료에서 가져와야 합니다. 불확실한 경우 [확인 필요]로 표시하고 납품 시 별도로 나열합니다.
  5. 기본적으로 브랜드/워터마크 없음: 사용자가 로고/브랜드명을 제공하지 않는 한 기본 페이지 하단에는 강의/주제 정보만 표시합니다.
  6. 단일 인코딩: 오디오는 WAV 단계에서 믹싱과 라우드니스 처리를 완료하고, 최종적으로 한 번만 AAC 인코딩합니다. 반복적인 트랜스코딩을 금지합니다.
  7. 납품 전 반드시 QA 통과: 결함 프레임, 검은 프레임, 라우드니스, 길이, 자막, 오디오-비디오 동기화 확인 (8단계 참조).

2. 입력 및 산출물

입력 (선택 사항, 혼합 가능)

유형처리 방식
PDFscripts/ingest.py로 텍스트 추출; 스캔본/깨짐 시 자동으로 PNG로 래스터화하여 모델이 '페이지를 보도록' 함
PPTX페이지별 제목, 본문, 메모 추출; 필요 시 주요 페이지를 이미지로 내보내기
DOCX / Markdown / TXTsource/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. 대상은 누구인가? 그들은 무엇을 이미 알고 있는가?
  2. 시청 후 말하거나/할 수 있어야 하는 것은 무엇인가? (1~3개의 검증 가능한 목표)
  3. 가장 오해하기 쉽거나/어려운 점은 무엇인가?
  4. 반드시 등장해야 할 사실/공식/데이터는 무엇인가? 출처는 각각 어디인가?
  5. 길이와 화면비율은? 플랫폼은? (강의실/모바일/소셜미디어)?

원문 페이지 순서대로 설명하지 마십시오. 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. 화면 텍스트 ≠ 내레이션 대본: 화면에는 키워드/결론만 남기고, 내레이션이 설명을 담당합니다.
  2. 한 화면에는 최대 1개의 결론 + 3개의 근거; 제목은 18자 이내, 본문은 줄당 22자 이내.
  3. 2~4초마다 변화가 있어야 함 (요소/장면/강조). 단, 파티클 폭발은 피하십시오.
  4. 먼저 '금지 목록'을 작성: 그라데이션 배경 + 중앙 큰 글자, 모든 요소 페이드 인, 화면 가득 작은 글자, 무의미한 광채 효과.
  5. 사실 문장은 출처를 별도로 표시; 불확실한 것은 [확인 필요] 추가.

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:91920×1080좌우 96 / 상하 6472–12028–40
9:161080×1920좌우 64 / 상하 16064–9632–44
1:11080×1080사방 7256–8828–40
4:51080×1350사방 8060–9230–42

세로 화면은 레이아웃을 재구성해야 함: 제목은 상단, 그림은 중간, 결론은 하단; 가로로 압축하지 마십시오. 템플릿은 layout()을 사용하여 화면비율에 따라 전환합니다. references/formats.md 참조.


6. 일반적인 실패 → 해결 방법

현상근본 원인해결 방법
검은 화면/흰 화면JS 오류, render 미정의, 캔버스 크기 0render.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: 검증 체크리스트 및 자동 검사 명령어.

관련 스킬