Communitygithub.com

视频转短视频

该技能从完成的视频项目中提取并生成短视频(short-form content),支持水平与垂直交付,并包含结构化的审核流程。

视频转短视频 是什么?

此技能旨在从已完成的视频项目中高效提取并生成短视频。它包含两个核心阶段:规划阶段和最终提取阶段。在规划阶段,它会分析已转录的对话时间线,由用户或AI代理审核并批准候选片段,生成详细的规划文件(包括程序时间范围、源时间范围、评分等),但不会产生实际视频。在提取阶段,当主视频渲染完成并验证后,它会精确地根据已批准的规划,从最终视频中通过seek加速方式提取出水平(16:9)和可选的垂直(9:16)短视频。支持的平台包括Claude Code、Cursor等AI代码编辑器,依赖于`ffmpeg`、`Python Pillow`库以及前置技能`/video-understand`。其工作流程高度结构化,包括严格的候选评分(基于六个维度,总分100)、基于SHA-256哈希的媒体绑定验证、以及明确的审核模式(人类或AI代理)。垂直版本的规划通过分析视觉内容(如场景边界、演讲者位置)来确定裁剪策略(静态裁剪、场景裁剪、信箱模式或需要人工审核),确保生成的短视频在保持关键信息的同时适配不同宽高比。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/WhiteTowerAI/cut-as-code/tree/main/skills/video-to-shorts

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

视频转短视频 是做什么的?

依赖项

/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 必须精确等于重叠的转录单词,而不是整个重叠的片段;
  • 所有六个评分条目和不为空的理由;
  • 不为空的 metadata.editorial_reason;
  • 可选的、已审核的 filler_drop_spans 和视觉证据字段。

不要提供总 score;验证器会自行添加六个维度的分数:

维度最大值
hook(钩子)20
completeness(完整性)20
audience_value(观众价值)20
emotion_tension(情感张力)15
quotability(可引用性)15
pace_editability(节奏可编辑性)10

优先选择完整、能独立理解的思想,而不是一个更短的片段。当依赖性的采访者问题、前提、主张支持、反转或回报对于理解是必要时,请保留它们。边界必须落在完整的单词和思想上。

验证已创作的文件:

$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 只是一个指向最新页面的非权威便利别名。使用当前操作系统的本地命令打开打印出的权威路径:

# Windows PowerShell
Start-Process (Resolve-Path -LiteralPath "<printed-authoritative-page>")
# macOS
open "<printed-authoritative-page>"
# Linux
xdg-open "<printed-authoritative-page>"
# Agent: 展示权威页面并停止。

如果打开失败,重试本地命令,如果仍然打不开,则报告失败。在展示页面后不要继续。页面以所有候选复选框和两个交付选项均未选中开始。用户必须选择 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."

AI 代理会打开并检查相同的权威页面,使用明确的候选引用、明确的交付模式以及非空的理由。它永远不会编写虚假的人类响应或 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%,并且除非配置修改,否则最多输出五个短视频。

只有孤立的、语义上空白的犹豫词,并且具有安全单词边界,才可能被批准为填充词删除。被拒绝/不安全的跨度会保留在计划中并附上原因。总删除量不得超过 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 仅禁用语义短语捕捉;它永远不会禁用强制性的释放处理。如果源视频在所需处理能被保留之前结束,则提取失败,而不是将短视频标记为已验证。

短视频相关的转录原文排除了被删除的单词,将后续单词移到一个连续的、基于零的时钟上,并保留输入程序/源证据。水平媒体直接进入 final/shorts;工作目录仅包含其转录和报告。

垂直规划

垂直交付从已批准的水平输出开始。以 1 秒为间隔生成密集的视觉证据,当运动需要时则为 0.5 秒。检查每一个帧集合,并创作以下策略之一:

  • STATIC_CROP:一个稳定的、固定的 9:16 裁剪。
  • SCENE_CROP:基于场景边界的固定裁剪,对于需要完整水平信息的场景,使用 LETTERBOX。
  • LETTERBOX:在模糊/变暗的填充上显示完整的、清晰的(锐化的)前景。
  • REVIEW_REQUIRED:证据不足以支持确定性的固定裁剪;正式渲染被阻止。

演讲者场景应保持头部和躯干稳定且比例适中。幻灯片、产品、组图、图表等必须保留必要的信息。不要声称进行持续的物体追踪。裁剪更改应发生在场景边界。

每个规划片段完全覆盖短视频时间线,具有一种策略、配置的中心点/宽度、保持于帧内的边缘、使用的证据帧以及任何关注的解释。垂直规划拒绝未知策略和未充分覆盖的策略。

垂直预览和审核

在写入 vertical_plan.json 并可能交付之前,为每个非 REVIEW_REQUIRED 的短视频渲染一个带水印的代理预览 mp4(300kbps)和一个 JPEG 联系表。非垂直代理的短视频(STATIC_CROP 或 LETTERBOX)是快速的、确定性的单遍编码;基于场景的项目可能需要组装。通过 media-probe.json 验证输出。

对于每个 REVIEW_REQUIRED 短视频,代理预览和联系表不存在;审核者必须查看原始水平输出。当存在任何 REVIEW_REQUIRED 短视频,和/或任何基于场景的裁剪在整个短片中分割成超过 7 个不同片段时,必须进行人工审核。 对于所有其他情况,代理可以批准。

python "$SkillRoot\scripts\vertical_render.py" $FinalVideo `
  --plan "$ShortsWork\short-001\vertical-agent\vertical_plan.json" `
  --out "$ShortsWork\short-001\vertical-agent" `
  --preview-only

打开具有人类审核能力的权威垂直审核页面:

python "$SkillRoot\scripts\vertical_interaction.py" review-open --out $ShortsWork --short-id short-001

该命令打印一个权威的、审核 ID 范围的页面。此绑定将短视频及其代理预览、联系表、媒体探针、源水平和垂直计划固定下来。页面以所有可选裁剪按钮取消选中开始。

对于批准(人类或代理),为每个短视频记录:

Shorts vertical review
Short: <short-id>
Review: <review-id>
Decision: approve
Changes: <optional requested changes>

对于驳回(仅限人类):

Shorts vertical review
Short: <short-id>
Review: <review-id>
Decision: revise
Changes: <non-empty requested changes>

在以下情况下,代理可以批准:

  • 没有 REVIEW_REQUIRED 短视频,并且
  • 没有基于场景的短视频被分割成超过 7 个片段。

当满足这些条件时,代理可以在无需人工审核的情况下运行:

python "$SkillRoot\scripts\vertical_interaction.py" review-agent-approve `
  --out $ShortsWork --short-id short-001 `
  --assessment "Single STATIC_CROP with stable head position, no cropping loss on whiteboard content."

代理评估必须引用具体的策略、分割计数以及确认没有裁剪损失或信息损失。

最终垂直渲染

python "$SkillRoot\scripts\vertical_render.py" $FinalVideo `
  --plan "$ShortsWork\short-001\vertical-agent\vertical_plan.json" `
  --out "$ShortsWork\short-001\vertical-agent" `
  --mp4-out "$ProjectRoot\final\shorts\short-001-vertical.mp4"

最终垂直交付文件是 H.264/AAC、1080x1920、最高 12 Mbps、恒定帧率、无 GBR(回放时避免水平伪影)、4:4:4 色度子采样(只适用于协作式上传)。

代理必须始终在最终的垂直 mp4 上运行 ffprobe 验证:

ffprobe -v quiet -print_format json -show_format -show_streams `
  "$ProjectRoot\final\shorts\short-001-vertical.mp4"

如果验证失败,报告证据且不重试。

技能总结

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

review/06-shorts/shorts-summary.md 记录了短视频输入选择、交付模式、文件路径、时长、格式和任何问题。

独立模式

给定任何视频文件,无需项目 JSON:

python "$SkillRoot\scripts\prepare_transcript.py" <source.mp4> --out <workdir>
python "$SkillRoot\scripts\prepare_visual_context.py" <source.mp4> --out <cachedir> --interval 15
# 手动创作 shorts-candidates.v2 在 <workdir> 中
python "$SkillRoot\scripts\candidates.py" `
  --out <workdir> --candidates <candidates> --transcript <transcript> --project-root <workdir>
python "$SkillRoot\scripts\interaction.py" candidate-open --out <workdir> --review-out <reviewdir>
python "$SkillRoot\scripts\interaction.py" candidate-answer --out <workdir> --response-file <response>
python "$SkillRoot\scripts\plan.py" --out <workdir> --project-root <projectdir>
python "$SkillRoot\scripts\extract_shorts.py" --video <mp4> --out <workdir> --project-root <projectdir>

独立模式跳过项目时间线映射,保持输入相关时间,不允许垂直处理,并且不进行验证。

配置

work/shorts/shorts-config.json(在工作目录中)覆盖默认限制:

| 键 | 默认值 |\n|---|---| | max_outputs | 5 | | program_min_seconds | 20 | | program_max_seconds | 90 | | min_completeness_score | 15 | | min_total_score | 70 | | max_overlap_ratio | 0.5 | | max_filler_ratio | 0.15 | | min_keep_seconds | 0.15 | | release_handle_seconds | 0.30 | | horizontal_video_codec | h264 | | vertical_video_codec | h264 | | vertical_max_bitrate_kbps | 12000 |

Individual skills in this repo

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

相关技能