Communitygithub.com

video-to-shorts

원본 동영상에서 이해된 스크립트를 기반으로 숏츠 후보를 계획하고, 최종 동영상에서 수평 및 수직 숏츠를 추출합니다.

video-to-shorts란 무엇인가요?

이 스킬은 긴 동영상에서 숏츠(짧은 클립)를 자동으로 계획하고 추출하는 AI 에이전트용 도구입니다. 먼저 `/video-understand` 스킬로 생성된 스크립트와 타임라인을 분석하여 숏츠 후보를 식별하고, 사용자 승인을 받은 후 최종 동영상에서 해당 구간을 추출합니다. Cursor, Claude Code, Codex와 같은 플랫폼에서 사용할 수 있으며, `ffmpeg`와 Python `Pillow` 라이브러리가 필요합니다. 수평(Horizontal) 숏츠를 기본으로 생성하고, 필요 시 수직(Vertical) 숏츠도 추가로 생성할 수 있습니다. 이 스킬은 숏츠 후보 선정, 트랜스크립트 매핑, 비디오 추출 과정을 자동화하지만, 자막, 그래픽, 등급 조정 등은 수행하지 않습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/WhiteTowerAI/cut-as-code/tree/main/skills/video-to-shorts

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

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

문서

비디오 투 숏츠(Video To Shorts)

종속성

/video-understand가 선행되어야 합니다. 숏츠가 검증된 원본 트랜스크립트와 정식 타임라인을 사용할 수 있도록 먼저 실행하세요. 시작하기 전에 /video-understand가 설치되어 있는지 확인하세요. 설치되어 있지 않으면 사용자에게 이 선행 조건이 누락되었음을 경고하고 미디어 처리를 중단하세요.

ffmpeg/ffprobe가 PATH에 있어야 하며 Python Pillow 라이브러리가 필요합니다. 미디어를 처리하기 전에 이를 확인하세요.

범위

이 스킬은 두 가지 프로젝트 단계로 구성됩니다:

  1. 렌더링 전 계획: 이해된 트랜스크립트를 프로그램 시간에 매핑하고, 후보를 작성 및 승인하며, work/shorts/shorts-plan.json을 생성합니다. 이 단계에서는 최종 비디오를 생성하지 않습니다.
  2. 렌더링 후 마무리: 선택된 모든 주요 시퀀스 편집이 승인되고 공유된 주요 결과물이 검증된 후, plan.py를 다시 실행하여 동일한 승인된 범위를 해당 결과물에 바인딩한 다음 수평 및 선택적 수직 출력물을 추출합니다.

이 스킬은 숏츠 후보 판단, 결정론적 자격 부여, 수평 추출, 숏츠 관련 트랜스크립트, 선택적 결정론적 수직 결과물 생성을 담당합니다. 프로젝트 모드에서 트랜스크립션을 수행하지 않으며, 메인 시퀀스를 변경하거나, 캡션/그래픽을 추가하거나, 등급을 조정하거나, 게시하거나, 지속적인 피사체 추적을 수행하지 않습니다.

전달되는 숏츠는 final/final-video.mp4의 파생물이지만, 후보 계획은 해당 파일보다 먼저 수행됩니다. 프로젝트 DAG에 작업을 기록하되, sequences.main.operations에는 추가하지 마십시오. 메인 결과물과 원본-최종 비교는 변경되지 않은 상태로 유지됩니다.

프로젝트 입력

  • work/project.json
  • project.source.path에 기록된 프로젝트 소스
  • 소스 시간 기준의 work/understand/transcript.json
  • work/timeline.json
  • 각 단계별 활성 메인-작업 리비전

계획 단계에서는 final/final-video.mp4가 필요하지 않습니다. 마무리 및 추출 단계에서는 render.status: verified 상태의 정확한 프로젝트 렌더링이 필요합니다.

prepare_transcript.py --timeline은 공유된 projectlib.map_transcript_to_timeline을 호출합니다. 후보/추출 시간은 따라서 실제 최종 비디오의 프로그램 시간(초)입니다. 메인 편집에서 제거된 단어는 숏츠에 사용할 수 없습니다. 각 보존된 단어는 source_range, program_range, clip_id를 유지합니다.

프로젝트 트랜스크립트 메타데이터는 프로젝트 소스, 소스 트랜스크립트, 타임라인을 절대 경로, 크기, 수정 시간, SHA-256으로 바인딩합니다. 후보 검토 프레임은 프로그램 타임스탬프를 timeline.json을 통해 소스 비디오로 다시 매핑합니다. 후보 검증은 변경된 바인딩을 거부합니다.

출력 구조

work/shorts/
|-- transcript.json
|-- transcript_metadata.json
|-- candidates.json
|-- shorts-plan.json
|-- review/
|   |-- candidate_review.json
|   `-- approved_candidates.json
`-- short-001/
    |-- transcript.json
    |-- extraction-report.json
    `-- vertical-agent/
        |-- agent_vertical_plan.json
        |-- vertical_plan.json
        `-- review/vertical_review.json

work/cache/shorts/                 # 임시 프레임/시트/중간 미디어

review/06-shorts/
|-- candidates-<review-id>.html              # 변경 불가능한 권위 있는 페이지
|-- candidates-<review-id>-question.md
|-- assets/candidates-<review-id>/            # 변경 불가능한 시작/중간/끝 프레임
|-- candidates.html                           # 권위 없는 최신 별칭
|-- candidates-summary.md
|-- short-001-horizontal.jpg
|-- short-001-vertical-preview.mp4
|-- short-001-vertical-contact-sheet.jpg
|-- short-001-vertical-preview-summary.json
|-- short-001-vertical-preview-probe.json
|-- <short-id>-vertical-review-<review-id>.html # 변경 불가능한 권위 있는 페이지
|-- <short-id>-vertical-review-<review-id>-question.md
|-- <short-id>-vertical-review.html             # 권위 없는 최신 별칭
|-- <short-id>-vertical-review-assets/
|   `-- <review-id>/                             # 변경 불가능한 권위 있는 증거
|       |-- preview.mp4                          # REVIEW_REQUIRED의 경우 없음
|       |-- contact-sheet.jpg                    # REVIEW_REQUIRED의 경우 없음
|       |-- preview-summary.json
|       `-- media-probe.json
`-- shorts-summary.md

final/shorts/
|-- short-001-horizontal.mp4
`-- short-001-vertical.mp4          # 선택 및 승인된 경우에만

프로그램 트랜스크립트

저장소 루트에서 실행:

$RepoRoot = (Resolve-Path ".").Path
$SkillRoot = Join-Path $RepoRoot "skills\video-to-shorts"
$ProjectRoot = (Resolve-Path "<project-root>").Path
$Work = Join-Path $ProjectRoot "work"
$ShortsWork = Join-Path $Work "shorts"
$ProjectSource = (Resolve-Path "<project-source-from-work/project.json>").Path
$FinalVideo = Join-Path $ProjectRoot "final\final-video.mp4"
$ShortsReview = Join-Path $ProjectRoot "review\06-shorts"
New-Item -ItemType Directory -Force $ShortsWork,$ShortsReview | Out-Null

python "$SkillRoot\scripts\prepare_transcript.py" $ProjectSource `
  --transcript "$Work\understand\transcript.json" `
  --timeline "$Work\timeline.json" `
  --out $ShortsWork

프로젝트 타임라인 모드에서는 정식 제공된 트랜스크립트가 필요합니다. 독립 실행 모드에서는 --timeline을 생략할 수 있습니다. 이 경우 입력-상대 시간을 유지하며 임시 video-understand/scripts/transcribe.py 폴백을 사용할 수 있습니다. 트랜스크립트는 자동으로 검색되지 않습니다.

후보 작성

긴 비디오 시각적 컨텍스트를 캐시에 생성하고, 결정에 필요한 모든 시트를 검사한 후 후보 JSON을 수동으로 작성합니다. 결정론적 코드는 편집 판단을 검증하며, 후보나 점수를 자체적으로 생성하지 않습니다.

python "$SkillRoot\scripts\prepare_visual_context.py" $ProjectSource `
  --timeline "$Work\timeline.json" `
  --out "$Work\cache\shorts\candidate-visual" --interval 15

후보 입력은 호환성을 위해 shorts-candidates.v2로 유지됩니다. selection.evidence_mode와 각 후보의 evidence_mode를 text_visual로 설정하세요. 각 후보는 다음을 필요로 합니다:

  • 안정적인 candidate_id, 제목, 장면 유형
  • 프로그램 시간의 완전한 start_time/end_time
  • 겹치는 트랜스크립트 단어와 정확히 동일한 transcript_excerpt (전체 겹치는 세그먼트가 아님)
  • 6개의 점수 항목과 비어 있지 않은 이유
  • 비어 있지 않은 metadata.editorial_reason
  • 선택적 검토된 filler_drop_spans 및 시각적 증거 필드

전체 score를 제공하지 마십시오. 검증기가 6개 차원을 추가합니다:

차원최대값
hook20
completeness20
audience_value20
emotion_tension15
quotability15
pace_editability10

짧은 조각보다는 완전하고 독립적으로 이해 가능한 생각을 선호하세요. 필요한 경우 종속적인 인터뷰어 질문, 전제, 주장 뒷받침, 반전, 또는 결과를 유지하세요. 경계는 전체 단어와 생각 단위에 위치해야 합니다.

작성된 파일을 검증하세요:

$CandidateDir = Join-Path $ShortsWork "preview\text_visual"
python "$SkillRoot\scripts\candidates.py" `
  --out $CandidateDir `
  --candidates "$CandidateDir\candidate-input.json" `
  --transcript "$ShortsWork\transcript.json" `
  --project-root $ProjectRoot

이 명령은 호환성 미리보기 파일, 지속성 있는 work/shorts/candidates.json, review/06-shorts/candidates.{html,summary.md}를 생성합니다.

검토 모드

후보 선택 및 전달 모드는 하나의 해시-바인딩 게이트입니다. 전달 방식은 정확히 horizontal_only 또는 horizontal_and_vertical입니다.

인간 모드에서 바인딩된 대화형 페이지를 여세요:

python "$SkillRoot\scripts\interaction.py" candidate-open --out $ShortsWork --review-out $ShortsReview

명령은 권위 있는 검토-ID 범위의 페이지를 출력합니다. 영수증은 해당 페이지, 후보 JSON, 트랜스크립트, 소스 미디어, 고정 질문, 추출된 모든 프레임을 SHA-256으로 바인딩합니다. candidates.html은 권위 없는 최신 페이지 별칭일 뿐입니다. 출력된 권위 있는 경로를 현재 OS 기본 명령으로 여세요:

# Windows PowerShell
Start-Process (Resolve-Path -LiteralPath "<printed-authoritative-page>")
# macOS
open "<printed-authoritative-page>"
# Linux
xdg-open "<printed-authoritative-page>"
# 에이전트: 권위 있는 페이지를 제시하고 중단(STOP)하세요.

열기가 실패하면 기본 명령을 재시도하고, 그래도 열리지 않으면 실패를 보고하세요. 페이지를 제시한 후에는 계속 진행하지 마세요. 페이지는 모든 후보 체크박스와 두 전달 선택 사항이 모두 초기에 선택 해제된 상태로 시작됩니다. 사용자는 1-5개의 후보와 하나의 전달 모드를 선택해야 합니다. 바인딩된 페이지는 절대 후보를 자동으로 선택하지 않습니다.

승인을 위해, 페이지가 생성한 이 정확한 구조화된 요약을 변경 없이 candidate-answer에 복사하세요:

Shorts candidate review
Review: <review-id>
Candidates: text_visual/cand-001, text_visual/cand-002
Delivery: horizontal_and_vertical

수정을 위해, 페이지가 생성한 이 정확한 구조화된 요약을 변경 없이 복사하세요:

Shorts candidate review
Review: <review-id>
Decision: revise
Changes: <non-empty requested changes>

이후 응답을 다시 작성하지 않고 기록하세요:

python "$SkillRoot\scripts\interaction.py" candidate-answer `
  --out $ShortsWork --response-file "<verbatim-summary-file>"

사용자가 명시적으로 결정을 위임할 때:

python "$SkillRoot\scripts\interaction.py" candidate-open `
  --out $ShortsWork --review-out $ShortsReview --decision-mode agent `
  --delegation-note "User delegated shorts selection and vertical approval."

python "$SkillRoot\scripts\interaction.py" candidate-agent-approve `
  --out $ShortsWork `
  --candidates "text_visual/cand-001" `
  --delivery horizontal_and_vertical `
  --rationale "The selected range has a self-contained hook, explanation, and payoff."

에이전트는 동일한 권위 있는 페이지를 열고 검사하며, 명시적인 후보 참조, 명시적인 전달 모드, 비어 있지 않은 근거를 사용합니다. 가짜 인간 응답이나 user_response를 절대 작성하지 마십시오. 인간 모드와 에이전트 모드는 상호 배타적입니다. 인간 응답 명령은 에이전트 모드에서 실패하고, 에이전트 승인 명령은 인간 모드에서 실패합니다. 영수증 검증은 검토, 페이지 및 미디어 해시를 다시 확인합니다. 재생성된 소스, 후보, 트랜스크립트, 페이지, 질문, 프레임 또는 승인된 후보 아티팩트는 승인을 무효화합니다.

정식 계획

python "$SkillRoot\scripts\plan.py" `
  --out $ShortsWork --project-root $ProjectRoot

work/shorts/shorts-plan.json은 정수 schema_version: 1을 사용합니다. 다음을 기록합니다:

  • target: derived, timebase: program, timeline_id
  • 계획 중 delivery_status: awaiting_main_render
  • 후보 검토에 사용된 프로젝트 소스 및 타임라인 바인딩
  • 활성 메인 시퀀스의 정확한 depends_on / based_on 리비전
  • 선택 모드, 근거, 전달 모드, 검토 ID
  • 안정적인 숏츠 ID
  • 명시적인 program_range 및 매핑된 source_ranges
  • 점수/편집 증거, 승인된 필러 드롭, 프로그램 시간 유지 범위
  • 작업 트랜스크립트/리포트 경로 및 ../final/shorts/*.mp4 전달 경로

첫 번째 실행은 계획 단계의 끝입니다. 여기서 멈추고 요청된 캡션, 콘텐츠 카드, 그래픽 모션 및 기타 남은 메인 시퀀스 작업을 정식 순서로 계속 진행하세요. extract_shorts.py를 실행하지 말고 이 스킬에서 final.mp4를 생성하지 마십시오.

공유 렌더러가 final/final-video.mp4를 검증한 후, 동일한 plan.py 명령을 다시 실행하세요. 승인된 프로젝트 소스와 타임라인의 유효성을 재검증하고, 전체 활성 작업 리비전을 새로 고치고, 검증된 메인 렌더 핑거프린트를 추가하며, delivery_status: ready로 설정합니다. 타임라인 변경은 새 후보와 승인이 필요합니다. 콘텐츠 카드 및 캡션과 같은 픽셀 전용 작업은 그렇지 않습니다.

자격 부여는 결정론적으로 유지됩니다: 점수가 70 이상, 완전성 15 이상, 예상 출력 길이 20-90초, 유효한 정확한 발췌문, 더 높은 순위의 숏츠와 50% 이상 중복되지 않음, 설정되지 않은 경우 최대 5개의 출력.

안전한 단어 경계를 가진 고립되고 의미론적으로 비어 있는 망설임 단어만 필러 드롭으로 승인될 수 있습니다. 거부/안전하지 않은 범위는 이유와 함께 계획에 남습니다. 전체 제거는 15%를 초과할 수 없으며 유지 범위는 0.15초보다 짧을 수 없습니다.

수평 추출

python "$SkillRoot\scripts\extract_shorts.py" `
  --video $FinalVideo --out $ShortsWork `
  --project-root $ProjectRoot

추출 전, 스크립트는 메인 렌더 핑거프린트, 프로젝트 렌더 상태, 현재 메인-작업 목록 및 리비전, 후보 영수증, 승인된 후보 해시, 소스 비디오를 다시 확인합니다. awaiting_main_render 계획은 거부됩니다. 각 유지 범위는 자체 seeked -ss/-t/-i 입력이 됩니다. ffmpeg는 이러한 입력을 연결하고 하나의 H.264/AAC 인코딩을 수행합니다. 유지 범위당 한 번씩 전체 메인 비디오를 디코딩하지 않습니다.

선택된 최종 트랜스크립트 단어와 미디어 컷 종료점은 별개의 경계입니다. 추출은 선택된 콘텐츠 후에 최소 0.25초의 해제 오디오를 보존하며 0.30초를 목표로 합니다. --no-refine-boundaries는 의미론적 구문 스냅만 비활성화하며, 필수 해제 핸들은 절대 비활성화하지 않습니다. 소스가 필요한 핸들을 보존하기 전에 끝나면, 추출은 숏츠를 검증된 것으로 표시하는 대신 실패합니다.

숏츠-상대 트랜스크립트는 드롭된 단어를 제외하고, 이후 단어를 연속적인 0-기반 클록으로 이동시키며, 입력 프로그램/소스 증거를 유지합니다. 수평 미디어는 final/shorts로 직접 이동하며, 작업 디렉토리에는 트랜스크립트와 리포트만 포함됩니다.

수직 계획

수직 전달은 승인된 수평 출력에서 시작됩니다. 1초 간격으로 밀집된 시각적 증거를 생성하거나, 움직임이 필요한 경우 0.5초 간격으로 생성합니다. 모든 시트를 검사하고 다음 중 하나를 작성합니다:

  • STATIC_CROP: 하나의 안정적인 고정 9:16 크롭.
  • SCENE_CROP: 장면 경계 내 고정 크롭, 완전한 수평 정보가 필요한 장면에 대해서만 LETTERBOX 사용.
  • LETTERBOX: 흐리거나 어두워진 배경 위의 완전하고 선명한 전경.
  • REVIEW_REQUIRED: 증거가 결정론적 고정 크롭을 지원할 수 없음. 정식 렌더링이 차단됨.

발표자 장면은 머리와 상체를 안정적이고 크게 유지해야 합니다. 슬라이드, 제품, 그룹, 다이어그램은 필수 정보를 유지해야 합니다. 연속적인 추적을 주장하지 마십시오. 크롭 변경은 장면 경계에 속합니다.

각 계획 세그먼트는 숏츠 타임라인을 완전히 덮고, 전략을 가지며, 캔버스 전체를 [0, 0, canvas_w, canvas_h]로 설정합니다. 선택 bounds는 [x, y, w, h]입니다. 미리보기를 위해 이미지와 시트를 생성하지 말고, 계획의 타당성을 검증하기 위한 충분한 컨텍스트를 제공하세요.

수직 추출

python "$SkillRoot\scripts\extract_vertical.py" `
  --shorts $ShortsWork --out "$ProjectRoot\final\shorts" `
  --project-root $ProjectRoot

이 단계에서는 항상 수직 계획이 필요하며 LETTERBOX에 대한 기본 정책이 있습니다. 기본 정책은 agent/vertical_plan.json이 재작성되지 않음을 의미합니다. LETTERBOX는 extract_vertical.py가 블러/어둡게 함을 적용합니다.

검증은 각 세그먼트의 중간 프레임에서 해시 기반으로 이루어집니다. REVIEW_REQUIRED 세그먼트는 추출을 차단합니다. 한 세그먼트라도 차단되면 전체 숏츠가 차단됩니다. 포기하는 대신 여기서 멈추고 보고한 후 피드백을 기다리세요.

REVIEW_REQUIRED 범위를 재평가하려면 동일한 인수로 다시 실행하세요. 다시 실행은 기존 계획을 다시 읽고 잠재적으로 재현 가능한 해시 일치를 허용합니다.

Individual skills in this repo

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

관련 스킬