마스터 클래스 렌더은(는) 무엇을 하나요?
입력: <source>/scripts/NN - Title.script.md (master-class에서 작성).
사용자 작성: <source>/scenes/NN.scenes.md (D2 텍스트, 좌표 및 타이밍 없음).
하나의 명령어로 다음을 생성: <videos>/NN - Title.mp4 + <notes>/NN - Title.md + <notes>/<MOC>.md.
모든 것이 로컬에서 실행됨: D2가 다이어그램을 (스케치 스타일로) 배치하고, Kokoro-82M이 음성을 생성하며, 실제 오디오로부터 타이밍이 결정되고, Chromium이 시각적 변경마다 한 프레임을 캡처하며, ffmpeg가 인코딩합니다. 어떤 데이터도 제3자에게 전송되지 않습니다. 사용되는 유일한 토큰은 장면 파일(스크립트 크기의 약 1배)입니다.
0 · 설정 (머신당 한 번; 재실행해도 안전)
bash ~/.copilot/skills/master-class-render/scripts/setup.sh
d2, ffmpeg, uv (Homebrew), scripts/.venv 내 가상환경(kokoro-onnx, soundfile, playwright(Chromium) 포함), 그리고 ~/.cache/kokoro (~350 MB)에 Kokoro 모델을 설치합니다. scripts/.venv/bin/python이 이미 존재하면 설정이 완료된 것입니다.
1 · 장면 작성
참고자료/scenes-guide.md와 승인된 예제 01, 05, 08를 먼저 읽으십시오. 각 예제는 ~/.copilot/skills/master-class/examples/에 있는 해당 스크립트와 쌍을 이루므로, 각 화면이 어떻게 다이어그램이 되는지 정확히 볼 수 있습니다. 이 단계는 작고 빠른 모델에서도 잘 실행됩니다: 한 번에 한 레슨씩 작업하고, 검증기가 올바르다고 알릴 때까지 진행하세요. 그런 다음 각 스크립트에 대해, 하나의 ## Beat N과 비트당 하나의 ```d2 블록을 작성하여 해당 비트의 화면 설명을 변환합니다:
# @at "phrase"(해당 비트 내레이션에서 그대로 가져온 3–7 단어)는 화자가 그 구절을 말할 때 뒤의 내용이 나타나도록 합니다. 최종 레이아웃은 한 번만 계산되므로 아무것도 움직이지 않으며, 새 조각이 잠시 반짝입니다.# @continue는 이전 비트의 다이어그램을 확장합니다.- 클래스:
model,code,tool,data,person,bad,good,note(결론을 담은 스티커; 수업 노트의 핵심 아이디어가 됨),muted,wrong. - 가이드에는 D2 주의사항(
\$,{}블록 내부에서는@at사용 불가,|||md테이블, 스타일 변경은 애니메이션되지 않음)이 나와 있습니다.
각 레슨을 진행하면서 검증하십시오 (반드시 ok:를 출력하고 warning:이 없어야 함):
cd ~/.copilot/skills/master-class-render/scripts && export PATH=/opt/homebrew/bin:$PATH
.venv/bin/python render.py "<source>/scripts/NN - Title.script.md" "<source>/scenes/NN.scenes.md" /tmp/check.html
레슨이 많으면 가이드와 예제와 함께 병렬 하위 에이전트(각각 약 4개 레슨)로 분할하십시오.
2 · 코스 구축
cd ~/.copilot/skills/master-class-render/scripts && export PATH=/opt/homebrew/bin:$PATH
.venv/bin/python build_course.py \
--source "<lab>/_attachments/master-class/source" \
--videos "<lab>/_attachments/master-class" \
--notes "<lab>/Master class" \
--moc "<Lab name> · Master class" \
--course "<label shown top-left in the video>" \
--tags "course/<course-tag>,section/labs,topic/<x>,type/lesson" \
--intro "One paragraph for the MOC: what the course is built from ([[source note links]]) and its intent." \
--voice am_michael --lang en-us
- 언어/음성: 영어
--voice am_michael --lang en-us(대안am_puck,bm_george --lang en-gb); 스페인어--voice em_alex --lang es(여성:ef_dora). --only 03,07로 선택한 레슨만 다시 빌드합니다 (노트는 항상 전체 재생성).--notes-only는 비디오 없이 노트만 재생성합니다.- 음성이 캐시된 후 레슨당 약 15초 (첫 번째 합성은 레슨당 약 1분). 출력물은 임시 폴더에 인코딩된 후 복사됩니다. OneDrive 동기화 폴더에 직접 쓰면 타임아웃이 발생하기 때문입니다.
--tags를 원본 노트에서 사용된 태그와 일치시키십시오.
3 · 보고 전 확인
- 빌드가 모든 레슨에 대해
ok:를 출력했고!! ... @at phrase(s) not found가 없어야 합니다. - 하나 또는 두 개의 MP4에서 2프레임을 추출하여 확인하십시오 (매번 새 파일 이름 사용; 이미지 뷰어가 캐시함):
ffmpeg -v error -ss 120 -i "<mp4>" -frames:v 1 -vf scale=1280:-1 /tmp/mc_check_<n>.png확인: 다이어그램이 읽을 수 있고 (아주 작은 띠가 아님), 캡션이 일치하며, 올바른 비트가 표시되어야 합니다. - 다이어그램이 너무 작은가요? 렌더러가 자동으로 다른 레이아웃 방향을 시도합니다. 여전히 작다면, 비트의 다이어그램을 분할하거나
@continue를 제거하고 이전 단계를 하나의muted상자에 요약하십시오. - MOC 노트와 하나의 수업 노트를 열어 확인: 비디오 임베드
![[NN - Title.mp4]], 목표, 핵심 아이디어, 확인 문제 (질문 + 접힌 답변), 접힌 대본, 이전/다음 링크.
각 수업 노트의 내용 (생성됨, 토큰 사용 없음)
Frontmatter (태그, 레슨, 길이, 코스 링크) · 임베드된 MP4 · 목표 · 오해 · 핵심 아이디어 (note 스티커로부터) · 확인 문제 (회상 멈춤 비트로부터) · 접힌 대본 · ← 이전 · 코스 색인 · 다음 →.
파일
scripts/: build_course.py (진입점) · render.py (스크립트 + 장면 → 오디오 및 타임라인이 있는 중간 HTML) · export_mp4.py (HTML → MP4) · make_notes.py (노트 + MOC) · player.html (중간 템플릿; 오프라인 플레이어로도 사용 가능) · prelude.d2 (클래스, 글꼴 크기) · setup.sh. 캐시: scripts/.cache/ (음성 클립, 다이어그램; 삭제해도 안전).