Communitygithub.com

gabelul/stitch-kit

Stitch 프로젝트에서 Remotion을 사용해 워크스루 비디오를 생성합니다. Stitch 화면에서 스크린샷을 다운로드하고, 전환 효과와 텍스트 오버레이가 있는 Remotion 컴포지션을 빌드한 후 MP4로 렌더링합니다. 화면 탐색에는 stitch-mcp-list-screens 및 stitch-mcp-get-screen을 함께 사용하세요.

stitch-kit란 무엇인가요?

이 스킬은 Stitch 앱 디자인에서 워크스루 비디오를 제작하는 비디오 프로덕션 도구입니다. Stitch MCP 서버에서 스크린샷을 검색하고, Remotion을 사용하여 슬라이드 전환, 줌 애니메이션 및 텍스트 오버레이가 포함된 컴포지션을 생성한 후 MP4로 렌더링합니다. 사용자는 Stitch 프로젝트의 화면 목록을 가져오고, 각 화면의 스크린샷을 다운로드한 후, screens.json 매니페스트를 작성하여 비디오 시퀀스를 정의합니다. 이 스킬은 Remotion CLI와 @remotion/transitions 패키지를 활용하여 매끄러운 페이드 및 슬라이드 전환을 구현하며, 각 화면에 제목과 설명을 오버레이할 수 있습니다. 빠른 데모, 기능 워크스루, 프레젠테이션 데크, 소셜 미디어 클립 등 다양한 비디오 스타일을 지원하며, Jaykef/screenshot 및 Remotion 기반 워크플로우를 이미 사용하고 있는 개발자에게 특히 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gabelul/stitch-kit/tree/HEAD/skills/stitch-remotion

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

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

문서

Stitch → Remotion 워크스루 비디오

제약사항: 사용자가 명시적으로 "Stitch"와 워크스루 비디오, 데모 또는 Remotion을 언급할 때만 이 스킬을 사용하세요.

당신은 Stitch 앱 디자인에서 워크스루 비디오를 제작하는 비디오 제작 전문가입니다. Stitch 스크린샷을 검색하고 Remotion 컴포지션(슬라이드 전환, 줌 애니메이션, 텍스트 오버레이)을 빌드합니다.

사전 요구사항

  • Stitch MCP 서버 (또는 이미 알려진 스크린 ID)
  • Node.js 18+ 및 npm
  • Remotion CLI (npm install -g remotion 또는 npx 사용)

1단계: Stitch 에셋 수집

스크린 탐색

  1. list_tools 실행 → Stitch MCP 접두사 찾기
  2. [prefix]:list_projects 호출 → 프로젝트 선택
  3. [prefix]:list_screens 호출 projects/[projectId] → 모든 스크린 나열
  4. 비디오에 포함할 각 스크린에 대해 숫자 ID로 [prefix]:get_screen 호출

스크린샷 다운로드

각 스크린에 대해:

# assets 디렉토리로 스크린샷 다운로드
curl -L "[screenshot.downloadUrl]" -o "video/public/assets/[screen-name].png"

또는 fetch 스크립트 사용:

bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/[screen-name].html"
# 스크린샷은 별도 — 스크린샷 URL로 curl을 통해 다운로드

스크린 매니페스트 생성

비디오를 설명하는 screens.json 생성:

{
  "projectName": "내 앱",
  "fps": 30,
  "screens": [
    {
      "id": "home",
      "title": "홈 화면",
      "description": "주요 지표가 있는 메인 대시보드",
      "imagePath": "./public/assets/home.png",
      "width": 390,
      "height": 844,
      "durationSeconds": 4
    },
    {
      "id": "profile",
      "title": "사용자 프로필",
      "description": "설정 및 계정 관리",
      "imagePath": "./public/assets/profile.png",
      "width": 390,
      "height": 844,
      "durationSeconds": 3
    }
  ]
}

2단계: Remotion 프로젝트 설정

# 작업 디렉토리 내에 새 Remotion 프로젝트 생성
cd video
npm create video@latest -- --blank
cd walkthrough-video
npm install @remotion/transitions

3단계: 컴포지션 빌드

ScreenSlide 컴포넌트

// video/src/ScreenSlide.tsx
import { AbsoluteFill, Img, interpolate, spring, useCurrentFrame, useVideoConfig } from 'remotion'

interface ScreenSlideProps {
  /** 스크린샷 이미지 경로 */
  imagePath: string
  /** 오버레이로 표시될 화면 제목 */
  title: string
  /** 설명 텍스트 */
  description: string
  /** 표시 중 약간 줌할지 여부 */
  withZoom?: boolean
}

/**
 * 선택적 줌 효과와 텍스트 오버레이가 있는 단일 화면 슬라이드.
 * 페이드 인, 유지, 페이드 아웃.
 */
export function ScreenSlide({ imagePath, title, description, withZoom = true }: ScreenSlideProps) {
  const frame = useCurrentFrame()
  const { fps, durationInFrames } = useVideoConfig()

  // 처음 15프레임 동안 페이드 인
  const fadeIn = spring({ fps, frame, config: { damping: 200 } })

  // 미세 줌: 100% → 105% (전체 지속 시간 동안)
  const scale = withZoom
    ? interpolate(frame, [0, durationInFrames], [1, 1.05], { extrapolateRight: 'clamp' })
    : 1

  return (
    <AbsoluteFill style={{ backgroundColor: '#000' }}>
      {/* 스크린샷 */}
      <AbsoluteFill style={{ opacity: fadeIn, transform: `scale(${scale})`, transformOrigin: 'center' }}>
        <Img src={imagePath} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
      </AbsoluteFill>

      {/* 하단 텍스트 오버레이 */}
      <AbsoluteFill
        style={{
          justifyContent: 'flex-end',
          padding: '40px 60px',
          background: 'linear-gradient(transparent, rgba(0,0,0,0.7))',
          opacity: fadeIn,
        }}
      >
        <h2 style={{ color: '#fff', fontSize: 36, fontWeight: 700, margin: 0 }}>{title}</h2>
        {description ? (
          <p style={{ color: 'rgba(255,255,255,0.8)', fontSize: 20, margin: '8px 0 0' }}>
            {description}
          </p>
        ) : null}
      </AbsoluteFill>
    </AbsoluteFill>
  )
}

워크스루 컴포지션

// video/src/WalkthroughComposition.tsx
import { Series, TransitionSeries } from '@remotion/transitions'
import { fade } from '@remotion/transitions/fade'
import { slide } from '@remotion/transitions/slide'
import screensData from '../../screens.json'
import { ScreenSlide } from './ScreenSlide'

const TRANSITION_FRAMES = 15  // 30fps에서 0.5초

/**
 * 메인 워크스루 컴포지션 — 각 화면당 하나의 슬라이드, 페이드/슬라이드 전환.
 */
export function WalkthroughComposition() {
  return (
    <TransitionSeries>
      {screensData.screens.map((screen, i) => (
        <>
          <TransitionSeries.Sequence
            key={screen.id}
            durationInFrames={screen.durationSeconds * screensData.fps}
          >
            <ScreenSlide
              imagePath={screen.imagePath}
              title={screen.title}
              description={screen.description}
            />
          </TransitionSeries.Sequence>
          {/* 화면 간 전환 추가 (마지막 이후 제외) */}
          {i < screensData.screens.length - 1 && (
            <TransitionSeries.Transition
              key={`t-${screen.id}`}
              timing={fade({ durationInFrames: TRANSITION_FRAMES })}
            />
          )}
        </>
      ))}
    </TransitionSeries>
  )
}

Root.tsx에 등록

// video/src/Root.tsx
import { Composition } from 'remotion'
import { WalkthroughComposition } from './WalkthroughComposition'
import screensData from '../../screens.json'

const TOTAL_FRAMES = screensData.screens.reduce(
  (acc, s) => acc + s.durationSeconds * screensData.fps,
  0
)

export const RemotionRoot = () => (
  <>
    <Composition
      id="Walkthrough"
      component={WalkthroughComposition}
      durationInFrames={TOTAL_FRAMES}
      fps={screensData.fps}
      width={screensData.screens[0]?.width ?? 390}
      height={screensData.screens[0]?.height ?? 844}
    />
  </>
)

4단계: 미리보기 및 렌더링

# 브라우저에서 미리보기
cd video/walkthrough-video
npm run dev

# MP4로 렌더링
npx remotion render Walkthrough output.mp4

# 고품질 렌더링
npx remotion render Walkthrough output.mp4 --jpeg-quality 95 --concurrency 4

일반적인 비디오 스타일

스타일구성
빠른 데모 (1–2분)화면당 2–3초, 페이드 전환, 제목만
기능 워크스루화면당 4–5초, 줌 + 슬라이드, 제목 + 설명
프레젠테이션 데크화면당 5–8초, 페이드만, 전체 설명 오버레이
소셜 미디어 클립화면당 1–2초, 빠른 컷, 음악 트랙

파일 구조

project/
├── screens.json             ← 화면 매니페스트
├── scripts/fetch-stitch.sh  ← GCS 다운로더
└── video/
    ├── public/
    │   └── assets/          ← 다운로드된 스크린샷
    └── walkthrough-video/
        ├── src/
        │   ├── WalkthroughComposition.tsx
        │   ├── ScreenSlide.tsx
        │   └── Root.tsx
        ├── remotion.config.ts
        └── package.json

문제 해결

문제해결책
흐릿한 스크린샷전체 해상도 다운로드: 썸네일이 아닌 스크린샷 URL 직접 사용
레이아웃 불일치Remotion 컴포지션 크기를 get_screen에서 얻은 스크린의 width + height와 일치시킴
전환 효과가 어색함TRANSITION_FRAMES 증가 또는 slide에서 fade로 변경
ESM에서 빌드 실패package.json에 "type": "module" 추가 및 Remotion 버전 호환성 확인
MP4 재생 안 됨FFmpeg 설치 확인: ffmpeg -version

참고 자료

관련 스킬