Communitygithub.com

funi-ai/demo-video

사용자의 실제 화면 녹화 영상에서 제품 데모, 스토어 프리뷰, App Store 헤더/검색 영상, GIF 루프를 생성합니다. 로컬 ffmpeg를 사용하여 트리밍, 속도 조절, 확대/축소, 프레이밍, 자막 추가, 음성 더빙을 처리하며, Eleven v3, Gemini TTS 등 모델은 제품 외적인 요소(내레이션, 배경 음악, UI 사운드)만 생성합니다.

demo-video란 무엇인가요?

이 스킬은 사용자의 실제 화면 녹화 영상을 기반으로 제품 데모, 스토어 프리뷰, App Store 헤더/검색 영상, Google Play 홍보 영상, Product Hunt 런칭 영상, GIF 루프 등을 제작하는 AI 에이전트 스킬입니다. 핵심 원칙은 앱 인터페이스를 절대 재생성하거나 수정하지 않는다는 점으로, 녹화 영상 그대로를 사용하여 트리밍, 속도 조절, 확대/축소, 프레이밍, 자막 추가, 음성 더빙 등 편집 작업만 수행합니다. 로컬 ffmpeg를 사용해 정밀하고 무료로 편집하며, 내레이션(Eleven v3, 터키어는 Gemini TTS), 배경 음악, UI 사운드와 같은 제품 외적인 요소만 모델을 통해 생성합니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 코딩 도구에서 사용할 수 있으며, 하나의 `cut.json` 파일에 녹화 영상, 장면 순서, 변형을 저장하고 `democut.py` 스크립트가 이를 처리하여 MP4, WebM, GIF, SRT/VTT 자막 파일, 포스터 이미지를 출력합니다. 작업 흐름은 녹화 영상 수집 및 분석, 컷 카드(장면 목록) 제시 후 사용자 승인, 내레이션 생성 및 시간 측정, 컷 편집, 렌더링, 결과 검증 및 전달 순서로 진행됩니다. 중요한 것은 사용자의 질문은 최대 2개로 제한되며, 컷 카드를 승인 받기 전까지는 어떤 생성이나 렌더링도 수행하지 않습니다. 또한 사용자의 개인 데이터가 포함된 프레임은 블러 처리 대신 다시 녹화하도록 요청하며, 평점, 사용자 수, 상, 고객 이름, 로고 등은 사용자가 직접 제공한 경우에만 사용합니다. 마지막으로, 모든 편집은 로컬에서 이루어지며 생성 비용은 USD 0이고, 모델 사용 시에만 예상 비용을 미리 알리고 사용자의 명시적 승인을 받습니다.

지원 대상✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/funi-ai/claude-plugins/tree/main/plugins/genmedia-skills/skills/demo-video

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

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

문서

데모 비디오

사용자의 실제 화면 녹화를 기반으로 제작되는 제품 데모, 스토어 프리뷰 또는 기능 루프입니다. 인터페이스는 절대 재생성되지 않습니다. 녹화 영상은 트리밍, 속도 조절, 확대/축소, 프레이밍, 자막 및 음성 처리를 거칩니다. Apple은 프리뷰에 대해 동일한 규칙을 명시하고 있습니다(2.3.4: 앱 자체의 비디오 화면 캡처, 내레이션 및 오버레이 허용). 하나의 cut.json 파일이 녹화 영상, 장면 순서 및 변형을 저장하며, democut.py가 이를 로컬 ffmpeg를 사용하여 파일로 변환합니다. 재편집은 무료입니다.

0단계 — 사전 점검

세션당 한 번:

python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" tools
  • kind: "ffmpeg_missing" → 로컬에서 편집이 불가능합니다. 이 사실을 알리고 references/routing-utility.md에 있는 유료 유틸리티 경로를 제안하거나 사용자에게 ffmpeg 설치를 요청하세요. 다른 도구로 임시 방편을 사용하지 마십시오.
  • can.burn_captions(libass), can.duck(사이드체인 컴프레서), can.webm 상태를 확인하세요. 누락된 기능은 약속하는 내용을 변경할 뿐, 주장하는 내용을 변경하지 않습니다.
  • 무언가 생성될 때만(내레이션, 음악, 사운드, 더빙, 플레이트):
    command -v genmedia
    python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" preflight
    
    blockers가 비어 있지 않거나, CLI가 없거나 0.7.0보다 오래된 경우 → /genmedia-skills:setup. 키가 없는 경우 → 사용자가 직접 genmedia setup을 실행하거나 FAL_KEY를 내보내도록 안내하고 기다리세요. 키를 읽거나, 출력하거나, 요청하거나, 입력하지 마십시오. config.announce_above_usd와 config.confirm_above_usd(기본값 0.50 및 2)를 유지하세요.
  • 먼저 이어서 작업: .genmedia/projects/<slug>/demo-video/cut.json이 존재하는 경우 → 해당 내용을 이어서 작업하고, 동일한 제품에 대해 두 번째 컷을 시작하지 마십시오.

UX 규칙

  1. 사용자 언어로 응답하세요. 내레이션, say 라인 및 화면 텍스트는 제공된 언어를 유지하며, 모델 프롬프트는 영어를 사용합니다. 경로, ID 및 필드 이름은 변경하지 마십시오.
  2. JSON, 필터 그래프, 요청 ID 또는 도구 설명을 채팅에 표시하지 마십시오. 각 긴 단계당 최대 한 줄의 상태 메시지만 표시하세요.
  3. 질문 예산: 2개, 한 번에 하나씩, 선택지를 표시하고, 답변이 누락된 경우에만 질문하세요:
    • Q1 녹화 영상: 파일이 제공되지 않은 경우, 경로를 묻고 references/recording-tips.md의 짧은 캡처 목록을 제공하세요. 영상에 대한 기본값은 없습니다.
    • Q2 용도: 요청에 명시되지 않은 경우: A 웹사이트 데모(16:9) · B App Store 프리뷰 · C App Store 헤더 또는 검색 결과 영상 · D Google Play 홍보 · E Product Hunt 런칭 영상 · F 무음 루프 또는 GIF. 여러 개 선택 가능하며, 하나의 컷으로 모든 용도를 처리합니다. 그 외 모든 것은 전달 시 명시하는 기본값을 따릅니다: 데모는 60초, 스토어 프리뷰는 20초, App Store 헤더 또는 검색 영상은 12초, 루프는 6초; 데모는 내레이션 켜짐, 루프 또는 헤더/검색 영상은 꺼짐; 음악은 요청 시에만; 자막은 사이드카 파일; 컷(디졸브 아님); 스토어 또는 소셜 대상이 원하지 않는 한 기기 프레임 없음.
  4. 컷 카드는 하드 스탑입니다. 장면 목록(시간, 내용, 대사, 길이)을 보여주고 생성이나 렌더링 전에 승인을 기다리세요. 침묵은 승인이 아니며, 이전 버전에 대한 승인은 현재 버전에 대한 승인이 아닙니다.
  5. 그림보다 내레이션을 먼저. 장면별로 음성을 생성하고, time이 길이를 측정하게 한 다음, 그림을 음성에 맞춰 자르세요. 문장 길이를 추측하여 장면 시간을 정하지 마십시오(references/narration-and-audio.md).
  6. 전달하기 전에 확인하세요. 완성된 파일의 포스터 프레임과 콘택트 시트를 읽고, GIF의 첫 번째 프레임을 읽으세요. 검증을 통과했지만 잘못된 화면을 보여주는 데모는 여전히 잘못된 것입니다.
  7. 사실과 개인 정보는 사용자에게서 비롯됩니다. 평점, 수, 상, 고객 이름 및 로고는 사용자가 제공한 경우에만 나타납니다. 프레임에 실제 데이터가 표시되면 블러 처리 대신 새 녹화를 요청하고, 명확히 말하세요.
  8. 비용: 컷, 프레임, 루프 및 모든 검사는 USD 0입니다. 생성 전에 사전 점검에서 게이트를 추정하고 적용하세요: announce_above_usd 미만 → 실행하고 명시; confirm_above_usd까지 → 한 줄 메시지 후 실행; 초과 → 명시적 승인. 기억에서 가격을 인용하지 마십시오.
  9. 제한: 단계당 최대 3번의 수리 시도, 매번 변경 사항이 있어야 함; 콘텐츠 정책 거절은 변경 없이 재전송하지 않음; 요청 ID가 있는 작업은 재시작하며 재제출하지 않음.

발견 가드레일

scripts/video-surfaces.json은 날짜가 기록된 캐시입니다(verified_on, democut.py specs로 읽음): null은 공식 페이지에서 아무도 읽지 않은 숫자이며, 절대 기억에서 채우지 말고, 스토어에서 파일을 거부하면 공식 페이지가 우선하며 행이 수정됩니다.

세션에서 유료 엔드포인트에 처음 호출하기 전:

genmedia models --endpoint_id <endpoint_id> --json
python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" schema <endpoint_id>

status는 active여야 합니다. 필드, 열거형 및 제한은 스키마에서 가져옵니다. 활성 상태가 아닌 경우 → references/routing-audio.md에서 해당 작업의 다음 단계로 이동합니다. 엔드포인트 ID 대신 프롬프트로 genmedia run을 실행하지 마십시오. 새 릴리스는 fal-ai/ 네임스페이스뿐만 아니라 벤더 네임스페이스 아래에 있습니다.

라우팅

필요방법이유
트리밍, 속도, 확대/축소, 프레이밍, 결합, 오버레이, 믹싱, 음량, GIF, 검사democut.py (로컬 ffmpeg)정확하고, 무료이며, 반복 가능; 제품 픽셀이 모델을 통과하지 않음
녹화 또는 결과를 시청하지 않고 확인democut.py analyze, sheet, grab; frames.py sheet추측 대신 탐지기 및 콘택트 시트
내레이션fal-ai/elevenlabs/tts/eleven-v3; 터키어: fal-ai/gemini-3.1-flash-tts기본 TTS; 터키어 경로는 스키마 확인됨
배경 음악, UI 사운드elevenlabs/music/v2.5 (정확한 길이), fal-ai/elevenlabs/sound-effects/v2길이 제어; 저렴한 초당 비용
단어 수준 정확한 자막 타이밍fal-ai/elevenlabs/speech-to-text/scribe-v2 → audiokit.py captions단어 타임스탬프
완성된 파일의 다른 언어 버전fal-ai/elevenlabs/dubbing언어당 한 번 호출
기기 프레임, 엔드 카드, 정확한 화면 내 텍스트/genmedia-skills:launch-graphics (layers, 구성된 PNG)텍스트는 정확한 위치에 구성되며 생성되지 않음
프레임된 기기 뒤 배경 플레이트bytedance/seedream/v5/pro/text-to-image비디오당 하나의 플레이트, 문자 없음
로컬 ffmpeg 없음fal-ai/ffmpeg-api/* in references/routing-utility.md호출당 몇 센트, 대체재이며 기본값 아님

동점자 및 함정:

  1. 인터페이스는 절대 생성, 스타일 변경, 재프레이밍 또는 '향상'되지 않습니다. video-reframe, video-edit 및 업스케일러는 UI 텍스트를 다시 칠합니다: 이는 생성된 영상용이며 녹화용이 아닙니다.
  2. 확대/축소는 소스 프레임의 분수 단위로, grab --grid 또는 sheet --grid로 읽습니다. hold는 세부 정보용, push는 한 번 시선을 유도하기 위해, pull은 한 번 컨텍스트를 드러내기 위해 사용합니다(references/editing.md).
  3. 스토어 프리뷰는 짧은 엔딩이 있는 데모가 아니라, 고유한 장면 하위 집합을 가진 별도의 변형입니다.
  4. Play 및 Product Hunt는 YouTube URL을 사용합니다. 파일을 전달하고 누가 업로드하는지 알리세요.
  5. App Store 헤더 또는 검색 결과 영상(iOS 27 크리에이티브 에셋)은 자체 무음 루핑 변형입니다: appstore-header-video (3840x1646) 또는 appstore-search-video (3:2), 30 또는 60fps, 5-30초, 하나의 아이디어, 2초 이상의 장면, 시작점으로 끝남. Apple은 범용 비디오를 나열하지 않습니다. 정지 이미지는 launch-graphics 작업입니다(references/surfaces.md 섹션 1a).
  6. 전화 녹화는 전화 프레임이 필요합니다. time은 30% 종횡비 불일치를 거부합니다.
  7. can.burn_captions이 true인 경우에만 자막을 비디오에 포함시키고, 그렇지 않으면 사이드카 파일 또는 유료 자막 경로를 사용한다고 명시합니다.
  8. 사용자가 모델을 지명한 경우 → 실시간 확인 후 사용합니다.

워크플로우

  1. 인테이크. 목표, 대상, 녹화 영상, 브랜드. 사용자가 언급한 모든 파일을 읽습니다. 그런 다음 녹화 영상별로:
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" init --slug <slug> --name "<Product>" --target web-16x9
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" source add --slug <slug> --id app --file ./recordings/demo.mov --os desktop
    
    응답에는 크기, fps, 지속 시간, 오디오, 내장된 레터박스 및 종횡비에 맞는 대상이 포함됩니다. 대상보다 작은 녹화 또는 실제 데이터를 표시하는 녹화는 편집 전에 재촬영을 요청합니다(references/recording-tips.md).
  2. 확인.
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" analyze --slug <slug> --source app
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" sheet --slug <slug> --source app --count 12 --cols 4 --grid
    
    시트를 읽습니다. dead_spans 및 keep_spans는 후보일 뿐 편집이 아닙니다: 정지 화면이 때로는 포인트입니다. 확대할 프레임에 대해 grab --at <s> --grid를 사용하세요.
  3. 컷 카드. 순서대로 장면: ID, 소스 in/out, 속도, 확대/축소, 시청자가 보는 것, 음성이 말하는 것, 길이; 그런 다음 변형, 생성되는 것, 사용자에게 필요한 것, 가정. 표시하고, 멈추고, 승인을 기다리세요(references/editing.md).
  4. 내레이션, 측정됨 (데모에 음성이 있는 경우에만). references/narration-and-audio.md 당 하나의 배치 가격을 책정하고 실행하며, 장면당 하나의 파일을 생성한 다음 숫자가 그림을 결정하도록 합니다:
    python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" price fal-ai/elevenlabs/tts/eleven-v3,elevenlabs/music/v2.5 --explain
    python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" batch --plan .genmedia/projects/<slug>/demo-video/voice-plan.json
    
  5. 컷 작성. Write 또는 Edit 도구를 사용하여 .genmedia/projects/<slug>/demo-video/cut.json을 편집합니다: scenes, audio, variants. 모든 필드: references/cut-json.md. 기기 프레임은 launch-graphics layers에서 가져옵니다(references/frames-and-loops.md).
  6. 게이트.
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" time --slug <slug>
    
    렌더링 전에 모든 오류를 수정하세요: scene_shorter_than_voice (스팬을 늘리거나, 속도를 늦추거나, 단어를 자릅니다 — 음성 속도를 높이지 마십시오), duration_out_of_range (스토어 대상), wrong_size, fps_not_allowed, transition_too_long, frame_aspect_mismatch, overlay_invisible. 경고에 따라 조치하거나(quick_cut, fast_motion, narration_muted 크리에이티브 에셋 비디오의 경우) 유지하는 경고를 설명합니다.
  7. 빌드.
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" build --slug <slug>
    
    600000ms Bash 타임아웃. 장면은 콘텐츠별로 캐시됩니다. 개정 시 변경된 부분만 다시 렌더링합니다(--scene <id>, --force). 그런 다음 자막 및 루프:
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" captions --slug <slug> --variant <id> --formats srt,vtt
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" gif --slug <slug> --variant loop-16x9 --budget-mb 3 --seconds 6
    
  8. 결과 확인. 포스터 프레임을 읽고, 완성된 파일의 콘택트 시트를 읽고, GIF의 첫 번째 프레임을 읽으세요:
    python3 "${CLAUDE_SKILL_DIR}/scripts/frames.py" sheet genmedia-output/<slug>/demo-video/<variant>/<slug>.mp4 --count 9 --cols 3
    
    처음 3초, 확대된 프레임(읽을 수 있는지?), 마지막 프레임(안정적인지?), 모든 프레임에서 개인 데이터가 없는지 확인하고, 큐 파일을 글자 단위로 읽으세요.
  9. 검증 및 전달.
    python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" validate --slug <slug>
    
    정확한 크기, fps, 지속 시간이 플랫폼 창 내에 있는지, 코덱 및 프로필, 바이트 제한, 오디오 구성, 측정된 음량 및 실제 피크, 루핑 대상의 경우 이음매(loop_seam). 그런 다음 전달 메시지. 개정: 컷을 편집하고, 다시 빌드하고, 다시 검증하세요.

전달

<Product> 데모: genmedia-output/<slug>/demo-video/
마스터 16:9: web-16x9/<slug>.mp4 (1920x1080, <n> 초) · 포스터 web-16x9/<slug>-poster.png
App Store 프리뷰: appstore-iphone/<slug>.mp4 (886x1920, <n> 초, H.264 High, AAC 256k) <빌드된 경우에만>
App Store 헤더 / 검색 영상: appstore-header-video/<slug>.mov (3840x1646, <n> 초, <fps> fps, 무음 루프) · App Store Connect에서 선택할 포스터 프레임: <t> 초 <빌드된 경우에만>
Play 프로모 / Product Hunt: 동일한 마스터 — 두 플랫폼 모두 YouTube URL을 사용하므로 업로드하고 링크를 붙여넣으세요 <빌드된 경우에만>
루프: loop-16x9/<slug>-loop.mp4 · <slug>-loop.gif (<n> MB, <w>px@<fps>) · 첫 번째 프레임 <slug>-loop-first.png <빌드된 경우에만>
자막: <variant>/<slug>.srt, .vtt (<language>) <빌드된 경우에만> · manifest.json
녹화 영상, 변경되지 않음: 컷, <기다린 부분은 속도 조절됨>, <내용>에 확대/축소, <그려진 기기에 프레임됨>. 인터페이스는 재생성되지 않았습니다.
사용자를 위해 선택됨: <길이, 장면 수, 내레이션 켜기/끄기, 음악, 자막, 프레임, 맞춤 — 사용자가 설정하지 않은 모든 기본값>
스토어 참고 사항: <해당되는 각 항목별 한 줄: App Store 프리뷰는 15-30초, 기기당 최대 3개, 화면 캡처만 가능(2.3.4) · 헤더 및 검색 영상은 음소거 루프(검색: 절대 음소거 해제 안 됨), iOS 27 및 iPadOS 27 이상에서 표시, 승인되면 포스터 프레임 고정 · Play 프로모의 처음 30초만 자동 재생 · Product Hunt 이미지(GIF 포함)는 3MB 미만 유지, GIF는 호버 시 애니메이션>
생성됨: <없음, USD 0 | 내레이션 <n> 라인 (<model>), 음악, 약 USD <x>> · 파일은 로컬에 있습니다. 아무것도 업로드되지 않았습니다.
다음: 변경할 장면과 내용(in/out, 속도, 확대/축소, 단어)을 지정하세요. 재편집은 무료입니다.

번역하세요. 경로, 크기 및 화면 텍스트는 변경하지 마십시오.

오류

신호수행
kind: "ffmpeg_missing"로컬 ffmpeg 없음. 여기서는 컷을 만들 수 없다고 말하고, fal ffmpeg-api 경로(references/routing-utility.md)를 제안하거나 사용자에게 설치를 요청하세요.
source_changed녹화 영상이 이동하거나 변경됨. source add --replace를 사용한 다음 모든 in/out을 다시 확인하세요. 이전 타이밍은 더 이상 의미가 없습니다.
time에서 check_failed각 항목은 장면과 숫자를 명명합니다. 컷을 수정하세요. 오류가 있는 동안에는 아무것도 렌더링되지 않습니다.
scene_shorter_than_voice스팬을 늘리거나, speed를 낮추거나, 단어를 자르세요. 음성 속도를 높여 맞추지 마십시오.
duration_out_of_range공식 창을 놓쳤습니다(App Store 프리뷰 15-30초, 헤더 및 검색 영상 5-30초). 해당 변형에 대해서만 장면을 삭제하거나 단축하세요.
wrong_size, fps_not_allowed, fps_too_high변형의 크기 또는 fps가 해당 행을 위반합니다. 재정의를 삭제하거나 행이 허용하는 값을 선택하세요(specs).
validate에서 loop_seam루프가 다시 시작될 때 점프합니다. 시작 상태로 끝나거나 동일한 영역을 유지하고, 빌드하고, 다시 검증하세요.
frame_aspect_mismatch기기 프레임의 종횡비가 소스와 일치하지 않습니다. 올바른 프레임 ID를 사용하고 있는지 확인하세요.
language_not_supported언어가 TTS 또는 더빙 모델에서 지원되지 않습니다. 사용자에게 알리고 지원되는 언어를 제안하세요.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

funi-ai/ads

Ads from the user's REAL product: UGC and polished ad videos (presenter, unboxing, showcase, testimonial, TV spot) and static ads with copy. Physical products: keyframes locked to the product photo, Seedance clips or TTS + OmniHuman, GPT Image 2.5 copy. Apps and SaaS: real captures and recordings, composited, never regenerated. Use when: "make a UGC ad for this product", "15 second TikTok ad", "static ad with this headline", "app install ad from my screen recording", "A/B ad variants", "bu ürün için reklam videosu yap", "uygulamam için reklam hazırla", "indirim görseli hazırla". Chain: consumes `product-photoshoot` stills, `character` @handles, `launch-graphics` pages; produces ads and a manifest. NOT for: text-free product photos (use `product-photoshoot`); posters (use `image`); listing cards (use `marketplace-cards`); store screenshots, OG cards (use `launch-graphics`); one clip (use `video`); organic shorts (use `short-video`); product demos (use `demo-video`); thumbnails (use `youtube-thumbnail`).

funi-ai/youtube-thumbnail

Thumbnails and covers that survive at small size: YouTube thumbnails (16:9), Shorts, Reels and TikTok covers (9:16), podcast and course covers (1:1), from a title plus an optional face photo, @handle character, brand colours or a frame of the user's own video. Text baked in by GPT Image 2.5; faces locked through reference edits. Use when: "make a thumbnail for my video", "YouTube thumbnail with my face", "Shorts cover", "podcast cover art", "thumbnail from this frame", "change only the text on the thumbnail", "videoma thumbnail yap", "kapak görseli hazırla", "küçük resimdeki yazıyı değiştir". Chain: consumes an @handle from `character` and stills or frames from `image` and `video`; produces sized PNG and JPEG. NOT for: posters, photo edits (use `image`); logos (use `brandkit`); link cards, OG images (use `launch-graphics`); ad creatives (use `ads`); the video (use `video`, `short-video`); new characters (use `character`); batches (use `pipelines`); model choice (use `models`); setup problems (use `setup`).

관련 스킬