{"id":"video-recap","name":"video-recap","summary":"入力動画から中国語ナレーション動画を端から端まで生成します。ユーザーは.mp4 / .mov / .mkv / .webmを提供し、ナレーション、吹き替え、要約、短編ドラマ、テレビドラマ、映画、ドキュメンタリー、大衆科学解説の追加をリクエストします。","body":"## 1. 定位与流程\n\n本技能是五个独立技能的轻量编排器。各技能只通过 `work_dir` 中的 JSON / MP4 产物通信，不共享代码：\n\n```text\nvideo-understanding ─▶ Agent 按 video-script 制定方案并写稿 ─▶ [video-cut] ─▶ video-voiceover ─▶ video-assemble\n```\n\n流程支持断点续跑：写好 `narration.json` 后重复同一条命令即可继续。第二阶段会校验\n`recap_run_manifest.json`，拒绝复用来自其他源视频或其他运行参数的旧工作目录；视频理解产物也只在来源一致时复用。\n\n## 2. 创作职责\n\n这不是单纯的 JSON / 渲染流水线。Agent 是本次内容的创作负责人，在进入昂贵的下游处理前，必须按顺序完成五次判断：\n\n1. **导演判断**：确定观众承诺、POV、戏剧问题、情绪终点，以及哪些信息要保留到后面揭示。\n2. **故事编辑**：比较至少两个可行的剪辑假设，选择一条主线，并把 beat 定义为“发生了什么变化”，而不是场景摘要。\n3. **画面剪辑**：选择真正值得保留的具体时刻、人物反应、入点与出点。\n4. **声音/旁白**：先分配画面、原声、沉默和旁白的任务，再写解说词。\n5. **观众复核**：分别检查无旁白、只听声音和第一次观看时的体验，优先修改回报最高的问题。\n\n执行前阅读本技能的 `references/creative-editing-playbook.md`，并把简洁的创作决定写入：\n\n- `recap_story_plan.json`：导演意图、备选假设、选定主线和基于变化的 beat 图。\n- `visual_audio_board.json`：每拍的画面任务、表演/反应选择、原声锚点、`audio_owner` 与 `narration_job`。\n\n这两个文件只记录可审计的决定，不记录冗长思维过程；它们不会增加服务或渲染依赖。现有工具可以忽略它们，Agent 与建议型解说评审会用它们保持创作一致。建立这条内容基线不需要平台数据。\n\n## 3. 环境与脚本路径\n\n```bash\n# ffmpeg: brew install ffmpeg | apt install ffmpeg | choco install ffmpeg\nexport MIMO_API_KEY=***\n```\n\n同一个 MiMo key 驱动：\n\n- ASR：`mimo-v2.5-asr`\n- VLM：`mimo-v2.5`\n- TTS：`mimo-v2.5-tts`\n\n`tp-*` Token Plan 密钥默认使用中国区集群，可用 `MIMO_TOKEN_PLAN_CLUSTER` 覆盖。\n\n可选能力：\n\n- `--mimo-video-overview`：按场景块补充 MiMo 视频理解。\n- `--mimo-qc pre-assemble|post-render|both`：在合成前、成片后或两个阶段给出建议型复核。\n\nMiMo QC 默认关闭；每个选定阶段最多请求一次，写入 `mimo_qc.json`。任何凭证缺失、限流、超时、格式错误或采样失败都只记录状态，不阻断流程。详细可覆盖配置见 `references/config-playbook.md`。\n\n下面的 `scripts/...` 均相对于本技能目录。若执行器从仓库根目录启动，请给脚本路径加上本技能的绝对目录。脚本启动后会自行定位兄弟技能和资源。\n\n## 4. 标准解说流程\n\n### 4.1 背景调研\n\n若能识别影片、剧集或主题，先按本技能的 `references/research-guide.md` 调研并写入\n`work_dir/background_research.json`。视频理解会把人物名和剧情背景折入 VLM 上下文，避免只得到“黑衣男子”一类模糊描述。无法识别来源时可跳过。\n\n### 4.2 分析并暂停创作\n\n```bash\npython3 scripts/recap.py <video> --work-dir <work_dir> --context \"背景\"\n```\n\n命令完成视频理解、写出 `agent_narration_brief.md`，然后暂停。此时按以下顺序执行 `video-script`：\n\n1. 查看创作 brief 与原片故事板。\n2. 写 `recap_story_plan.json` 和 `visual_audio_board.json`。\n3. full 模式写 `narration.json`；cut 模式第一阶段只写 `clip_plan.json`。\n4. cut 模式第二阶段查看剪后故事板，补充输出时间与声音分工，再写 `narration.json`。\n\n不要从标题或旁白句子开始；先锁定故事体验和素材选择。\n\n时间线有两条不可降级的硬约束：原声只能在可靠句末/静音边界被切入、切出或恢复；旁白必须使用\n完整逐段音频，任何 clip 映射裁段、TTS 裁尾或剪映引用更长的加速前素材都阻断。Agent 收到\n`interrupts_source_sentence` / `unsafe_clip_sentence_boundary` / `no_safe_fit` /\n`timeline_audio_mismatch` 时，应移动边界、缩短整句或删除该块，而不是增加抢断 override。\n\n### 4.3 多视频与素材库\n\n多视频只支持 cut 模式。项目 brief 会列出稳定的 `source_id`，`clip_plan.json` 中每个片段都必须填写来源：\n\n```bash\npython3 scripts/recap.py ep1.mp4 ep2.mp4 --edit-mode cut --target-duration 10m --work-dir work_dir_multi_ep\n```\n\n可选文件系统素材库：\n\n```bash\npython3 scripts/recap.py ep1.mp4 --material-library-dir .video-materials --save-materials\npython3 scripts/recap.py ep1.mp4 ep2.mp4 --edit-mode cut --material-library-dir .video-materials --use-materials\n```\n\n素材检索只是对 JSON / MD / JSONL 做 grep，例如 `grep -R \"keyword\" .video-materials`。当前版本不复制原始媒体，也不提供数据库、向量或语义搜索。\n\n### 4.4 继续生成成片\n\n写好所需产物后，重复同一条命令：\n\n```bash\npython3 scripts/recap.py <video> --work-dir <work_dir>  # 可追加 --edit-mode cut / --no-burn-subtitles\n```\n\n流程会校验当前阶段的硬输入（`clip_plan.json` / `narration.json`）；两份创作计划仍是 Agent 与建议型评审使用的工作记录，不是渲染门禁。cut 模式随后生成 `edited_source.mp4`，再合成旁白并输出 `recap_<name>.mp4`。\n\n若需要建议型 MiMo 复核：\n\n```bash\npython3 scripts/recap.py <video> --work-dir <work_dir> --mimo-qc both\n```\n\n合成前复核会读取脚本、计划和 TTS 元数据；成片后还会读取最多六张临时 JPEG。相同输入命中内容缓存，`--mimo-qc-refresh` 可强制刷新。帧的 base64 与凭证不会写入磁盘。\n\n### 4.5 字幕与克隆旁白\n\n若要把旁白字幕固定在原片字幕区域，先在仓库根目录运行：\n\n```bash\npython3 tools/measure_subtitle.py <video>\n```\n\n再传入测得的 `--subtitle-y-top/--subtitle-y-bot`。坐标基于 ffmpeg 自动旋转后的显示画布，区间为半开 `[top, bot)`，并要求底对齐 ASS 样式；显式设置后，该区域默认使用 60% 透明度的旁白窗口遮罩。\n\n解说模式如需克隆参考声音，使用 `--voice-ref <audio>`；它与 dub 模式不同。\n\n## 5. 英译中原声复刻模式\n\n`--edit-mode dub` 把英文视频翻译为中文，并用原说话者的克隆音色替换人声；它不是在压低原声上叠加解说。\n\n```bash\npython3 scripts/recap.py <video> --edit-mode dub --work-dir <work_dir>\n```\n\n准备阶段会转写英文、提取一段参考音频，并写出 `dub_brief.md` 与 `dub_transcript.json`。Agent 随后写：\n\n```json\n[{\"start\": 0.0, \"end\": 2.0, \"zh\": \"中文译文\"}]\n```\n\n要求：\n\n- 逐句忠实翻译，不删钩子、不合并、不擅自压缩；原文重复，译文也按时间重复。\n- 每句沿用原声 `[start, end]`，相邻句不重叠。\n- 译文尽量控制在约 5 字/秒，使其能在原时间窗内说完。\n\n重复同一命令后输出 `dub_<name>.mp4`。每句单独克隆并贴回原时间线；只有即将覆盖下一句时才局部加速。当前版本只支持单说话者、整轨替换，不分离背景音乐。\n\n## 6. 自检命令\n\n```bash\npython3 scripts/recap.py --doctor\n```\n\n## 7. 输出与参数\n\n主要输出：\n\n- `recap_<video>.mp4`：最终成片。\n- `subtitles.srt` / `subtitles.ass`：字幕。\n- `work_dir/`：全部中间产物，契约见 `references/data-schema.md`。\n- `work_dir/recap_story_plan.json` / `visual_audio_board.json`：Agent 创作意图与剪辑决定。\n- `work_dir/mimo_qc.json`：可选的建议型复核，不作为发布门禁。\n\n可透传参数：\n\n`--context`、`--scene-threshold`、`--style`、`--edit-mode {full,cut,dub}`、`--target-duration`、\n`--skip-asr`、`--mimo-video-overview`、`--mimo-qc {off,pre-assemble,post-render,both}`、\n`--mimo-qc-refresh`、`--consolidate`、`--consolidate-asr`、`--mimo-tts-voice`、`--voice-ref`、\n`--allow-partial-tts`、`--review-narration`、`--no-review-narration`、`--require-narration-review`、\n`--subtitle-y-top`、`--subtitle-y-bot`、`--no-burn-subtitles`、`--output-dir`、\n`--export-jianying`、`--jianying-bundle-media`、`--jianying-no-bundle-media`、\n`--material-library-dir`、`--use-materials`、`--save-materials`。\n\n`--style` 是原样传给 Agent 的自由文本指导，不是 preset、枚举、开关或有限风格分类。\n\n## 8. 能力边界\n\n- 编排器不代替 Agent 写 `narration.json` / `clip_plan.json`；具体写作遵循创作 brief 与写作阶段契约。\n- 语义评审默认建议型、失败开放；只有调用方显式启用严格解说评审时，事实矛盾、残句或评审不可用才会在 TTS 前阻断。确定性校验阶段始终负责硬校验。\n- MiMo QC 不能阻断、自动修复或改变退出状态，只提供定位建议。\n- 建立内容质量基线不依赖平台分析、留存遥测或发布接入。\n- 本技能不是无人值守调度器，不会向任何平台发布内容。\n- 各阶段技能不共享代码，只通过 `work_dir` 产物通信。","author":"@worldwonderer","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/worldwonderer/video-recap-skills/tree/main/skills/video-recap","license":"MIT","category":null,"lang":"multi","tokens":2713,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/config-playbook.md","size":10161,"sha256":"a8420e135b0b908f679feea46f57c648973e730799d38018dffafe4e72ec335e"},{"path":"references/creative-editing-playbook.md","size":8090,"sha256":"e4710fa6d2deffefb84e7d3d63b427c0929d950de63294db0783dcd9ffbd24da"},{"path":"references/data-schema.md","size":26595,"sha256":"9d27cdaeba69a565d5314288808a7cdb18e003385e0ac4c877d2b2b6717d1361"},{"path":"references/research-guide.md","size":2880,"sha256":"5d8a0830ee2092ea759a05ed842c63679fb205b653af79af8a99f1234e406b13"},{"path":"references/shift-left-qc-schema.md","size":2314,"sha256":"d4db18ce8b58fc160dcd08174fbc48dbf1a724b27d7d95dcf13817c979218df2"},{"path":"references/timeline-and-jianying.md","size":13760,"sha256":"479c73100d1db242a617ac0473ada9e68bc2588901312579844583dfc43214b2"},{"path":"scripts/doctor.py","size":16503,"sha256":"f51024b0b11ab495ea68844c0e13b799017f76d1a9edc63cecb627c423f8374b"},{"path":"scripts/final_qc.py","size":31180,"sha256":"d4b42adbf62e6929268d867257bdf49f3061be3a4ee2a6d74cd07d13f95ea295"},{"path":"scripts/lib.py","size":10375,"sha256":"d2ccd1e8c80a25fba42dbbd7a78ce44da17bade5d48ee44674e724ee454777fc"},{"path":"scripts/materials.py","size":18536,"sha256":"c7238193ecf3a9ca8aba280e1d85b8b4c8b4cc5521fe4f15fa2e98dfffad8442"},{"path":"scripts/mimo_qc_client.py","size":670,"sha256":"3a08a4944bdafea168b66f9a15e7d6b68b85b7e7dd264677cbfcdc808a1b90f1"},{"path":"scripts/mimo_qc_contract.py","size":239,"sha256":"e51d30a11798d056ebfadfd1fa21142fea82bc69a07d611670b0dab394cca6fc"},{"path":"scripts/mimo_qc_evidence.py","size":11817,"sha256":"9a3622e273ae157e8bf4c3e5455a5d4447f640a13e322e5efc39320fe6377959"},{"path":"scripts/mimo_qc_observations.py","size":7171,"sha256":"3d0ec2ce33c718e7d0c4337757e2df26f5b6363e89243087fb5f671be2faffc6"},{"path":"scripts/mimo_qc_payload.py","size":11403,"sha256":"cf2c57b2c7d9405aa4d0b71ee8beeebe7560451e1b8c98d18a9c835e154f36b3"},{"path":"scripts/mimo_qc.py","size":2083,"sha256":"54dc05048b034cf2e57ea3c877ffed6ceff18618d3ca2071454a1039cb35e73d"},{"path":"scripts/mimo_qc_report.py","size":11338,"sha256":"c10faa491170dc0838cfecf70706c80a969bcb25e22349c73e7ec5511006a32f"},{"path":"scripts/mimo_qc_runner.py","size":3796,"sha256":"1120676164c669243d78fbc872c4302435117c090e0752a569c13b5693c0d409"},{"path":"scripts/qc_contract.py","size":12771,"sha256":"cfdabd6a92a9005e4e4cf2951cba4d569716312412173c0dd16ef31354bfba8f"},{"path":"scripts/recap_cli.py","size":4750,"sha256":"2da181c9a160cfeb47d22d7b3799440a4b20d9e89b138ec3cfe2410b2653ffb8"},{"path":"scripts/recap_inspect.py","size":23216,"sha256":"1cae353fc871114d8bb187989fe4185a06fa6c1338d4e686b9983bd1f62a1255"},{"path":"scripts/recap.py","size":183,"sha256":"873a1f849fb25b2c192cf5e57b6ca82a339c3045ca90f18dfded49fe3f34a222"},{"path":"scripts/recap_review.py","size":2988,"sha256":"d86e906bfa236e6961623ff06018ccc0ea1549b4a7b2263cda1ad03d23fa4adc"},{"path":"scripts/recap_runner.py","size":24338,"sha256":"3a51464c74f3e11076d2b028f14244f0b28d483c075c02bcc4d07947666351c7"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"net.endpoints","kind":"exfiltration","excerpt":"api.xiaomimimo.com, token-plan-ams.xiaomimimo.com, token-plan-cn.xiaomimimo.com, token-plan-sgp.xiaomimimo.com","message":"bundled scripts reach 4 external host(s)","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":true,"networkEndpoints":["api.xiaomimimo.com","token-plan-ams.xiaomimimo.com","token-plan-cn.xiaomimimo.com","token-plan-sgp.xiaomimimo.com"]}}