Auto Demo Producer (자동 데모 제작기)
모든 웹 애플리케이션의 전문 내레이터 비디오 데모를 자동으로 제작합니다.
파이프라인 개요
사용자 컨텍스트 → 데모 스크립트 → 슬라이드 → TTS 내레이션 → 브라우저 녹화 → 최종 MP4
세 단계, 완전 자동화:
- 내레이션 — edge-tts (무료 Microsoft Neural TTS)가 장면별 오디오 생성
- 녹화 — Playwright가 헤드리스 Chromium을 구동하여 비디오 캡처
- 조립 — ffmpeg가 비디오 + 오디오를 병합하여 정제된 MP4 생성
활성화 시점
- 사용자가 "데모를 만들어 줘", "워크스루를 녹화해 줘", "비디오 데모를 제작해 줘"라고 요청할 때
- 사용자가 URL과 보여줄 내용을 제공할 때
- 사용자가 자동 내레이션 스크린캐스트를 원할 때
단계별 워크플로우
1단계: 컨텍스트 수집
사용자에게 다음을 요청하세요:
- 대상 URL — 데모할 웹 앱 (예:
https://myapp.azurewebsites.net) - 보여줄 내용 — 주요 기능, 사용자 흐름 또는 시나리오
- 대상 청중 — 누가 볼 것인가? (임원, 개발자, 고객)
- 목표 길이 — 데모 길이는? (일반적으로 1-5분)
- 음성 선호도 — 언어와 성별 (기본값:
en-US-JennyNeural) - 브랜딩 — 제품명, 부제목, 조직, 인트로/아웃트로 강조 색상
2단계: 데모 스크립트 생성
다음 형식을 사용하여 demo_script.md를 생성하세요:
# 데모: {제품명}
## intro | 5
> slide intro
제품명 데모에 오신 것을 환영합니다. 오늘은 주요 기능을 살펴보겠습니다.
## login | 8
> goto {base_url}
> fill 사용자명 [email protected]
> fill 비밀번호 ****
> click button 로그인
여기서 데모 자격 증명을 사용하여 애플리케이션에 로그인합니다.
## dashboard | 10
> wait 2
> scroll down 300
대시보드는 모든 활성 항목의 실시간 개요를 보여줍니다.
## feature_one | 12
> click link Feature One
> wait 1
> scroll down 200
워크플로우를 생성하고 관리할 수 있는 기능 하나를 살펴보겠습니다.
## outro | 5
> slide outro
시청해 주셔서 감사합니다! 더 자세한 정보는 contoso.com을 방문해 주세요.
스크립트 형식 규칙:
## scene_id | min_duration_seconds— 장면 헤더> action args...— Playwright 동작 (아래 동작 참조)- 일반 텍스트 줄 = 내레이션 (TTS 음성으로 읽힘)
- 내레이션이 실제 장면 길이를 결정합니다 (오디오 길이에 맞춰 패딩됨)
3단계: 슬라이드 생성
슬라이드 생성기를 실행하여 인트로/아웃트로 HTML 파일을 만드세요:
python generate_slides.py `
--title "제품명" `
--subtitle "여기에 태그라인" `
--org "Contoso" `
--badge "Azure 제공" `
--accent "#60a5fa" `
--out-dir ./slides
4단계: 의존성 설치
pip install edge-tts playwright
playwright install chromium
# ffmpeg가 사용 가능한지 확인:
# Windows: winget install Gyan.FFmpeg
# macOS: brew install ffmpeg
# Linux: sudo apt install ffmpeg
5단계: 레코더 실행
python record_demo.py `
--script demo_script.md `
--base-url "https://myapp.azurewebsites.net" `
--voice en-US-JennyNeural `
--slides-dir ./slides `
--output demo_final.mp4
추가 옵션:
--resolution 1280x720— 더 작은 파일 크기--var project_id=abc123— 스크립트의 사용자 정의 변수--var [email protected]— 매개변수화된 흐름
6단계: 검토 및 반복
녹화 후 출력 비디오를 검토하세요. 일반적인 조정 사항:
- 너무 빠름? 장면 헤더에서
min_duration증가 - 타이밍이 잘못됨? 단계 사이에
> wait N동작 추가 - 단계 누락? 스크립트에 장면 더 추가
- 음성이 마음에 안 듦? 다른 edge-tts 음성 시도
동작 참조
| 동작 | 구문 | 설명 |
|---|---|---|
goto | > goto https://url.com | URL로 이동 |
slide | > slide intro | 슬라이드 디렉토리에서 HTML 슬라이드 표시 |
click | > click link 링크 텍스트 | 텍스트로 링크 클릭 |
click | > click button 버튼 텍스트 | 텍스트로 버튼 클릭 |
click | > click text 모든 텍스트 | 텍스트로 요소 클릭 |
fill | > fill 레이블 값 | 양식 텍스트 상자 채우기 |
type | > type #선택자 값 | CSS 선택자로 요소에 입력 |
hover | > hover 요소 텍스트 | 요소 위로 마우스 가져가기 |
select | > select 레이블 옵션 | 드롭다운 옵션 선택 |
scroll | > scroll down 300 | 아래로 픽셀만큼 스크롤 |
scroll | > scroll up 200 | 위로 픽셀만큼 스크롤 |
wait | > wait 2 | N초 동안 일시 정지 |
screenshot | > screenshot name.png | 스크린샷 저장 |
음성 선택
인기 있는 edge-tts 음성 (모두 무료, API 키 불필요):
| 음성 | 언어 | 스타일 |
|---|---|---|
en-US-JennyNeural | 영어 (미국) | 따뜻하고 대화체 |
en-US-GuyNeural | 영어 (미국) | 전문적이고 명확함 |
en-US-AriaNeural | 영어 (미국) | 자연스럽고 다재다능함 |
en-GB-SoniaNeural | 영어 (영국) | 세련되고 전문적 |
it-IT-IsabellaNeural | 이탈리아어 | 자연스럽고 명확함 |
de-DE-KatjaNeural | 독일어 | 전문적 |
fr-FR-DeniseNeural | 프랑스어 | 우아함 |
es-ES-ElviraNeural | 스페인어 | 명확함 |
ja-JP-NanamiNeural | 일본어 | 자연스러움 |
zh-CN-XiaoxiaoNeural | 중국어 | 다재다능함 |
전체 목록: edge-tts --list-voices
변수
스크립트에서 {변수명}을 사용하세요. 내장 변수:
{base_url}—--base-url인수로 설정
--var key=value를 통한 사용자 정의 변수:
> goto {base_url}/projects/{project_id}
> fill 검색 {search_term}
출력
이 스킬은 다음을 생성합니다:
demo_final.mp4— H.264 비디오, AAC 오디오, 웹 최적화 (faststart)- 해상도: 1920×1080 (기본값) 또는 사용자 정의
- 품질: CRF 18 (고품질), AAC 192kbps
훌륭한 데모를 위한 팁
- 스크립트 우선 — 동작보다 내레이션을 먼저 작성하세요. 이야기가 속도를 결정합니다.
- 짧은 장면 — 장면당 8-15초. 간결하게 유지하세요.
- 넉넉한 대기 시간 — 탐색 후 시각적 여유를 위해
> wait 1-2를 추가하세요. - 내레이션과 동작 일치 — 화면에서 일어나는 일을 그대로 설명하세요.
- 인트로/아웃트로 슬라이드 — 전문성을 위해 항상 사용하세요.
- 점진적 테스트 — 먼저 한 장면을 녹화하여 타이밍을 확인한 후 추가하세요.
- 브랜드 일관성 — 인트로/아웃트로 슬라이드 색상은 PoC의 브랜드 팔레트와 일치해야 합니다 (
threadlight-design교차 절단 패턴 1 참조). 빨간색 브랜드 고객에게 기본 파란색/보라색 그라데이션을 사용하지 마세요. PoC의demo-deck.html에서 CSS 사용자 정의 속성을 슬라이드 HTML 파일로 복사하세요. - 자막 — 내레이션 텍스트에서 WebVTT 파일을 생성하세요. 외부
<track src="file.vtt">를 사용하지 마세요 — Edge는file://프로토콜에서 CORS를 차단합니다. 대신 VTT를 인라인 JS Blob URL로 포함시키세요:var blob = new Blob([vttData], {type:'text/vtt'}); track.src = URL.createObjectURL(blob);그리고 동적으로<track>요소를 추가하세요. 타임스탬프는HH:MM:SS.mmm형식을 사용해야 합니다 (MM:SS.mm는 Edge에서 거부됨). - 데크에 포함 — PoC가
demo-deck.html을 제공하는 경우, 라이브 데모 보류 카드에 비디오를 대체 콘텐츠로 포함시키세요.V키 토글을 구현하세요: V를 누르면.is-cue슬라이드에서 비디오가 인라인으로 재생되고, 다시 V를 누르면 중지됩니다. 발표자가 키보드 단축키에만 의존하지 않도록 가시적인 제어 막대 (재생/일시 정지 버튼 + 클릭 가능한 진행 막대 + 시간 표시)를 추가하세요.ended이벤트에서 자동 중지하세요. 대체 텍스트 힌트 ("V를 누르면 사전 녹화된 대체 콘텐츠 재생")는 낮은 불투명도로 큐 텍스트 아래에 표시됩니다.
에이전트 데모 녹화 (전투 테스트 완료 패턴)
이 섹션은 Foundry 호스팅 에이전트 PoC에서 6번의 실패한 녹화 시도에서 추출되었습니다. 아래 패턴은 에이전트 응답 시간이 불규칙한 경우(10-50초)에 시청 가능한 비디오를 안정적으로 생성하는 유일한 접근 방식입니다.
문제
AI 에이전트 데모는 실시간으로 녹화할 수 없습니다. 에이전트가 응답하는 데 10-50초가 걸립니다. 브라우저를 계속 녹화하고 사전 생성된 내레이션 오디오를 오버레이하면, 화면에 "작업 중..."이 표시되는 동안 음성이 답변을 설명합니다. 포스트 프로덕션 속도 증가나 오디오 이동으로는 이 문제를 안정적으로 해결할 수 없습니다 — 두 타임라인이 근본적으로 동기화되지 않습니다.
해결책: 장면당 스크린샷 점프컷
비디오에 "작업 중..."을 절대 표시하지 마세요. "질문 입력됨"에서 "답변 렌더링됨"으로 바로 점프컷하세요. 에이전트 대기 시간은 스크린샷 사이에서 오프 카메라로 발생합니다.
장면별 워크플로우:
- 프롬프트 입력 → 입력된 상태의 스크린샷 (내레이터가 이 프레임 위에서 질문을 소개함)
- "질문" 클릭 → 응답이 완전히 렌더링될 때까지 폴링 (오프 카메라 — 녹화 안 함)
- 완료된 답변의 스크린샷 (내레이터가 이 프레임 위에서 응답을 설명함)
- 세그먼트 빌드: 정지 이미지 + 일치하는 내레이션 오디오 클립 (정확한 길이 일치)
- 모든 세그먼트 연결: 인트로 → K1입력됨 → K1완료 → K2입력됨 → K2완료 → … → 아웃트로
스마트 대기 — 나타남→사라짐 폴링:
# 1단계: 로딩 표시기가 나타날 때까지 대기 (API 호출 시작 확인)
for _ in range(30):
if await page.evaluate("() => !!document.body.innerText.match(/작업중/)"):
break
await page.wait_for_timeout(500)
# 2단계: 로딩 표시기가 사라질 때까지 대기 (응답 렌더링 확인)
for _ in range(120):
if not await page.evaluate("() => !!document.body.innerText.match(/작업중/)"):
break
await page.wait_for_timeout(1000)
await page.wait_for_timeout(2000) # DOM 안정화 대기
정규식 (/작업중/)을 작업 공간에서 사용하는 로딩 표시기에 맞게 조정하세요. 2단계 패턴은 스크립트가 "작업 중..."이 나타나기도 전에 확인하고 즉시 진행하는 일반적인 버그를 방지합니다.
정지 이미지 + 오디오로 세그먼트 빌드:
def make_segment(image_path, audio_path, output_path):
audio_dur = ffprobe_duration(audio_path)
subprocess.run([
"ffmpeg", "-y",
"-loop", "1", "-i", str(image_path),
"-i", str(audio_path),
"-c:v", "libx264", "-preset", "fast", "-crf", "18",
"-c:a", "aac", "-b:a", "192k",
"-t", str(audio_dur),
"-pix_fmt", "yuv420p",
"-movflags", "+faststart", str(output_path),
], check=True)
각 세그먼트의 길이는 내레이션 오디오 길이와 같습니다 — 내레이터는 항상 화면에 보이는 것을 설명합니다.
안티 패턴 (Foundry 호스팅 에이전트 PoC에서 6번의 실패한 녹화 시도에서)
| ❌ 접근 방식 | 실패 이유 |
|---|---|
| 연속 녹화 후 오디오 오버레이 | 오디오와 비디오 타임라인이 절대 일치하지 않음 — 화면에 "작업 중..."이 표시되는 동안 내레이터가 인용에 대해 이야기함 |
setpts로 "작업 중..." 비디오 부분 속도 증가 | 어색해 보임; 속도 증가율은 불규칙한 에이전트 응답 시간에 따라 달라짐 |
스크립트의 고정 > wait 35 타이머 | 에이전트 응답 시간은 10-50초; 고정 타이머는 답변을 자르거나 30초 동안 아무것도 표시하지 않음 |
| 실시간으로 비디오 + 오디오 동시 녹화 | Playwright는 시스템 오디오를 캡처할 수 없음; 헤드리스 Chromium에는 오디오 장치가 없음 |
| 오디오 이동 감지로 포스트 프로세싱 | 너무 취약함; "작업 중..." 텍스트는 DOM에 나타나지만 시각적 로딩 스피너는 작업 공간마다 다름 |
에이전트 데모를 위한 음성 선택
영국 청중을 위한 PoC에는 영국 음성 (en-GB-SoniaNeural)을 사용하세요 — 데모 속도에서 자연스럽게 읽히며 전문적인 분위기와 일치합니다. 규제 산업 (금융 서비스, 통신, 의료) 데모에는 미국 캐주얼 음성을 피하세요.
파일 위치
글로벌 Copilot CLI 스킬로 활성화되면 스크립트는 다음 위치에 있습니다:
~/.copilot/skills/auto-demo-producer/scripts/record_demo.py~/.copilot/skills/auto-demo-producer/scripts/generate_slides.py
프로젝트 디렉토리로 복사한 후 실행하거나, 직접 참조하세요.
전제 조건
- **Python 3.10+**와
pip - edge-tts —
pip install edge-tts(무료 Microsoft Neural TTS) - Playwright —
pip install playwright && playwright install chromium - ffmpeg — 시스템 바이너리 (위 설치 명령어 참조)