Install
$ agentstack add skill-bam-bam-2-solo-skills-web-demo-video ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
웹 데모 영상 만들기
사용자의 웹 프로젝트(모자이크, 커뮤니티앱, 카공메이트 등) 소개 영상을 만들 때 쓰는 절차. 목업 이미지를 이어붙이는 게 아니라 실제 사이트를 실제로 조작한 화면을 찍는 게 핵심이다.
먼저 물어볼 것
영상은 어디 쓰느냐로 비율·길이가 갈린다. 만들기 전에 반드시 확인한다.
| 용도 | 비율 | 길이 | |---|---|---| | 스레드·릴스·쇼츠 | 9:16 (1080x1920) | 15~25초 | | 블로그·유튜브 임베드·랜딩 | 16:9 (1920x1080) | 30~40초 | | 인스타 피드·카톡 공유 | 1:1 (1080x1080) | ~20초 |
사용자는 시각 산출물의 형식에 구체적인 기대가 있다. 레퍼런스가 있으면 먼저 달라고 한다.
절차
1. 로컬 서버로 대상 사이트를 띄운다
cd && python3 -m http.server 8899
무대(stage) 페이지와 대상 사이트는 반드시 같은 오리진이어야 한다. 포트가 다르면 iframe.contentDocument 접근이 막혀서 조작이 불가능하다. → 무대 파일을 프로젝트 폴더 안에 임시로 두고, 작업이 끝나면 반드시 빼낸다(안 그러면 다음 배포에 딸려 올라간다).
2. 무대 페이지를 만든다
assets/stage-template.html를 복사해서 고친다. 구조:
#stage— 출력 비율 그대로의 고정 크기 div (1:1이면 540x540, dpr 2로 캡처하면 1080x1080)#cap/#foot— 큰 자막(상단) / 보조 문구(하단)#win— 맥 브라우저 창 목업(신호등 3개 + URL) 안에 `을transform: scale()`로 축소해 넣음#cursor— 가짜 마우스 커서 SVG. 이게 있어야 조작 영상처럼 보인다#ring— 클릭·브러시 크기를 보여주는 하이라이트 원#end— 엔딩 카드(제품명 / 한줄 설명 / 셀링포인트 3개 / URL)window.__tick(frameIndex)— 프레임 번호 하나를 받아 그 시점의 화면 상태를 만드는 결정론적 함수
3. 타임라인을 결정론적으로 짠다
__tick(frame) 안에서 t = frame / FPS로 시간을 계산하고, 모든 상태를 t로부터 다시 계산한다. 실시간 setTimeout을 쓰면 캡처 속도와 어긋나서 망가진다.
- 1회성 동작(이미지 로드, 모드 전환)은
once(key, fn)으로 중복 실행을 막는다 - 드래그는
drag(t, 시작초, 끝초, ptFn)— 시작 프레임에mousedown, 매 프레임mousemove, 끝나면mouseup - 이벤트는 iframe의
W.MouseEvent로 만들어clientX/clientY(iframe 기준 좌표)로 dispatch한다.
mousedown은 대상 요소에, mousemove/mouseup은 보통 window에 붙어 있으니 확인하고 각각 맞는 타깃에 쏜다
- 좌표는 하드코딩하지 말고 요소의
getBoundingClientRect()또는 그려넣은 목업의 rect 비율로 계산한다. 창 크기를 바꿔도 안 깨진다 - iframe 안에서 영상에 불필요한 요소(헤더, SEO 본문, 푸터, 광고 배너, 상태줄)는
iframeload 시점에 `` 주입으로 숨긴다
4. 프레임을 캡처한다
for (let i = from; i __tick(f), i);
const buf = await page.screenshot({ clip: { x:0, y:0, width:540, height:540 } });
await fs.writeFile(`${DIR}/f${String(i).padStart(4,'0')}.png`, buf);
}
clip은 CSS 픽셀 단위다. devicePixelRatio를 곱하면 안 된다. dpr 2면 540 클립이 1080px 이미지로 나온다- 프레임 한 장에 약 0.09초. 400장이면 40초 → REPL 120초 제한 때문에 100~150장씩 나눠 호출한다
- 캡처 시작 전에 페이지를 새로 로드해 상태를 초기화하고,
__tick(0)후 이미지 로드가 끝날 시간을 준다
5. ffmpeg로 합성한다
ffmpeg는 PATH에 없다. export PATH="$PATH:/opt/homebrew/bin" 를 붙인다.
ffmpeg -y -framerate 20 -i frames/f%04d.png \
-vf "scale=1080:1080:flags=lanczos,fps=30" \
-c:v libx264 -profile:v high -pix_fmt yuv420p -crf 20 -movflags +faststart out.mp4
-pix_fmt yuv420p는 SNS 호환 필수- 채팅에 붙여 보여줄 미리보기 GIF는 palettegen/paletteuse 2패스로:
fps=10,scale=420:-1:flags=lanczos,palettegen=stats_mode=diff → paletteuse=dither=bayer:bayer_scale=3
- 콘티 확인용 컨택트시트:
select='eq(n\,20)+...',scale=340:340,tile=3x3
6. 뒷정리
- 무대 파일을 프로젝트 폴더 밖으로 옮긴다 (배포에 섞이면 안 됨)
- 로컬 서버 종료:
lsof -ti:8899 | xargs kill -9 - 캡처 탭 닫기
주의
- 영상에 쓰는 예시 데이터(대화 내용, 이름, 계좌번호, 전화번호, 주소)는 전부 지어낸 가짜로 만들고, 보고할 때 가짜라고 명시한다. 사용자의 실제 개인정보(전세금 등)나 제3자 정보는 절대 넣지 않는다
- 무음이 기본. 음악이 필요하면 사용자에게 확인받는다
- 완성본은 세션 artifacts에 두되, 다시 뽑을 수 있도록 무대 파일을 영구 경로에 보관한다
부록 · 블로그 본문용 GIF (브라우저 목업 없이)
SNS 영상과 목적이 다르다. 블로그 독자는 "이 도구가 뭘 하는지"를 3초 안에 봐야 하므로, 맥 브라우저 창 목업·엔딩 카드 없이 작업 대상만 크게 보여주는 편이 낫다. 무대(stage) 페이지도 로컬 서버도 필요 없다. 배포된 사이트를 직접 조작하고 캔버스를 그대로 뜬다.
절차
- 배포 사이트를 열고 예시 이미지를 붙여넣기 이벤트로 주입한다(파일 선택 UI를 거치지 않아도 된다).
``js await page.evaluate(async (b64) => { const blob = await (await fetch('data:image/png;base64,'+b64)).blob(); const dt = new DataTransfer(); dt.items.add(new File([blob],'s.png',{type:'image/png'})); document.dispatchEvent(new ClipboardEvent('paste',{clipboardData:dt,bubbles:true})); }, b64); ``
- 영상에 불필요한 요소는 캡처 전에 숨긴다 (
adInCanvas같은 광고 영역). - 좌표는 반드시 픽셀로 탐지한다. 눈대중 금지. 이번에 눈대중으로 잡았다가 펜·채우기가 엉뚱한 데
찍혀서 세 번 다시 찍었다. 캔버스 픽셀을 직접 훑어 대상 글자의 bbox를 구한다. ``js const bbox = (x0,x1,y0,y1) => { /* 어두운 픽셀(r,g,b + loading="lazy" + 캡션에 "예시 데이터는 전부 가짜"를 명시
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: bam-bam-2
- Source: bam-bam-2/solo-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.