千枢汇·多源融合混剪引擎

SKILL前端设计
前端设计 未标注权限 许可证不明确
安装这个技能

【千枢汇专用】多源同款原片融合混剪(显示名「千枢汇·多源融合混剪引擎」):把同一款商品的 4~8 条原片打散成共享素材池,批量产出多条(通常 5~12 条)画面互不雷同的带货短视频,出片时自动替换原口播字幕。|【何时用】多条同款原片+问「能出几条/做几条不一样的」→ 本技能;1 条素材+1 份定稿文案 → 用 qianshuhui-hunjian。|【两模式】批量(≥4 条铺量测品,画面重复度只报不拦)/精品(1~3 条全池择优)。|【开工五问】文案来源·生产模式·商品口径(产地/品种/规格/价格,素材标题的产地≠用户卖的产地)·交付形态(成片/剪映草稿)·打码口径(默认开);配音五问挪到 Step 3.6(文案定稿后·排镜前,音色须给推荐);文案交付带时长双标注。|【流程】素材体检→产量测算→文案矩阵→文案评审关→配音五问→融合编排→配音合成→七道闸门→出片交付。|【产出】一批(通常 5~12 条)成片(1080×1920,带 +faststart 点开就能播);需要时另出剪映草稿。|【用户只把两关】文案终稿(Step 3.5)与最终成片,其余由 AI 自查。|【真人口径】真人与无人平权、按文案择优;硬红线=同片禁换人(可辨正脸≤2);铁律六=改像素/改时轴从产物反测。|【价格】只用用户告知的。|触发【融合混剪:】。从素材自身熔炼文案。

一句话选型结论

按资料字段整理

千枢汇·多源融合混剪引擎是前端设计类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类前端设计 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_1518b4a4/qianshuhui-duoyuan-hunjian
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

前端设计
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_1518b4a4仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791711149
正文体量163.1 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
出页面与组件

按描述生成页面结构和组件草稿。

调整样式与布局

改间距、配色与响应式布局。

生成设计说明

把设计稿整理成开发能接的说明。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在前端设计场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
千枢汇·多源融合混剪引擎当前 未标注权限 未标注 未标注 未标注 有
前端设计 只读 GitHub 仓库 882.3 万 Codex、Claude、Cursor 有
Vercel 组合模式 联网访问 GitHub 仓库 385.9 万 Codex、Claude、Cursor 有
Vercel React native skills 前端 只读 GitHub 仓库 246.9 万 Codex、Claude、Cursor 有
adapt 搜索 浏览器控制 GitHub 仓库 202.7 万 Codex、Claude、Cursor 有
使用我的浏览器 浏览器控制 GitHub 仓库 184.8 万 Codex、Claude、Cursor 有

SKILL.md 全文

163.1 KB
模型实际读到的说明书原文,来自技能仓库

千枢汇·多源融合混剪引擎

⚡ 现行口径速查(用户定调,2026-10-05/06/08 · 优先级最高)

> 这一节是全部文档的裁判:正文任何地方与本节冲突,以本节为准。
> 散落各处的旧数值若与本节矛盾,一律视为历史残留(完整历史在 references/CHANGELOG.md)。

# 口径 用户原话/依据
1 画面重复度只报不拦(两种模式同口径);真正要避开的只有「同素材+同刀位+同时长」 2026-10-05「不必卡得这么死,两条片不是一模一样就行,有少许偏差就行」
2 镜头复用不设机械上限,max_reuse=3 只是程序兜底值,选镜以文案为准 「我也没有规定一个镜头只允许复用两次」
3 刀长下限 1.0s(不是 0.5s),<1s 绝对禁用;下限与上限成对设(一镜到底优先) 「不能用那种 1 秒以下的镜头,那种就不太好」
4 文案不必逐句配画面:卖点句尽量配、没有也能用;独白句有则更好;唯一硬线是不矛盾 「并不是说每一句文案非要匹配对应的画面片段…这个你得自行判断」
5 长镜是否够用靠清点脚本落档(宽裕≥2/紧张1~2/不足<1,先重排后补素材),不套历史比值 「不要把所有东西都写死」
6 母版数 = f(目标条数):1 条 → 1 母版;≥2 条才出甲乙双母版 由「不写死」推定,2026-10-06 确认
7 真人与无人平权:编排时两类镜头同池择优、不再回避真人,「无人优先」已取消(不做任何限制);用不用真人由 AI 按文案与排片自决(不问用户);唯一硬红线=同片禁换人(可辨正脸 ≤2,⑦ 闸门无条件拦)。「禁换人」=前后呼应:素材里有两位真人可以都用(不是二选一),要求是成片内真人集合固定 —— 前面用了谁,后面还是谁,不中途引入别人(2026-10-09 用户澄清) 2026-10-08「把『无人优先』这条规则删掉,不做限制……素材池也会变大,排版时选择性也会更大」;2026-10-09「并不是说有真人就不能用……你前面用了两个真人的镜头,如果后面还需要用,还是要用这两个」
8 ★★「定点修」优先于「全量重跑」——本技能第一工作习惯,优先于"求稳":只要已知问题在第几秒 + 画面哪个位置,就直接定位过去只改那一小段,绝不为了"保险"把整条片从头到尾重扫一遍。适用范围不止糊字幕 —— 任何"已知具体位置的小瑕疵"(漏糊一个字、坏帧、错字、音画错位、贴纸残留)一律定点修。实测代价:定点补丁 ≈1.5 分钟 vs 全片重扫 ≈22 分钟(差 15 倍)。 做法 = ①定位到秒 + 位置 → ②只重做那一小段 → ③三段统一 libx264 -crf 16 重编后拼接(⚠ 不要 -c copy 拼不同编码)。⚠ 2026-10-10 同一晚踩了两次(修完 47.5s 又为"保险"铺全片扫描,白等 14 分钟)→ 这条必须形成肌肉记忆。细节见 references/pitfalls.md 「★铁律」段 2026-10-10「你既然知道是 47.5 秒……直接定位到那里,把这个字糊掉不就可以了吗?难道你还要全部重新扫描一遍吗?还要 20 分钟,太花时间了。」;「哪里没有糊到,你也知道具体是哪一秒,也要知道具体的位置。你直接定位到那里操作就行了,用不着从头到尾扫描一遍。这点你要记住,要灵活变动。」;「能定点去做的事情,你又为了保险,改成全片扫描。这种事你一定要记得,不然很浪费我的时间。」
9 ★★ 灵活解决,不死板:规则是默认值不是硬约束。遇到问题时先想"最小改动路径",不要一上来就套"全量重做"的标准流程。判断顺序 = ①问题在哪(秒+位置)→ ②能不能只改那里 → ③不能才扩大范围。 用户要的是省时间,不是"保险地把流程重跑一遍" 2026-10-10「以后我们还会遇到各种各样的问题,你要灵活地去解决。」;「规则永远是死的,但我们要根据实际情况来变动」(2026-10-05)
10 ★★ 骨架=从素材「长」出来的,不是端一张菜单让你挑。正确顺序:素材(画面+分镜+卖点)→ 融合 → 文案 → 骨架自然长出来。推荐制:我按目标条数直接给「首选 N 个」+一句理由(⛔ 不许丢一张空白菜单让用户自己选);但必须同时附「本次还能长出来的其他骨架」备选池 —— 用户保留改选权(推荐 ≠ 拍板);被推翻时当场快速评估、不给用户等第二轮。骨架清单是开放的(素材长出菜单里没有的结构,照用);⛔ 不许说「素材撑不住这个骨架」(那是融合没融准的借口)。完整规则见 references/gujia-menu.md 2026-10-10「你可以先做一个开工骨架菜单,再根据素材文案融合来做搭配,选择最适配的骨架结构……因为后续文案都是要匹配画面的」;「并不是让我自己选,而是根据最好的文案、最好的画面来推荐」;「必须我推荐、不许让你挑,但是我也要有选择的权利……你也要给我选择的选项」;「并不是说我一定需要这种骨架,还是要根据文案和分镜来决定」;「既然融出了文案,那肯定是有对应的骨架的,怎么会说撑不住呢?除非是你前面融合的文案和分镜不准确」
11 同骨架派生条数 = 默认 2 条(必须把条数选项摆出来);同骨架两条「换主画面来源」不写死(画面撑不满时,两条看着差不多也可以);借入清单不跟骨架绑(它是文案的伴生物,文案一出来自然就有) 2026-10-10「同一个骨架默认派生 2 条,如有其他需要,我会和你提。你要给我选项。」;「这一条也不要写死。如果画面支撑不好时,两条骨架视频画面差不多也可以。」
12 ★★ 音色不只「必问」,还必须给推荐:问的时候是「我推荐 X(一句理由),想换 Y/Z 也可以」—— ⛔ 不许只丢 5 个音色名让用户自己挑。四条依据有先后:① 画面里的可辨真人(最硬,一票否决 —— 音色性别/年龄要对上出镜人,否则是穿帮)→ ② 骨架调性 → ③ 品类调性 → ④ 同批多条分开配(同一音色不超过一半;同一骨架的 2 条优先配不同音色,但不写死,画面有可辨真人时以画面为准)。推荐在 Step 3.6 一次给到位(文案定稿后·排镜前)。规则与映射表见 references/voices-user.md §二 2026-10-10「我选择音色的选项那里,你会有推荐吗?也就是说,根据文案结构和对应的画面分镜素材,你会给我推荐使用音色吗?」
13 ★★ 配音五问在「文案定稿后、排镜前」问一次(Step 3.6),不在开工问 —— 音色要看的四样依据里三样(真人 / 骨架 / 文案)开工时都还没有,问早了必回头改;但也不许拖到 Step 5(语速一改,句首→画面切换点全变,整条排镜作废)。并且:文案交付必须带「时长双标注」(按 1.2 倍 ≈ 多少秒 / 按 1.0 倍 ≈ 多少秒),口径见 references/voices-user.md §四 2026-10-10「这个不一定要放在开工的时候就要问我吧?应该是你出了骨架文案到需要配音的时候再问我吧,我感觉……放得太过于早了」;「写文案的时候你就参考 1.2 倍速来估,但是你出完文案的时候,要标注一下……1.2 倍大概多少秒?正常倍数 1.0 倍大概多少秒?」

配套判据:一个数字如果只有值、没有「从哪来、什么时候该重算」,它就是写死的——
改这类参数时补上「来源 + 重算条件」(范本:切镜阈值 clip(3.1×中位数,20,45) 的标定口径)。


★★ 第一工作习惯:能定点就定点,别为了"保险"全量重跑

> 这一节是本技能最高优先级的行为准则,超过任何"标准流程"。每次动手前先读一遍。
> 完整方法论(含 2026-10-10 一晚上踩两次的详细复盘)在 references/pitfalls.md 的「★铁律」段。

用户原话(三遍,语气一次比一次重):
1. 「你既然知道是 47.5 秒……直接定位到那里,把这个字糊掉不就可以了吗?
难道你还要全部重新扫描一遍吗?还要 20 分钟,太花时间了。
」
2. 「哪里没有糊到,你也知道具体是哪一秒,也要知道具体的位置。你直接定位到那里操作就行了,
用不着从头到尾扫描一遍。这点你要记住,要灵活变动。
」
3. 「能定点去做的事情,你又为了保险,改成全片扫描。这种事你一定要记得,
不然很浪费我的时间。
」

硬性判断顺序(不许跳步)

① 问题在哪?  →  报得出&quot;第几秒 + 画面哪个位置&quot;吗?
                    ├─ 报得出 → 【只改那一小段】(默认路径)
                    └─ 报不出 → 先花 1 分钟定位,再回到上面
② 只改那里行不行? → 行 → 三段拼接(前/补丁/后),统一编码
③ 实在不行才扩大范围 —— 并且要跟用户说清&quot;为什么要扩大&quot;

⛔ 明令禁止的行为:
- ❌ 「为了保险,我全量重跑一次」
- ❌ 「反正跑一遍也就 20 分钟」
- ❌ 不做定位直接套"全量扫描"的标准流程
- ❌ 已知位置却整个文件重新处理

✅ 标准动作:
| 环节 | 耗时(实测·119 秒素材) |
|---|---|
| 定点补丁(只重做 1.8 秒) | ≈1.5 分钟 |
| 定点密抽定位(只抽有问题的 7 秒) | ≈40 秒 |
| ❌ 全片重扫 | ≈22 分钟 |

代价差 15 倍。用户的评价标准是"浪不浪费时间",不是"流程走得全不全"。

适用面(不止糊字幕)

任何"已知具体位置的小瑕疵"一律定点修:
漏糊一个字 / 坏帧 / 错字 / 音画错位 / 贴纸没去掉 / 某秒画面不对 /
文案某句要改 / 某刀时长要调 …… 只要报得出坐标,就走定点。

定点修的通用三步(可复用)

  1. 定位 —— 报出第几秒 + 画面哪个位置(归一化框或像素坐标)。
    ⚠ 报坐标前先取一帧看清楚,别报一个"其实那里什么都没有"的点。
  2. 局部重做 —— 只对那一小段重新处理(糊/绘/裁/换帧/inpaint)。
  3. 统一编码拼接 —— 前段 + 补丁段 + 后段,三段一律用 libx264 -crf 16 重编再 concat。
    ⚠ 不要 -c copy 拼不同编码(会产出损坏文件,实测踩过);
    ⚠ 无损中间段写 .avi(FFV1 写在 .mp4 里会静默失败)。

灵活解决(同一口径的第二半)

规则是默认值,不是硬约束。 遇到问题先想"最小改动路径",
不要一上来就套"全量重做"的标准流程。
用户 2026-10-10:「以后我们还会遇到各种各样的问题,你要灵活地去解决。」

推论:算法"慢"要先问清是在多大范围上慢。
实测案例:cv2.inpaint 全幅做 2.4s/帧("不可用"),
只在糊区外扩 24px 的小窗上做仅 203ms/帧 —— 定点场景完全可用。
"这个办法太慢"的结论,很多只在"全量"前提下成立。


概述

一句话

同一款商品,市面上往往已经有别人拍的好几条爆款。本技能把这些原片打散成一个共享素材池,
再让每条成片走不同的画面组合 + 不同的钩子与卖点顺序,批量产出多条互不雷同的成片 ——
一个商品就能同时铺开测品,不必重复拍片。

输入 / 输出对照

维度 说明
输入 4~8 条同款商品原片(可选:用户自带文案 / 口播)
输出 一批(通常 5~12 条)互不雷同的成片(1080×1920,已带 +faststart,点开就能播,不再另出 720p 预览版);需要时可另出剪映草稿
两条产线 批量 —— 铺量测品,画面重复度只报不拦(用户 2026-10-05 定调);精品 —— 1~3 条,全池镜头评级择优
文案来源 外挂(你给稿)或从素材自身熔炼(三层提取卖点 → 先出 2 条母版 → 派生变体)
交付前保障 七道机器闸门 + 一道 AI 自查关(逐句音画复核 —— AI 自己看图,不推给用户):句首=刀界 / 每刀单镜 / 帧数=配音时长 / 同镜不重复 / 多片重合度 / 内容禁用区间 / 人物一致性
合规与风险 真人与无人平权(编排按文案择优、不回避真人;2026-10-08 取消「无人优先」);真人出镜默认开眼睛打码;唯一硬红线 同片禁换人(可辨正脸 ≤2;禁换人=前后呼应,素材里两位真人可以都用、不是二选一)。完整口径与用户原话见 Step 4 铁律七;素材里出现的价格一律不参考,只用你告知的价格

用户只把两关(v1.15.0 定)

> ① Step 3.5 文案终稿 ② 最终成片。其余全部环节统由 AI 自查 ——
> 素材体检、分镜边界复核、人脸候选确认、人物表合并、逐句音画核对,一律不推给用户"自己看"。
>
> 依据(用户 2026-10-08 原话):「这个我也看不来呀……基本上,我也就是看文案和最后成片的效果,
> 其他东西都不太会看。就像之前看那个排片素材一样,很多很多,我看不过来。」
>
> 怎么做:AI 自己出拼图、自己看、自己判。真发现疑点时,用一张图 + 一句话摊给他
> ("第 3 句说到'拉丝',画面是生的,要不要换?"),不是把原始素材、整批拼图丢过去让他找。
> 用户看不懂 EDL、也分不出两帧画面的差别;把复核放在看得见细节的一方,才是这一步真正跑得起来的理由。

触发词

【融合混剪:】 + 任务描述(素材路径 · 要出几条 · 时长要求)。

> 千枢汇 = 品牌与达人资源对接枢纽(抖音电商带货达人/招商团长)。本技能服务达人侧「同一款商品有好几条别人拍的爆款,我要批量做出自己的版本」这一场景。

触发方式

方式 触发条件
显式前缀 【融合混剪:】 后跟任务描述(素材路径 + 要出几条 + 时长要求)
隐式触发 用户给出多条同款商品原片(≥4 条),问「能出几条」「做几条不一样的」「融合一下」「别让它同质化」

与 qianshuhui-hunjian 的职责边界(必读,避免走错技能)

两个技能都涉及"文案配画面",但尺度和产物不同:

qianshuhui-hunjian 本技能(多源融合混剪引擎)
输入 1 条素材(或单个素材池)+ 1 份已定稿文案/SRT N 条同款原片(4~8 条)+ 可选文案
核心动作 一句话配一个画面,匹配即可 把 N 条原片打散成一个共享素材池,逐刀指派画面,允许跨片借入
产物 1 个剪映草稿工程 一批(通常 5~12 条)成片(1080×1920,带 +faststart);精品模式 1~3 条
关键约束 素材片段防重复使用 批量:跨条防同质化(画面重复度只报不拦,用户 2026-10-05 定调;真正避开的是「同素材+同刀位+同时长」);精品:单条全池择优
文案 必须有(输入) 外挂(3A)或从素材熔炼(3B)
草稿生成 由它负责(JyProject 路线;注意本机剪映会把它写的明文 draft_content.json 判为损坏,见 P0-7) 本技能自己生成(v1.5.0 起,走明文 info 路线,见 jianying-draft-playbook.md)

怎么选:用户给"一堆素材 + 要好几条" → 走本技能;用户给"一条片子 + 一份稿" → 走 hunjian。
串联方式:本技能产出 EDL 与配音后,若用户要剪映草稿,本技能自己生成(v1.5.0 起,明文 info 路线);
hunjiang 的 JyProject 路线在本机剪映上会失效,不要再走(见 P0-7)。

前置环境检查(每次开工先做)

> 五条逐项过。第 2 条(Python 依赖)最容易漏 —— 认人 / 扫脸 / 原片字幕这一条链最吃依赖。

  1. FFmpeg 可用:ffmpeg -version。找不到就配 qsh.json 或设 QSH_FFMPEG。
  2. Python 依赖(一小步一条,别只装 numpy 就跑):
脚本 依赖
assemble_vo.py / cuts.py numpy(cuts.py 另需 Pillow)
scan_faces.py / cluster_persons.py opencv(cv2)+ numpy + Pillow
strip_subs.py(原片字幕处理) 额外 rapidocr-onnxruntime(--subs off 时不需要)
batch_transcribe.py faster-whisper(可选,不转写就不需要)

bash python -m pip install numpy pillow opencv-python-headless rapidocr-onnxruntime
> ⚠ opencv-python-headless 在国内镜像(清华/阿里)上常缺 wheel,装不上时改用官方源:
> python -m pip install opencv-python-headless --index-url https://pypi.org/simple(实测可行)。
> ⚠ 依赖装在托管 venv 里 → 跑脚本要用 venv 的解释器(详见 pitfalls.md P1-9)。
> 系统 python 常缺包,报 ModuleNotFoundError: numpy 时看着像脚本坏了,其实是解释器选错。
> 开工先验一次 python -c &quot;import numpy,PIL; print(&#x27;deps OK&#x27;)&quot;;
> 报错就把上面的 python 全部换成 venv 解释器的绝对路径再跑。
3. 当前模型支持读图:本技能要抽帧看画面内容(判断画面主体 / 价格信息 / 配料表)。Read 工具打不开 jpg → 停下,告知用户切换支持视觉的模型。
4. 路径自检(推荐开工第一条命令):
bash python scripts/_qsh.py 2&gt;/dev/null || python -c &quot;import sys;sys.path.insert(0,&#x27;scripts&#x27;);import _qsh;print(_qsh.diagnose())&quot;
打印出 project_root / src / ffmpeg 三行,确认没有取到默认值(默认值 = 没配好)。
5. 口播文案来源先确认(走 3B 才需要,但开工就要问,见 Step 3 铁律):按
用户提供 → 本地 faster-whisper → whisper.cpp 的优先级来。
- 有现成文案 → 直接进 3B,不转写(用户的稿子最准)。
- 没有 → batch_transcribe.py(需 asr_model 配好)。
- 都没有 → 先问用户同不同意再部署 whisper.cpp(模型约 190MB),
不要默默开始下载。部署步骤见 references/script-synthesis.md §二。

项目配置 qsh.json

在项目工作区根目录放一份(本技能所有脚本共用):

{
  &quot;root&quot;: &quot;D:/workbuddy/my-project&quot;,
  &quot;src&quot;: &quot;C:/Users/&lt;用户名&gt;/Desktop/&lt;素材目录&gt;&quot;,
  &quot;ffmpeg&quot;: &quot;D:/ffmpeg/bin/ffmpeg.exe&quot;,
  &quot;ffprobe&quot;: &quot;D:/ffmpeg/bin/ffprobe.exe&quot;,
  &quot;fps&quot;: 30,
  &quot;asr_model&quot;: &quot;D:/workbuddy/my-project/work/models/fw-large-v3-turbo&quot;,
  &quot;asr_prompt&quot;: &quot;商品名,产地,品种,卖点关键词,逗号分隔&quot;
}
字段 作用 取不到时的表现
root 项目根(work/ output/ 都挂这下面) 取默认值 → 等于没配好
src 素材目录 脚本找不到源片
ffmpeg / ffprobe 可执行文件路径 找不到就靠 PATH
fps 出片目标帧率(默认 30) 帧数换算错
asr_model 本地转写模型目录(走 3B 才需要) 转写直接失败
asr_prompt 转写热词(品名 / 产地 / 品种) 专有名词被同音字污染(P1-5)

> 也可用环境变量 QSH_ROOT / QSH_SRC / QSH_FFMPEG / QSH_FFPROBE / QSH_CONFIG 覆盖。命令行参数优先级最高。

执行流水线

> 九步流水线。只有 Step 3.5(文案终稿)与 Step 7(成片)两步需要用户点头,其余全由 AI 自查。
> 编号直接跟 Step 号走,与闸门的 ①~⑦ 是两套编号,别混。

Step 做什么 谁做 把关
0 建任务清单 + 五个必问 AI 问 / 用户答 —
1 素材体检(切镜 / 扫脸 / 认人 / 标注 / 转写) AI 自查
2 产量测算(批量可行性预检 / 精品全池评级) AI 自查
3 文案矩阵(3A 外挂 / 3B 熔炼 + 骨架推荐) AI —
3.5 文案评审关 AI 出稿 / 用户看 ★ 用户点头
3.6 配音五问(音色 / 停顿 / 留白 / 语速 / 情感) AI 推荐 / 用户定 —
4 融合编排(出 EDL · 四铁律) AI 自查
5 配音合成(静音治理 / 零漂移 SRT / 字幕细切) AI 自查
6 七道闸门校验 + 逐句音画自查 AI 自查
7 出片与交付 AI 出片 / 用户看 ★ 用户点头

Step 0 · 建任务清单 + 五个必问

> ⚠️ v1.24.0 起是「五个必问」(原六个)—— 「配音五问」已移出,
> 改到 Step 3.6(文案定稿后、排镜之前) 问一次。原因见下面第 5 条。

  1. 建任务清单:用 TaskCreate 建 9 项,编号直接跟 Step 号走(避免和下面的 ①~⑦ 闸门混淆):
    Step 1 素材体检 / Step 2 产量测算·全池评级 / Step 3 文案矩阵 / Step 3.5 文案评审关(人工闸门)
    / Step 3.6 配音五问(文案定稿后·排镜前) / Step 4 融合编排 / Step 5 配音合成
    / Step 6 七道闸门校验 / Step 7 出片与交付。
  2. 必问一 · 文案怎么来(决定 Step 3 走 3A 还是 3B)——不问「有没有」,主动把两个选项摆出来让用户挑:
    > 「文案这一步你想怎么来?
    > A. 你提供现成文案 —— 我只做分配与编排(你的稿子最准)。
    >  拿到后我先看整体:卖点打不打、人味够不够、同批几条是不是一个模板
    >  (这才是同质化的主因)。画面只查明显矛盾的(比如文案说拉丝、画面是生的),不会因为「这句没对应镜头」就建议删——画面匹配是加分项,不是通行证。
    > B. 我从这批素材里熔炼 —— 我提卖点、归纳钩子,按目标条数出母版(1 条就 1 母版)给你审。
    > 也可以 A+B:你给主线,我按素材补几个只有这批素材才有的卖点。」

—— 画面与文案的关系(用户 2026-10-06 定调· 别写死):
· 卖点句(软糯拉丝/颗粒饱满/开箱)→ 尽量配画面,但没有也能用,卖点好就留;
· 独白句(孩子上学/菜市场/产地介绍)→ 不一定需要画面,有则更好;
· 唯一硬线是不矛盾。「整箱十四根」配几根画面可以用;「拉丝」配生的玉米才是矛盾。
· 排镜时凑不到镜头 → 换文案或换镜头,不要回头删文案。
· 完整口径 + 踩坑记录见 references/script-synthesis.md §五·补。

—— 三条硬规则:
- 无论用户有没有文案,都必须问这一句,不许替他假定。用户自己说"我有稿子"也要问一遍,
因为他还可能想让你从素材补点他没想到的东西。
- 不许静默替用户选创作方向。要熔炼必须用户明说。
- 用户不提供文案 ≠ 你只能熔炼——也可能他选择"先不写文案,先看素材里有什么",
那就先跑 script_mine.py 出底表给他看,再回来定通道。
3. 必问二 · 生产模式(决定 Step 2/4 的取镜策略):
- 用户已说条数 → 按 1~3 条 = 精品、≥4 条 = 批量,以用户为准,不用问。
- 用户只问"能出几条" → 先按批量给产量区间,并提示"只想做 1~2 条精品的话可以走全池择优"。
- 用户要 3~4 条(两可地带)→ 必须问,不要自己定。详见 references/production-modes.md §二。
4. 必问三 · 商品口径(v1.7.0 新增)——这一问专治本技能最大的一笔返工:

> 「开工前先对齐三个口径,任一项没问清我就不往下走:
> ① 产地 / 品种 —— 你这批货卖的是哪个产地、哪个品种?
>  (你手里这批素材的标题和口播写的是另一个产地,我不会默认顺着素材写。)
> ② 规格 —— 单果规格、净重(几斤装)要不要写进文案?
> ③ 价格 —— 本轮写不写价格?写的话多少钱、什么计价单位?」

—— 三条硬规则:
- 素材标题里的产地 ≠ 用户卖的产地。 2026-10-01 冬枣批次实测:7 条素材标题全部写
「陕西大荔」(#大荔冬枣 #新鲜采摘),用户实际卖的是山东沾化。我按素材默认写成
「陕西大荔」,文案 / 全池评级 / 配音脚本做完后整批作废重做,白烧约 20 分钟。
产地必须由用户说,不许从素材推断——素材是"别人拍的货",不是用户卖的货。
- 口径变更 = 换池重做,不是改几个字。 产地一变,「哪条素材能用」的判断跟着变
(本项目可用池从 4 条 / 104s 扩到 6 条 / 572.3s;7 条素材总长 594.3s,其中素材6 整条排除 22.0s)。
且画面里的产地贴纸 / 原片口播若与用户口径
冲突(本项目素材4/5 左上角有「大荔冬枣」烫金贴纸、素材7 原片口播 3 处念「大荔」),
单独列给用户由他定(遮 / 换 / 原样保留),不替他决定。
- 价格规则照旧(见"既定参数"表):素材里出现的价格一律不参考,只用用户告知的;
未告知则本轮不写,并避开带价格的画面区间。规格数字同理——用户说不写就不写,
并把原片里念叨规格的画面一并避开
。
5. (原「必问四 · 配音五问」已移出 → Step 3.6) · v1.24.0 · 2026-10-10 用户定调:

配音五问不在开工问 —— 音色要看的四样依据(可辨真人 / 条数 / 骨架 / 文案)开工时三样都还没有,
问早了必回头重问;也不许拖到 Step 5 —— 语速 / 停顿一改,「每句时长 → 句首 → 画面切换点」全变,整条排镜作废。
唯一正确位置 = 文案定稿后、排镜之前(Step 3.6),只问一次。 理由与用户原话见 Step 3.6 与 references/voices-user.md。

  1. 必问四 · 交付形态:直出成片 / 出剪映草稿(2026-10-06 新增,必须问,不许默认选):

> 「出片这一步你要哪种?
> A. 直出成片 —— 高清 mp4 直接给你,字幕已经烧在画面里,发出去就能用。
> B. 出剪映草稿 —— 给你一份能在剪映里打开的草稿工程,你在剪映里自己精修字幕/调色/换配音。
> C. 两条都要 —— 先出成片,再附一份草稿(多花一轮时间,但改起来方便)。」

—— 三条硬规则:
- 必问,不许替用户默认选 A。默认选 A 是最常见的错:用户要改字幕/换BGM时,
直出成片就得重出整片(字幕是烧进画面的,改一个字都要重跑);
而草稿路线改字幕是零成本(拖一下就行)。
- 必问,即使只出 1 条。批量出片时开工问一次即可(问「这批都要 A / 都要 B / 混合」);
1~2 条时逐条问——同一批里有的要成片、有的要草稿是常事。
- 问了之后不许中途改口。已按 A 出了成片,用户又说"还是给我草稿" →
需要重出画面(--subs strip 重跑,字幕改由草稿字幕轨承担),这时必须提前说清要重跑一遍,不许默默重做。

—— 两条路线的技术差异(决定为什么必须提前定):

项 A 直出成片 B 剪映草稿
--subs burn(糊原字幕 + 绘我们的字幕) strip(只糊不绘,字幕交给草稿字幕轨)
切片 用主套 片段_XX/ 用净版 片段_XX_净/(v1.10.5 起同一次出片两套)
字幕可改性 烧进画面,改一个字重出全片 草稿字幕轨,拖一下就行
中间产物 出片后可清 片段_XX/ 不能删不能移,移动后剪映打不开

⚠ 两条都别用 burn 配草稿(画面已烧字幕 + 草稿再加一层 = 重影),
也别用 strip 出成片(成片就没字幕了,违反规则 A1)。

  1. 必问五 · 打码口径(用真人时要不要开眼睛打码)(v1.14.0 改定,必须问,默认开):

> 「画面我会按文案和排片自由选 —— 真人镜头和产品镜头放一起比,谁贴用谁(不再"无人优先")。
> 真人镜头默认开眼睛打码(出片时自动把眼睛糊掉),可以吗?」

—— 三条硬规则:
- 问的是"打码",不是"用不用真人":用不用真人由 AI 按文案与排片自决,不许拿去问用户(2026-10-08 用户拍板)。
用户能拍板的只有"真人出镜要不要打码"。
- 默认开打码,且必须在 Step 0/Step 1 定死:用户没说不开 → 出片真开 --faceblur eye、⑥ 闸门配 --faceblur;
用户明确说"不打码" → 按他说的执行。⚠ 出片时才想起打码就晚了(要重跑一遍画面)。
- 首次启用/关闭时说清风险一次(之后按用户口径执行、不再重复劝阻):
打码只对「人脸识别 / 账号关联」有用,对画面查重 / 语义查重 / 著作权毫无帮助;
且「只糊眼睛」在法律上基本无效。完整口径见 Step 4 铁律七·补。

Step 1 · 素材体检(第一段)

  1. 规格探测:ffprobe 逐条读分辨率/帧率/时长。素材规格不一致是常态(1080×1906 / 1078×1920 / 720×1280 / 120fps 混在一起),记下来——出片时靠 cut_multi.py 的 --norm 逐刀归一化抹平。
  2. 双轨切镜(切镜错了后面全白做,见 references/shot-boundary-playbook.md):
    bash # 轨道一:ffmpeg 场景检测粗筛(快,但反光/快动会误报、软切会漏) python scripts/scan_shots.py --src &quot;&lt;素材目录&gt;&quot; --out work/shots --thresh 0.30 # 轨道二:逐帧灰度差定权威剪辑点表(慢一点,但可信) python scripts/cuts.py scan python scripts/cuts.py diff &lt;素材名&gt; # 逐条自查:有没有漏切 python scripts/cuts.py shots # + 修正表 → work/shots/shots_final.json # 按「失效特征」扫全片(只提示,不改任何东西);跑不过的规则会被 verify 揪出来 python scripts/fix_rules.py scan --cuts work/cuts/cuts.json python scripts/fix_rules.py verify --fix work/shot_fixes.json --cuts work/cuts/cuts.json
    - 扫完先看 fix_rules.py scan 的输出,它会按失效特征列出「哪一段值得抽帧看一眼」——
    软切长镜、反光/手快动的高噪声段、挤在 0.35s 内的过密切点。这是从"全片盲搜"到"定点核验"的入口,
    也是当初靠 0.1s 抽帧才找到的那类漏切/误报能被自动翻出来的原因。
    - 规则只提示,边界真值只有目视能定(铁律五)。dense_probe.py --step 0.1 抽帧确认后才写修正。
    - ⚠ 要用抽帧推翻一个已有结论(尤其是人工定出来的边界)之前,先跑 --calib 校准工具:
    python scripts/dense_probe.py --name &lt;素材&gt; --t0 34.68 --t1 34.88 --calib ——
    确认「请求时刻 → 实际落帧」偏差 ≤1 帧(60fps 素材单帧只有 0.0167s,先用 ffprobe 看清 fps)。
    否则你推翻的可能只是自己的工具误差,不是对方错。同时别默认"自动点就是误报":
    2026-09-18 素材1 的实例里,人工补的点反而偏早 0.17~0.28s,自动点才是对的。
    - work/shot_fixes.json 是 v2 结构:patches(本项目的具体修正)+ rules(项目特有规则,一般留空);
    「什么样的画面特征会导致切镜失效」写在技能内的 references/shot-fix-rules.json(可跨素材复用,v1 表会自动迁移)。
    - 修正按三种失效写:manual_shots(软切,整段给边界)/ drops(误报,删点)/ adds(漏切,补点)。
    每条都要写核验依据(抽帧间隔 + 看到了什么),note 会打印在 shots 的输出里。
    - 排 EDL 前用 python scripts/cuts.py check &lt;素材名&gt; &lt;t0&gt; &lt;t1&gt; 逐刀确认窗口内无剪辑点,比事后返工便宜得多。
  3. 人脸候选扫描 + 人物聚类(机器初筛,v1.7.0 / v1.8.0):

3a · 有没有脸(产出 work/banned.json 的原料):
bash python scripts/scan_faces.py # 全片密抽帧(默认 0.1s/帧)+ YuNet python scripts/scan_faces.py --name 素材4 # 只扫一条
产出 work/facescan/:checklist.md(逐条确认表)+ &lt;素材&gt;_sheet.jpg(强候选代表帧拼图)
+ candidates.json。
> ⏱ 耗时约 0.85s / 素材秒(594s 素材 ≈ 8.5 分钟,4 进程并行)。建议后台跑,同时干别的活。
- 为什么要机器扫:此前靠稀疏抽帧 + 肉眼找真人区(3s 一帧),系统性漏标 ——
本项目漏掉素材4 的 4 段真人区、素材5 的 1 段,EDL 排完才发现两刀排进了真人正脸,
返工约 40 分钟。改成 0.1s 密抽帧后漏报概率降到接近 0(任何 ≥0.1s 的连续真人画面必被命中)。
实测验收(本批 7 条素材 / 594s):把机器候选与已确认的 banned.json 对账,
21 段已知真人/禁用区被 100% 覆盖(覆盖率 110%~200%,>100% 是区间外扩 0.5s 所致)——
零漏检,对照旧流程的漏 5 段。
- ⚠ 机器只出「候选」,不下结论:YuNet 在农产品带货实拍上假阳性率极高 ——
实测素材3(17s)170 帧全部命中、强候选 2 段共 15.4s,但框全部落在枣/树叶/袖子/篮子上,
零真人;素材7 报 3 处"人脸"全是误检;素材2 报 13.7s 实为箱内枣 + 手部。
必须逐段看拼图确认(checklist.md 每条填 真/假),确认后才写 banned.json。
- 判定口径:能看清面部五官 = 真;只有手 / 背影 / 产品 / 衣物被误框 = 假。
拿不准的回原片密抽帧看前后 1s(dense_probe.py --step 0.1)——真人往往只在某一帧露脸。
- 与逐句音画自查关(qc_sync_frames.py)互补不替代:那只查排进成片的刀,本步查全片。

3b · 是谁(认人;产出 work/persons/,v1.8.1 起无论走哪一档都必须跑一次):
bash python scripts/cluster_persons.py # 全池聚类(YuNet 检测 + SFace 特征) python scripts/cluster_persons.py --name 素材4 python scripts/cluster_persons.py --dump-sim # 调阈值时导出相似度分布
> ⚠ 无条件都要跑,不是"备查"(用不用真人、打不打码都一样)—— 第 ⑦ 道闸门(人物一致性)
> 的输入就是 work/persons/persons.json,缺它直接退 2「环境没备齐」。
> 跳过 3b 的人会在 Step 6 撞墙。跑一次的收益:① ⑦ 闸门有据可判
> (连"这条片里到底有没有真人"都是它判的);② 禁用表兜底;③ 万一后面想加真人镜头,
> 人物表已经在手。全池约 3~6 分钟,可后台跑。
> 注意:全池零命中(一条脸都没有)时 persons.json 里没有人 —— 此时
> check_persons.py 会报"人物表里没有任何人物"退 2。真遇到就手工把 EDL 与自己
> 目视核过的结论写进 banned.json,并在交付说明里注明"全池零可辨真人,⑦ 无输入"。
产出 work/persons/:persons.json(人物分组 + 区间表)+ P01.jpg/P02.jpg…(每人代表帧拼图)
+ _overview.jpg(总览图)+ report.md(含「疑似同一人」对账表)。
- 为什么必须认人:早期把「有脸 → 整段禁用」一刀切,等于把可用池砍掉一半
(本批 素材4 的 0–82s、素材5 的 0–30s 全是连续真人,全被禁掉)。
问题从来不是"有真人",而是"一条片里换人了" —— 观众读出的不是"这产品好",
而是"刚才那个人哪去了"。正确顺序:先认人 → 每条片定一个主角 → 副人物按文案需要准入。
- 阈值:SFace 比 128 维特征的余弦相似度,本人不同帧常见 0.6~0.95、
不同人 0.0~0.35,判同人阈默认 0.55(落在「同人 0.6~0.95 / 异人 0.0~0.35」的空档上方)。
宁高勿低 —— 把两个人并成一个(漏判)会让「换人」直接混进成片;
把一个人拆成两半(误判)只是多一组待确认的代表帧。
- --det-score 别随便调低(默认 0.85):「手上一把枣」会被 YuNet 判成脸,
而枣长得都一样 → 误检会稳定地聚成一簇,靠簇大小过滤根本没用。
实测真脸 0.93+、枣误检 0.53~0.72,0.85 是干净的分界。
(肤色占比救不了:红枣的红色正好落在 YCrCb 肤色范围内,实测误检 0.45~0.88 vs 真人 0.90~0.98,重叠严重。)
- ⚠ 缩略图上认人 = 必错:本批把同一条素材里两位女主播(白衬衫 / 粉衬衫)的缩略图并排看,
第一眼会判成「同一个人换了衣服」;放大裁脸后一目了然是两个人
(肤色 / 眉形 / 鼻翼 / 脸型全不同),而机器判的 0.308 才是对的。
所以 P*.jpg 拼图只能用来「复核机器」,不能用来「替代机器」。
- report.md 的「疑似同一人」表怎么用:同一个人换衣服 / 换光线时簇内均值会掉到阈值
以下而被拆成两簇,但两簇间仍有若干帧高度相像 —— ≥0.55 基本就是同一人(应合并);
<0.40 基本不同人;0.40~0.55 是模糊带,必须并排看图定。
- 产品 / 手部 / 空镜不受人物约束 —— 只有「可辨正脸」的刀才归人。
4. 逐镜内容标注(关键步,靠读图):
- 先做低分辨率总览图快速过一遍,再用 dense_probe.py 对可疑区间加密抽帧复核:
bash python scripts/dense_probe.py --src &quot;&lt;素材目录&gt;&quot; --name 片E --t0 0 --t1 6 --step 0.4
- 每个镜头记四件事:画面内容(是什么、在做什么)、是否有清晰人物主体、是否含价格信息、是否有画面内嵌文字/竖排文字。
—— ⚠ 登记「有内嵌文字」是为了知情。原片口播字幕(v1.9.0 起)已在出片时默认处理
(cut_multi.py --subs burn:逐刀实测字幕矩形 → 只糊那一块 → 重绘本片字幕);
其余静态贴纸 / 包装印刷文字仍不处理,交用户自行处理
(见"既定参数"表与 pitfalls.md P0-12)。
- 不要凭低分辨率缩略图下结论——本技能踩过最大的坑就是 160px 缩略图把"全程含人物主体"误判成"包装展示",导致整条片白做。可疑处一律加密抽帧复核。
5. 口播文案(走 3B 熔炼时才需要;优先用户提供,见 script-synthesis.md §二):
bash python scripts/batch_transcribe.py --src &quot;&lt;素材目录&gt;&quot; --root &quot;&lt;项目根&gt;&quot;
输出 work/transcript_&lt;名&gt;.json/.txt/.srt。asr_prompt 里务必写商品专有名词(品名/产地/品种),否则同音字错得离谱——实测「敖汉旗」会被转成「熬汉奇/汉黄/翰黄」、「净含量」变「金含量」。
- 用户手上已有逐字稿就别转写——机器转写必错几个专有名词,用户的稿子最准。
- 两条都没有 → 先问用户同不同意再部署 whisper.cpp(约 190MB),不要默默开始下载。
6. 产出体检报告:output/千枢汇-&lt;主题&gt;素材体检报告-&lt;日期&gt;.md,含每条片的规格、镜头数、可用画面总秒数、禁用区间清单(人物主体 / 价格信息 / 竖排文字)。
同时把禁用区间编码成 work/banned.json(第 ⑥ 道闸门的输入):真人区来自第 3 步
scan_faces.py 的候选经逐条看图确认后的结果(v1.15.0:AI 看拼图判,不推给用户),价格区/文字区来自第 4 步标注。
人物表 work/persons/(第 3b 步)保留不动 —— 它是第 ⑦ 道闸门(人物一致性)的输入,
也是 Step 4 编排时「指定主角 / 准入副人物」的唯一依据。

#### 1a · ⚠️ 标注禁用区间前,先判「能不能技术去掉」(v1.10.3 新增)

不要一看到价格条/文字条就整条禁用。 判为「整条不可用」之前,
必须先穷举技术去化路线 —— 玉米批实测:素材2 因右上角全程贴价格条被整条禁用,
但其实 delogo 一道滤镜就能去掉(全片 25 采样点目视无残留、看不出填充痕迹),
一条 50s 的一镜到底长素材因此复活,成了整个批次唯一能做 30s 长版的源。

常见可去化对象与对应手段:

画面上的东西 去化手段 实测效果
固定位置的价格条 / 促销贴纸 delogo=x=..:y=..:w=..:h=..(框要比实测 bbox 四周各留 10~20px) 纸箱/铝膜等平滑纹理上完全看不出痕迹;每 2s 抽一帧全片目视核验
快递面单 / 隐私信息 同上(区域小,成功率高) —
硬字幕 已有现成流程(--subs burn/strip,见下) —
竖排文字 / 台标 一般无解(位置分散、每帧不同) 只能禁

crop 裁切是下策,且经常是错的选择:玉米素材2 实测
crop=856:1520:112:400 虽能去掉价格条,但画幅被腰斩、主体被切掉大半,
还把原字幕带位置搞乱。delogo 保住完整 1080×1920,效果远好于裁切。

判断顺序:delogo(首选)→ 模糊/高斯(次选,痕迹明显)→ crop(下策)→ 禁用(最后手段)。

落地做法(原素材一律不改,另存副本):

bash mkdir -p work/src_delogo ffmpeg -i work/src_link/素材N.mp4 -vf &quot;delogo=x=205:y=298:w=680:h=110&quot; \ -c:v libx264 -crf 16 -preset medium -c:a copy -y work/src_delogo/素材N.mp4 # 出片时 --src work/src_delogo,后续所有流程不变

副本要参与同源查重(避免同一画面被算成两条不同素材),交付时说明用了副本。

反过来说:如果用户的商品口径允许出现价格,那价格条本身就是卖点,
直接用原素材,连 delogo 这一步都省了。所以这一判定的顺序是
先问口径 → 再判去化,不要反过来。

#### 1b · 价格贴纸:不再整条禁用,改为出片时"糊除 + 重绘"(v1.10.5 口径变更)

原口径已废:旧规则是「素材带价格 = 商业诋毁红线 → 必禁、永不可豁免」。
实测代价太大:本批 87 镜带价格,且能承载长句的长镜全在其中
(无价格长镜最长仅 5.0s)→ 禁掉后 A1 从 10 刀反弹到 15 刀、最短 0.43s(退回小分镜)。

新口径:带价格素材照用,由 engine/price_relabel.py 在出片时
糊掉原贴纸 → 重绘为我们的价。配套改动:
- app/annotate.py::_auto_ban() 移除 price 判定 → 禁用表只剩 person 类;
- 用户给的价:19.9 元 / 整箱 12 根(本轮)。
- 位置策略见 §既定参数「价格贴纸处理」:我们的价画在全片统一基准框,不跟原贴纸走。

> ⚠ 这一条推翻了「价格必禁」,但没有推翻「素材里的价格不参考」——
> 我们只关心"糊掉它",从不抄它的数字。仍只用用户告知的价格。

Step 2 · 产量测算(第二段)——两条分支

> 先按 Step 0 必问二的结论选分支。完整对照见 references/production-modes.md。

2.0 · 素材形态分型(v1.10.1 新增 · Step 2 必做,不做会排错)

用户原话(2026-10-05):
> 「爆款视频素材这个东西怎么说呢?比如黄糯玉米,里面的素材可能都是一些一秒或两秒的小镜头;
> 但有些品也有可能是一镜到底的视频。所以每个产品找来的素材,可能多多少少都会有这种问题:
> 有可能是小片段镜头拼接,也有可能是一镜到底的长视频。各种各样的视频都会出现。」

素材形态不固定,所以编排策略不能写死 —— 先分型,再选策略。

python scripts/solve_shots.py probe --root &lt;项目根&gt;

> 镜头表自动探测 work/shots/shots_final.json → shots.json(与各校验脚本同一套口径,
> v1.15.1 修 —— 旧版默认读的 shots_render.json/pool.json 是单源工具的文件名,
> 本技能不产
,按原话跑会直接报错退出)。缺表退 2、表空退 2,不会"空表 + 退 0"。

输出每片一条:段数 / 总时长 / 均长 / ≥2.5s 占比 / 型别 / 最多几句。

型别 判据(均长) 首要动作 反面做法
小分镜拼接型 < 2.5s 减句数(不是减字数) ❌ 硬塞 11 句 → 拆成 16 刀碎刀
混合型 2.5~4s 且长段 <60% 分段处理:长段给核心卖点 ❌ 平均用力
一镜到底型 > 4s 或长段 ≥60% 放心做 5~8s 长镜头,每句 20~30 字 ❌ 为凑句数切碎长镜头

参照系是 TTS 单句时长(≈2.3s),不是拍摄习惯。
豆包 TTS(lrate=+8)实测 4.2~4.7 字/秒 → 一句 10~14 字约 2.0~2.6s。
(这正是「文案时长双标注」的两个档位常数来源 —— 1.2 倍 ≈ 5.2 字/秒、1.0 倍 ≈ 4.3 字/秒,
折算过程与标定要求见 references/voices-user.md §四。)

> 实测(2026-10-05 玉米批):素材9 均长 2.70s / 素材11 均长 2.19s,
> probe 判「素材9 最多 5 句、素材11 最多 6 句」——最终排 7 / 6 刀,与判据吻合。
> 而素材1/4/10/12 均长 1.2~1.3s,probe 判「0 句可用」,正是那批同源废片。
> 分型不是理论,是能直接给出「这批素材能出几条」的判据。

分型之后:镜头序列写进 work/plan.json,配音后跑 check 逐句校验
(用法见 references/production-modes.md 第〇之二节)。
文案句数由此决定,不再是拍脑袋定的。

分支 A · 批量模式(≥4 条)

算法:理论可出条数 ≈ 各片可用画面秒数之和 ÷ 单条时长 ÷ (1 + 借入系数),再按"骨架片"分摊。

  • 单条时长怎么定(v1.8.1 明确 · 不许默默取默认值):
    ① 用户明确给过 → 用它;
    ② 没给 → 把默认值摆到用户面前对一眼:「本次按 30s/条 测算(常规 20~40s),要改说一声」;
    ③ 用户说"你定" → 取 30s,并在交付说明里写明这是默认值。
    它决定后面所有配额,默默取了 30s 而用户心里想的是 15s,整批配额全错。

  • 可行性预检(v1.8.1 新增 · 必须在排 EDL 之前做):

项 怎么算
可用池 Σ 各片体检后的可用秒数(不是原片总长)
同源折扣 先跑 scan_dupes.py;查出 ≥50% 同源的片子只计一条
骨架需求 N 条 × 单条时长 × 骨架占比(0.6~0.7)
判据 骨架需求 ≤ 可用池 × 0.8(留 20% 余量,抵掉取镜粒度与内容损耗)

结论写成人话,直接给用户:
- 够 → 「按当前池子,N 条可行(骨架需 Xs,池子 Ys,余量 Z%)」;
- 不够 → 「按当前池子,N 条不可行 —— 骨架需 Xs,池子只有 Ys,建议降到 M 条」。

> 为什么必须在这里拦:⑤ 是出片前的最后一道。等排完 EDL、配完音才发现池子不够,
> 那半天就白干了。越早拦越便宜 —— 这是本技能一贯的原则(三问 → 3.0 预检 → 评审关同理)。

  • 骨架片概念:每条成片以一个原片为主干(占 60~70%),其余从别片借入(30% 上限,由用户设定)。
  • 可用池薄弱的片子只能当供应商(借出画面给别人),不单独做骨架——例如某条片大量画面含人物主体,可用池只剩十几秒。
  • 输出建议表:每条片的骨架条数 × 借入来源,并给出总量。用户要 10 条就据此反推骨架分配(如 4 片各 2~3 条)。
  • 顺手查一遍同源 → python scripts/scan_dupes.py(dHash 感知哈希,每 0.5s 采样、汉明距离 ≤6 判同帧,分母取较短者采样数,与闸门⑤ 同口径)。同一场戏不同人发的原片经常大面积重合(实测遇过两条重合 67%),这种片子只能保留一条,否则"互不雷同"是假的。
    > ⚠ 同源有两个不同的问题,别混为一谈:scan_dupes.py 查的是「同一段画面被发了两遍」(时间轴对不上但画面相同,闸门⑤ 看不见,只有它看得见);cluster_persons.py 查的是「是不是同一个人」(同一场拍摄的不同片段,画面可以完全不同)。本项目实测:素材4/5 人物同源(共享面孔/箱子/字幕版式)但 scan_dupes.py 报 0.0% 画面重合 —— 两者都对,各说各的。

分支 B · 精品模式(1~3 条)——不算产量,改做「全池镜头评级」

把全部素材的可用镜头按三个维度打分排序,输出 Top N 清单:

维度 看什么
卖点含量 这个镜头能不能支撑一句卖点(强支撑 = 高)
画面冲击力 前 5 秒候选 / 高光成品(拉丝、米油、爆浆)/ 大份量堆叠(前 5 秒候选额外加权)
独家性 全池里只有这一条有(配料表、产地实拍)

产出 output/千枢汇-&lt;主题&gt;-全池镜头评级-&lt;日期&gt;.md。编排时从这张表取,不按骨架配额取——
不分配骨架、借入不设上限,把全池最好的镜头集中到这一两条里。
先按 script-synthesis.md §四 出 2 条母版,镜头再与母版的气质对齐(冲击型母版配冲击镜、共鸣型配场景镜)。

Step 3 · 文案矩阵(第三段)——双通道:3A 外挂 / 3B 熔炼

> 前置:Step 0 必问一已经有答案(用户选的是 A / B / A+B)。
> 用户提供文案 → 3A;用户选择熔炼 → 3B。不许把 3B 当默认动作。


3.0 · 文案 → 画面矛盾排查(不是逐句预检 · 3A / 3B 都要过)

> ⚠️ 口径已改(用户 2026-10-06 定调)· 旧版「逐句支撑预检」已作废
>
> 用户原话:
> > 「其实很多视频素材的文案,很多都是独白来着的。比如说:孩子每天早上上学吃一根。
> > 素材里也不会呈现孩子早上吃玉米呀。并不是说每一句文案非要匹配对应的画面片段。
> > 但是有些就要对应得上,比如软糯拉丝,就是配画面了。这个你得自行判断。
> > 画面重要,文案也是很重要的。
」
> > 「你是 AI 自动的,不要把所有东西都写死。」

旧版做法是错的:逐句 × 四档支撑等级 × 「无支撑 → 上报用户三选一」,
把「东北黑土地」「孩子上学」「菜市场」这类独白句判成"没画面",
然后逼用户逐句做「改/删/补」三选一 —— 既丢了人味,又违背用户口径。
(2026-10-06 实测:东北糯玉米批因此删掉一批好句子。)

现在的做法:
1. 先整体判三件事(这才是同质化的真病因):
① 卖点打不打 ② 人味够不够 ③ 同批几条是不是同一个模板
(实测:5 条开头钩子全不同✅,但9 句在 3 条以上重复 → 观众第 2 条就划走。
做法:拆句统计出现 ≥3 次的,9 句降到 2 句为合格线,剩下的必须是价格/规格这类合规必需的。
详见 references/script-matrix.md §四。)
2. 画面只在「明显矛盾」时才逐句核,触发条件二选一:
① 读到某句时觉得画面会给不出甚至会打脸(如文案说"拉丝"、画面是生的);
② 用户主动要求核画面。
3. 「矛盾」才上报用户三选一;「没对应画面」不上报、不建议删。

等级 判据 怎么处理
强支撑 池里有镜头直接就是这句话在说的东西(目视确认过) 直接排
可借入 本片没有、但池里别的素材有 记进借入清单(受借入上限约束)
近似 只有近似画面(说"米油"只找到一锅粥) 可用。是卖点句就让画面往文案靠;文案能改得更准就改,但不必改
无对应画面 全池找不到相关镜头 —— 多数是独白句,正常情况 照用。画面给商品本身/生活近景即可,不上报、不建议删(用户:「独白句不一定需要画面,有则更好」)
⚠️ 矛盾 画面会打脸文案(说"拉丝"画面是生的 / 说"十四根"画面是散装 / 价格与原片贴纸冲突) 唯一需要上报的 → 三选一(改文案 / 换画面 / 用户定)

> 判据落地:只有矛盾才触发上报。判「矛盾」时问自己一句
> ——「观众看到画面,会不会觉得这句在骗人?」不会 → 那就不是矛盾,是独白。

专项 · 涉及「人」的句子怎么判(v1.8.1 新增) —— 只在判矛盾时额外问一句:
这句话必须要真人出镜吗?

句子的说话对象 判法
产品(口感 / 产地 / 新鲜 / 包装 / 应季) 无人画面通常能撑 → 不矛盾;产品镜头与真人镜头按画面择优,不强制无人
人的动作(咬 / 吃 / 拿 / 递 / 掰) 人本位动作是真人该上场的地方,优先配真人;无人区有代偿(掰开 / 断面 / 汁水)也行 → 都不算矛盾。实在都对不上才改措辞("咬开一口"→"掰开一个")
人物关系(我妈催我买 / 孩子一次吃七八个) 属口播叙事,画面给产品即可,不算弱支撑("人声讲故事 + 产品 B-roll"是行业常态),不必为此硬塞人脸

> 口径:真人镜头与无人镜头平权,按「谁更贴这句台词 + 画面更好」选(铁律七)。
> 只要一条片里出现了可辨正脸,全片真人刀的人物集合就要固定 —— 不许中途引入别人。
> 「禁换人」=前后呼应,不是「限用一位」(2026-10-09 用户澄清,刮毛器批):
> 用了一位就用到底;素材里有两位真人可以两位都用(有真人出镜效果可能还更好,
> 用不用、用几位由 AI 按画面自判),前面用了两位,后面再出真人还得是这两位。
> ⚠ 曾把这条错执行成「同条片两人只能取其一」—— 方向错了,以本段为准。

⚠️ 旧版残留段· 现在只服务「矛盾」场景(等级表里已没有「无支撑」档,
「无对应画面」= 照用)。「矛盾句」的三条出路(列给用户选,不要自己替他决定):
1. 改 —— 改写这句话(保住卖点意思,换成画面撑得住的表达);
2. 删 —— 这句不进本轮;
3. 补 —— 用户补素材进来,或换一个池里真有画面的卖点顶上。

为什么不能硬配:画面与台词对不上,观众一眼就识破。
实测事故:台词「回购过好几次了」配了「真人吃玉米」的镜头,那五道机器闸门全部报通过——
自动校验抓的是时间对齐,抓不到"画面内容与台词不是一回事"(只有逐句音画自查关的抽帧拼图能抓到)。
铁律二「每刀画面 = 该句台词所指」就是在这里死的。

> ⚠️ 但铁律二不反过来当文案筛选器用 —— 它是排镜阶段的落位要求。文案阶段因为「没画面」就删句子是错的(用户 2026-10-06 定调,见 script-synthesis.md §五·补)。

产出(只在真的发现矛盾时才出这份文件;没有矛盾就不出、不报):
output/千枢汇-&lt;主题&gt;-文案画面矛盾排查-&lt;日期&gt;.md,一行一句:
句号 | 句子 | 等级 | 对应镜头(素材X Y–Z 秒)| 备注。
完整口径见 references/script-synthesis.md §五·补(用户 2026-10-06 定调)。

顺序差异:
- 3A(用户文案):文案是既定的 → 通读一遍找矛盾句(不是逐句判支撑),
只有矛盾句退回处理,其余照进分发编排。
- 3B(素材熔炼):矛盾与否本来就是第二层选举的输入,边熔炼边得到;
出品前再通读一遍——派生变体时改了词,可能改出矛盾句。


3.0-前置 · 文案结构先行(2026-10-06 新增 · 3A / 3B 都要过)

> 用户原话:「以后我让你出文案的时候,你也要先给我文案骨架、文案结构。
> 但是,这些文案骨架、文案结构,最后的文案还是要从爆款视频素材里凝练出来。」

本技能出文案(3B 熔炼)或重排用户文案(3A)之前,先走一步结构确认,不许直接吐成品。

结构卡格式与三段式(0A 给骨架 → 0B 爆款凝练 → 0C 填骨架成文)见
qianshuhui-xinwenan/references/copy-structure.md,不在本技能重复实现。

这一步的完整规则(骨架从哪来、怎么推荐、给几个)见 references/gujia-menu.md。
下面只列在本技能里必须遵守的硬规则。

骨架怎么来(顺序不许反):

① 素材体检(Step 1)已有&quot;能拍什么&quot;:镜头类型(特写/操作/对比/产地/真人…)
② 原片文案(Step 3B 三层提取)已有&quot;在说什么&quot;:卖点、钩子、口语节奏
③ 两边融合  →  融出文案
④ 骨架  →  文案一融出来,骨架是&quot;长&quot;出来的,**不是从菜单里挑出来的**
⑤ 推荐  →  我按目标条数给【首选 N 个】+ 理由 + 【还能换的备选池】→ 用户点头

⛔ 不许"先定骨架再找画面"(等于让素材去迁就文案 —— 用户说的"没有东西来匹配"就是这个下场)。

推荐交付模板(2026-10-10 用户定 · 两栏都要有):

这条素材我融出来能长 N 个骨架:

【我推荐用】
① &lt;骨架名&gt; —— &lt;从素材哪里长出来的:哪段镜头 / 哪个卖点&gt;
② &lt;骨架名&gt; —— &lt;同上&gt;

【还可以换(你说了算)】
③ &lt;骨架名&gt; —— &lt;半句:为什么也能用&gt;
④ &lt;骨架名&gt; —— &lt;同上&gt;

本次按【每骨架 2 条】测算,要改成 1 条或 3 条说一声。
③④ 不想要、或者想要别的,也直接说 —— 我当场给你换。

颗粒度 = 只报「骨架名 + 一句理由」:用哪几段镜头当主画面、从哪条片借镜头,留到 Step 4 再说。

在本技能里的五条硬规则:

# 规则 说明
1 3B 熔炼尤其要先给结构 熔炼本身就是「从素材凝练」,但凝练 ≠ 直接吐成品。先把「这条片用什么论证逻辑」摆给用户看,确认后才成文。
2 3A 重排前也要问结构 用户给了文案不等于结构已定。若用户要「同一条文案拆成多条片」或「换角度重写」,先确认每条走什么结构。
3 结构差异 = 画面防撞车的第一道保险 批量出片时(≥4 条),任意两条的论证逻辑 + 主语视角必须不同(详见 copy-structure.md 的 4 维度差异化表)。Step 3 的「钩子分配」是第二道保险,两道都要有。
4 推荐制 + 选择权(两层缺一不可) 首选由我定(我按"最好的文案、最好的画面"推荐,不许丢空白菜单让用户挑);改选权在用户(首选之后必须附备选池,用户不满意随时点名换,我当场评估、不让他等第二轮)。推荐个数:精品(1~3 条)= 条数;批量(≥4 条)= 条数 ÷ 2(向上取整)。
5 骨架清单是开放的 那十种(开箱实测/溯源/自用分享/对比/单点爆破/答疑/反向劝退/认知纠正/身份点名/算账)只是常见款的命名参考,不是白名单。素材里长出别的结构(开箱拆包式、踩坑对比式…)照用,现场起名即可。⛔ 反例:拿菜单去"砍"素材能长出来的结构。

> 同骨架派生 2 条时的画面处理(不写死):默认换主画面来源(第 1 条以 A 片为主、B 片借入,第 2 条反过来)→ 效果是"骨架像、画面不像"。
> 但画面撑不满时允许两条画面接近 —— "画面能配得上"永远优先于"画面看着不一样"(用户 2026-10-10:「如果画面支撑不好时,两条骨架视频画面差不多也可以」)。
> ⚠ 硬线仍在:两条的骨架名 + 论证逻辑 + 主语视角必须不同("画面可以像" ≠ "文案可以像")。

> 为什么这道关卡在本技能里更要紧:本技能下游是「配音 → EDL 排镜 → 七道闸门 → 出片」。
> 结构一改,卖点顺序变 → 每句时长变 → 每句帧数变 → 整条 EDL 重排。
> 5 条片重排一次实测烧 20~40 分钟。结构在上游挡住,比在下游返工便宜得多。

★ 音色推荐不在本节做 —— 跟「配音五问」一起挪到 Step 3.6(v1.24.0 改)

本节只负责把骨架定下来。音色既不在这里问,也不在 Step 0 问:
音色要看四样东西,最后一样是文案(情感指令从文案提炼),而文案 Step 3 才写、Step 3.5 才定稿。
问早了必然要回头改 —— 所以统一挪到 Step 3.6(文案定稿后、排镜之前)问一次。

> 本节末尾可以顺嘴预告一句「音色等文案定稿后一起给你推荐」,让用户有预期。
> 但不许在这里就把音色问定。


3A · 用户提供文案(原逻辑:本技能只做分配与编排)

> 本技能不内置合规词库(避免与千枢汇文案家族重复造库)。
> 文案来源:【千川素材:】→ qianshuhui-qianchuan-sucai;【新文案:】→ qianshuhui-xinwenan;【爆款文案仿写:】→ qianshuhui-baokuan-fangxie;【开头优化:】→ qianshuhui-kaipianyouhua。

拿到 N 套文案后,本技能负责三件编排事:

  1. 分发:把每套文案对到一个骨架片(精品模式对到镜头评级),确保同一骨架下的多条文案不撞开头钩子。
  2. 借入预算:标出每套文案里哪几句需要借入画面(通常是本片没有的名词性卖点:配料表、米油、谷穗、包装净含量)。借入只看文案需要什么画面,不要为了借而借。
  3. 钩子分配:给每条片指定不同的开场策略(价格反差/身份提问/场景痛点/认知纠正…),这是跨条防同质化的第一道保险。

产出:output/千枢汇-&lt;主题&gt;文案矩阵-&lt;日期&gt;.md,每行 = 一条成片的编号、文案来源、骨架片、借入清单、钩子类型。


3B · 从素材自身熔炼文案

> 完整方法论见 references/script-synthesis.md(三层提取判据、选举权重、2 条母版、派生规则、前 5 秒专项)。这里只列动作顺序。

# 动作 产出 / 命令
1 拿到口播文案:用户提供 → 本地转写 → whisper.cpp(先问用户再下载) python scripts/batch_transcribe.py --src &quot;&lt;素材目录&gt;&quot; --root &quot;&lt;项目根&gt;&quot;
2 跑统计底表(确定性统计,把候选摆上桌) python scripts/script_mine.py --dir work/transcripts --terms work/terms.json
3 第一层 · 口播层选举:卖点拆单元 → 语义归并 → 按支持度分层(≥60% 必进主线 / 30~60% 可选 / <30% 加分项) 底表 §① + §①b;先看 §①c 排掉 ASR 错字
4 第二层 · 画面层支撑:给每个卖点找画面支撑(强/中/无)。目视优先,Step 1 的 kind/note 只作初筛,用 dense_probe.py 抽帧确认 画面支撑矩阵
5 第三层 · 钩子层:归纳各条开场钩子类型与强度,同时记录画面钩子 底表 §② 开场口播 + 钩子清单
6 出 2 条母版(含必进项、钩子与卖点顺序分叉:甲=冲击型 / 乙=共鸣型) 母版甲、母版乙全文
7 按成片数派生变体:1 条取其一 / 2 条甲乙各一 / ≥3 条交替派生。单选只改一项(换钩子 或 换卖点顺序);同母版派生 ≤3 条;派生后做撞钩子检测 派生记录表
8 前 5 秒专项检查(六项打勾,不过就回第 5 步重选钩子) script-synthesis.md §六
9 每一句标注画面来源:[配:素材X 的 Y–Z 秒镜头] → 直接喂 Step 4,不用二次找画面 ①

硬约束:

  • 同源样本先去重。底表 §③b 标「强嫌疑(疑同源)」的样本对,只保留一条进选举——
    否则从同一套脚本里"选举"出两条母版,等于自己跟自己撞。
  • 价格只用用户告知的。素材里的价格一律不参考(底表 §④ 会把它们列出来,列出来是为了避开);
    用户未告知 → 本轮不写价格,并避开带价格的画面区间。
  • 零命中先怀疑错字。底表 §①c 会把低频词的近似片段列出来(配料表→配套表、净含量→金含量),
    确认是错字就补进词表变体,或改用用户提供的文案。
  • 画面支撑为「无」的卖点按 script-synthesis.md §五·补 判断——是独白 / 卖点本身好就可用,只有矛盾才淘汰(⚠️ v1.11.1 改:旧写法「不许进主线」与用户 2026-10-06 定调冲突,铁律二在排镜阶段落实,不是文案筛选器)。
  • 反向机会:有些镜头很出彩但没人提,可以补一句文案上去(画面已经在手 = 白捡一个卖点)。

产出:output/千枢汇-&lt;主题&gt;-素材文案熔炼-&lt;日期&gt;.md + output/千枢汇-&lt;主题&gt;-文案终稿-&lt;日期&gt;.md。

3.5-前置 · 文案交付必须带「时长双标注」(v1.24.0 新增 · 用户口径)

写文案时按 1.2 倍速估句子长短(默认档)——但交付时两个档位的秒数都要标出来。
用户要拿它对着「单条时长 20~40s」的目标先看一眼,别等排完镜才发现超了或不够。

每条文案末尾固定跟一行:

【时长估算】本条 152 字 / 14 句
  · 按 1.2 倍速:约 31.9 秒(净语音 29.2s + 句间停顿 2.6s + 开场留白 0.05s)
  · 按 1.0 倍速:约 38.0 秒(净语音 35.3s + 同上)
  · 估算依据:1.2 倍 ≈ 5.2 字/秒、1.0 倍 ≈ 4.3 字/秒(`references/voices-user.md` §四)
  · ⚠ 这是&quot;抬头写字时的预判&quot;,不是成片实测 —— Step 3.6 定了真实语速后会重算一次

算式(一次算清,不许估两遍):

净语音 = 总字数 ÷ 语速(字/秒)
成片 ≈ 净语音 + (句数 − 1) × 句间停顿 + 开场留白

语速常数、来源与「换音色/换语速后要重新标定」的要求 → references/voices-user.md §四。

> ⚠ 双标注是硬要求,不是可选。用户原话(2026-10-10):
> 「写文案的时候,你就参考 1.2 倍速来估。但是你出完文案的时候,要标注一下,
> 说明这段文案是按照多少倍速估的。把标注清楚就好:1.2 倍大概多少秒?正常倍数 1.0 倍大概多少秒?
」

Step 3.5 · 文案评审关(人工闸门,不点头不许往下排画面)

> 用户明确要求:文案要给我检查合不合格。
> 位置:Step 3 之后、Step 4 之前。3A / 3B 都要过这一关。

  1. present_files 把文案推给用户,明确问一句:「这几条文案合不合格?」
  2. 推的东西要带齐:
    - 3B:母版全文(逐句 [配:素材X Y–Z 秒] 画面标注)+ 派生记录表 + 卖点覆盖表 + 前 5 秒专项打勾表 + 价格声明 + 钩子分布统计(模板见 script-synthesis.md §八)。
    - 3A:文案矩阵表(编号 / 来源 / 骨架片 / 借入清单 / 钩子类型)+ 撞钩子检查结果 + 价格声明。
    - 两条都要带:每条文案的「时长双标注」(按 1.2 倍 ≈ 多少秒 / 按 1.0 倍 ≈ 多少秒,格式见上一节 3.5-前置)。
    用户要拿它对着「单条时长 20~40s」先看一眼 —— 缺这一行不算交齐。
  3. 用户挑毛病 → 改 → 重新出稿(改动大就重跑一遍前 5 秒专项)。
  4. 用户点头之后才进 Step 4。

理由:文案错一个字(或撞了钩子),后面 EDL、配音、七道闸门全得重来。
把错误拦在这里,返工成本从"重出全片"降到"改一版文案"。

Step 3.6 · 配音五问(文案定稿后 · 排镜之前 · 只问一次)「v1.24.0 新增」

> 位置是硬的:晚于 Step 3.5(文案定稿)、早于 Step 4(排镜)。
> 提到 Step 0 = 瞎猜(骨架 / 真人 / 文案三样都没有,到 Step 3 还得推翻重问);
> 拖到 Step 5 = 太晚(语速一改,每句时长变 → 句首变 → 画面切换点全变,整条排镜作废)。

为什么是这里(四样依据这时才齐):

依据 哪一步产生
画面里有没有可辨真人(音色最硬的一条) Step 1 素材体检
这次做几条 Step 2 产量测算
骨架调性 Step 3 骨架
文案(情感指令要从它提炼) Step 3.5 定稿

五问全项(一次问齐,不许拆成两次):

# 问什么 默认 参考
① 音色(必须给推荐,不许只摆清单) 无默认 voices-user.md §二 四条依据 / §三 清单
② 句间停顿 0.2s 0 会像机关枪
③ 开场留白 0.05s
④ 语速 1.2 倍(--rate 20) voices-user.md §四
⑤ 情感指令 从文案提炼 voices-user.md §五

音色的推荐口径(与「开工骨架菜单」同一套:我推荐 + 备选池,选择权归用户):

  • 四条依据有先后:① 画面里的可辨真人(最硬,一票否决 —— 音色性别/年龄要对上出镜人,否则是穿帮)
    → ② 骨架调性 → ③ 品类调性 → ④ 同批多条分开配
    (同一音色不超过一半;同骨架 2 条优先配不同音色,
    但不写死,画面有可辨真人时以画面为准)。
  • 格式:【我推荐用】+一句理由 /【还可以换】1~2 个备选。
  • 批量给分配表(第几条 → 音色 → 理由)+「本次按 X 个音色分配,要改说一声」。
  • ⛔ 不许只丢 5 个音色名让用户自己挑。 用户点名要换 → 当场评估、当场答,不许让他等第二轮。
  • 完整映射表与交付模板 → references/voices-user.md §二。

问完立刻做两件事:

  1. 按定下来的语速把每条文案的时长重算一遍(覆盖 3.5-前置 那份预判),
    与「单条时长」目标(默认 30s / 20~40s 区间)差太多 → 先谈再走。
  2. 把语速 / 停顿定为本轮参数,Step 4 排镜直接引用(solve_shots.py --rate / --gap / --head),
    不许排镜那边再各估一个(P0 族错误:两边两套数字 → 音画错位)。

用户确认后才进 Step 4。

Step 4 · 融合编排(第四段核心)

编排第一步(可选):写角色卡 work/cast.json —— 默认不写。真人镜头与无人镜头平权,直接进同一个候选池按文案择优,不必为了用真人而建卡(v1.14.0,2026-10-08 用户拍板取消"无人优先")。

只在你想显式锁定主角时才建卡,且每条片定一个主角:
主角从 Step 1 的 work/persons/ 人物表里选,优先选「命中帧最多、区间最连续」的那个人
(挑一个全池只出现 3~5s 的人当主角,天生凑不够 60% 占比);副人物按准入三条决定加不加。

{ &quot;1&quot;: {&quot;lead&quot;: &quot;P01&quot;, &quot;support&quot;: [&quot;P03&quot;], &quot;note&quot;: &quot;室内分拣台 · 白背心女主讲&quot;} }

> 建卡只是"锁主角"的可选项,不做限制、也不需要理由 —— 真人镜头该用就用(编排不再回避),
> 唯一要守住的是"同片不换人"(见铁律七)。混剪的是他人原片,用真人时出片记得开打码(默认开,见 Step 0 必问五)。

然后为每条片写一份 EDL(work/edl_&lt;编号&gt;.json):

[
  [&quot;片B&quot;, 0.0,   114, &quot;开场·金黄粥倾倒(连续长镜,整段用)&quot;],
  [&quot;片D&quot;, 48.0,  59,  &quot;借入·锅中金黄粥(米油感)&quot;],
  [&quot;片D&quot;, 96.27, 50,  &quot;借入·配料表特写(无价格信息)&quot;]
]

字段 = [素材名, 源内起点秒, 帧数, 说明]。
(上面的素材名与时间码是格式示例,只对某批特定素材有效,新素材必须重算。)

⚠ Step 4 前置 · 「一句话最长能有多长」必须反推,不能写死(v1.10.5)

三行结论:

  1. 不许把切句长度写死 —— 曾把 max_chars=18 写死 → 150 字硬切成 15 句 → A1 排成 15 刀、最短 0.73s,退回"小分镜"。这是"碎裂的根源"。
  2. 按镜池能力反推,且要「看顶峰」 —— 本技能口径 = solve_shots.py check 的「容量」列:
    每刀容量(字)= 该刀实长(s) × 0.92(余量)× RATE(6.10 字/秒,需现场标定),
    逐句与配音实测比对,超出就减字、或换更长的镜头;反推看最长的那个镜头能不能装,不是取中位数。这一步由 AI 执行、没有自动保险。
  3. 完整复盘见 references/pitfalls.md P0-32 —— v1/v2 算法对比、spill() 短缺分支(缺帧按句分摊、不许全加第 1 刀)、TTS 与排镜共享同一份切句预算、以及单源工具 hunjian-tool 的说明(那些函数本技能里没有)。

编排四铁律(违反必返工):

> ⚠️ 本处保留执行摘要(编排时随手要查);反例、修复方法、历史踩坑的详解在 references/edl-rules.md,那边是单点权威源。两处有出入以 edl-rules 为准。

  1. 句首 = 画面切换点。刀界必须落在台词句首上(允许"画面先行"0~2 帧,即画面比声音早)。对齐依据是字幕 SRT 的句首时间 × fps 取整。
    —— 排画面不许按感觉分配时长。这是本项目返工两次的根因:画面比音频慢 2.9 秒,观众听到"米油"时画面已经切走了。
  2. 每刀的画面内容 = 那句台词在说的东西。"配料表""米油""五斤装"这类名词性卖点必须有实拍对应,找不到就调整文案措辞或换构图,不许乱配。
    —— 落点必须落在镜头「内部」,绝不写镜头终点边界(v1.9.3 实测:拉丝镜头是 6.583-7.917 而落点写 7.9,snap() 吸附后整刀 95% 取自下一个镜头的「铝膜入水」—— 口播说拉丝、画面放汤锅)。snap() 只保证"这把刀存在",不保证"这把刀是这段语义";写落点时留 ≥2 帧余量。这类错机器查不出来,只能抽帧目视(铁律五),详见 pitfalls.md P0-22。
    —— ⚠ 开头 0~1s 不许有"过渡刀"(v1.9.3 实测):配音的前导静音在音频侧剪掉 + 字幕同步前移,绝不要在画面侧插一段实拍画面去填。那样 0–1s(抖音跳出率最高的区间)会被"唯一无声 + 信息量最低的远景"占住。详见 pitfalls.md P0-21。
  3. 不把同一段连续画面切成两刀。同一个长镜被拆成两刀接在一起,会因为重复帧出现"闪一下"的假硬切。
  4. 不跨原片自身的剪辑点。每刀必须完整落在 shots_final.json 的单一镜头区间内。唯一例外:差分法把同一段连续画面切碎时(用 check_sync.py / gate_check.py 的白名单 work/allow_cross.json 放行,且必须在清单里写明"已抽帧目视核验")。格式示例见 references/allow_cross.example.json(key 长这样:&quot;A2|片B|61.8&quot; → 说明;按素材生成,换一批素材必须重建,不沿用旧条目)。
    —— 反过来说:如果刀骑在剪辑点上,先怀疑是不是镜头表错了。差分法本身会漏切(渐变过渡、打码区域)和误报(手部抖动),去 shot_fixes.json 修表,不要靠挪刀位硬凑。

铁律五 · 自动切镜结果必须过一遍抽帧拼图:排完 EDL 先出无声画面 + 逐句抽帧拼图(qc_sync_frames.py),AI 逐句看图自查(⚠️ 不推给用户 —— 用户 2026-10-08 明确「看不过来」,他只在文案 + 成片两处把关),确认无误再合成配音。实测四条边界错误里有三条曲线报告完全不报错,只有拼图能发现("回购过好几次了"配了张真人吃玉米就是这么抓出来的)。

铁律六 · 凡改像素 / 改时轴,必须从产物实测反测 —— 不接受"我按参数执行了"这个说法。

这类操作(归一化 / 打码 / 加标识 / 转封装 / 按百分比定位)有个共同陷阱:
脚本正常退出、打印 ✓、结果却是错的。它不是"流程缺环",而是
校验器只证明"我按参数做了",不证明"产物是我要的"。

两次实测事故(详见 pitfalls.md P0-13 / P0-14):

事故 为什么脚本没拦住 反测怎么拦住
VFR 源(素材6/7)默认 CFR 编码悄悄丢 5~9 帧 → 时间轴漂 0.15s 逐刀帧数硬校验拿"自己的产物"比"自己的目标",内部自洽 verify_reencode.py:与源比帧数,再比每个切点的落帧 pts
像素换算写死 H=1920 → 4 条素材区间全偏 只验"参数有没有按我写的算",验不了参数本身错不错 从产物反推实际处理区间,与目标区间比对

判据只有一条:从产物量出来的数。脚本报"✓"不算数,产物实测才算数。

这条同样管「改动回执」:编辑工具报"已保存"、脚本报"写入成功",都是"我按参数做了"的变体 ——
唯一可信的是回读文件本身。实测(2026-09-19):同一条消息里对同一文件发的多处修改,
其中一处报成功但没落盘,重跑后产物照旧(详见 pitfalls.md P0-15)。
→ 对策:同一文件的多处修改分开逐次做;改完从产物侧回读核对,不看回执。

铁律七 · 真人与无人平权 → 禁换人(v1.14.0;2026-10-08 用户拍板取消「无人优先」)

核心:编排时真人镜头与无人镜头完全平权。 两类镜头进同一个候选池,按「谁更贴这句台词 + 谁的画面更好」择优 —— 不再"无人优先"、不再默认回避真人、不再需要"人本位理由"。用不用真人由 AI 按文案与排片自决(不拿去问用户)。

级 规则 说明
① 平权择优(默认档) 真人镜头 / 无人镜头同池,按「贴台词 + 画面好」选 不做任何限制。农产品带货里产品镜头信息量常更高(观众爱看产品),但这不是硬偏好 —— 该用真人("咬 / 吃 / 拿 / 递"这类人本位动作、第一人称近景)就用真人,别为了"躲脸"把好镜头浪费掉
② 禁换人(硬红线) 一条片里绝不出现「同一个叙事身份换了一张脸」 —— 机器侧可判的形式 = 一套片里可辨正脸人物数 ≤ 2 任何模式、任何时候都不放松。⑦ 闸门无条件执行此条:不给角色卡也拦(v1.8.1 修)

为什么可以放开(用户 2026-10-08 拍板):「既然人能打码了,就可以考虑使用真人」。打码把真人出镜的账号关联 / 人脸识别风险挡掉了一层,而"无人优先"这个默认档会把可用素材池砍掉一截(本批实测纯无人可用 ≈70%)—— 没必要再自我限制。取消后素材池更大、排片选择性更大。

> 放开 ≠ 放弃一致性:真人镜头进来后,唯一要盯死的是"同一条片别换人" —— 打码改的是"这张脸长什么样",改不了"这是两个人";观众看到第 3 秒白衬衫、第 8 秒花衬衣,读出的就是"换了个人"。这条由 ⑦ 闸门无条件拦。
>
> 如实告知(首次启用时说一次即可,之后按用户口径执行):① 打码只降低"人脸识别 / 账号关联"那一条线,对画面查重 / 语义查重 / 著作权毫无帮助;② "只糊眼睛"在法律上基本无效(要真降风险得糊到认不出是谁)—— 用户已知情,选择用它换取观感 + 账号关联上的好处。
>
> 也别从一头摆到另一头:平权 ≠ "有真人就优先用真人"。判定粒度是「句」,按内容选 —— 这句配真人好就配真人、配产品好就配产品。要挡的从来是"同片换人",不是"真人"本身。

铁律七·补 · 「打码后用」——把真人镜头救回来(v1.11.1 新增;2026-10-08 用户拍板启用)

前面两级解决"用不用 / 换不换人",这一档解决"怎么让真人能用":

python scripts/cut_multi.py --edl work/edl_A1.json --faceblur eye  ...   # 只糊两只眼睛(双椭圆)
python scripts/cut_multi.py --edl work/edl_A1.json --faceblur face ...   # 整脸糊掉
python scripts/cut_multi.py --edl work/edl_A1.json --faceblur eye --faceblur-all ...  # 不分级,一律打
项 口径
做了什么 出片时逐帧给人脸打码(blur_faces.py,与"糊字幕"同一趟逐帧管线 → 不多转一次码、不掉画质)
范围两档 eye=双椭圆只盖两眼(默认推荐,正常尺寸下基本看不出)/face=整脸
跟随与边缘 两颗椭圆跟着头的角度转(用 YuNet 的两眼坐标算倾角);边缘羽化(硬边一眼就看出"贴了一块")
默认分级 整刀中位脸宽 ÷ 画面宽 < 4% → 判"认不出是谁" → 这一刀不打码(打了也白打,还留糊块);--faceblur-all 关掉分级、一律打
闸门联动 ⑥ check_banned.py 加 --faceblur → person 类禁用区全部放行;价格/文字类照拦。<br>⑦ check_persons.py 不用改 —— 它判"一条片里有几个人",打码不改这件事(打码后仍要避免换成另一个不同的人)
编排口径 v1.14.0 起为硬口径(不只是"可以"):真人镜头与无人镜头完全平权 ——<br>① 进候选池:编排时把真人镜头和无人镜头放一起比,按「谁更贴这句台词 + 画面更好」选,不许因为"是真人"就跳过它;<br>② 不需要理由:不再要求"人本位动作在无人区无解"才准用真人;<br>③ 不必建卡:角色卡降为可选(想显式锁主角时才写);<br>④ 仍需自检:同一刀内不换人、同片不超过 2 张可辨正脸(⑦ 闸门照拦)。<br>—— 这就是"可用池被砍掉一截"的正解

> ⚠ 检测门槛必须 0.85(blur_faces.SCORE_TH):农产品素材里红枣 / 包装 / 手部会被 YuNet 稳定误判成脸。
> 用 0.60 时实测一段纯产品特写被检出 116/180 帧 → 在产品上打了一片码。
> 技能其它模块(scan_faces.py / cluster_persons.py)早就定死了这条:真脸 0.93+、误检 0.53~0.72。
> 详见 pitfalls.md P0-39。

> ⚠ 必须如实告知用户的两句(2026-10-08 用户已知情并明确拍板启用,此后不再重复劝阻):
> ① 打码只针对"人脸识别 / 账号关联"那一条线 —— 对画面查重(帧间运动)与语义查重
> 都没用(打码改的是像素);② 对著作权(混剪他人原片本身即复制 + 改编)毫无帮助。
> 另外要真降法律风险得糊到"认不出是谁",而"只糊眼睛"在法律上基本无效
> (法院/检察口径:五官轮廓 + 发型体态 + 场景能认出即可能侵权)—— 用户选它,是选观感 + 账号关联,
> 不是选"免死金牌"。这段话在首次启用时说一次即可,之后按用户口径执行。

副人物准入三条(满足其一,且片内自洽):

> 平权后这三条照样要满足 —— 判它的理由是叙事一致性:"多一张脸多一份叙事断裂风险"
> (观众会问"刚那个人哪去了")。判据本身不变。

# 条件 例子
1 场景可区分 —— 与主角处在明显不同的场景/角色,观众不会误认成同一人 主角在室内分拣台,副角在果园采摘
2 叙事有交代 —— 文案里对副人物有明确称呼/角色 "果农""我们打包的师傅""邻居阿姨"
3 只做环境 —— 远景 / 背影 / 手部 / 群体,不出现可辨正脸 背景里分拣的工人

硬约束(闸门 ⑦ 逐条核):

  1. 一条片里可辨正脸的人物 ≤ 2 个(主角 + 至多 1 个副人物)——无人刀不计数。
    本条无条件生效:不需要角色卡,不给角色卡也拦。
    (v1.8.1 修 —— 此前它挂在角色卡分支里,不给卡时"3 个不同的人同片"照样判通过,第 ② 级形同虚设。)
  2. 在有可辨真人的刀里,主角占比 ≥ 60%(全片无人 → 该条自动满足,闸门不因此拦片)。
    本条需要 --cast —— 不知道谁是主角就没法算占比;没给卡时只报「用到谁」、不判这一条。
  3. 绝不出现"同一个叙事身份换了一张脸" —— 若文案用第一人称「我」,
    全片近景正脸必须同一个人;这是最容易被观众抓到、也最伤信任的一条。

编排分叉(按 Step 0 必问二的模式):

  • 批量模式:三条配比生效——骨架 60~70%、借入 ≤30%、同一借入镜头复用次数不设机械上限(⚠️ 用户原话「我也没有规定一个镜头只允许复用两次」,max_reuse=3 只是兜底值,选镜以文案为准);
    同一画面有多个候选时,优先选未在本片用过的(防重优先于单条强度)。
  • 精品模式:三条配比全部取消,改走择优规则——按 Step 2 分支 B 的镜头评级表取分最高的;
    借入不设上限;1 条时镜头复用无限制。多个候选时取评分更高的,而不是"没在本片用过"的。

> 七条铁律两种模式都不放松——那是技术正确性,不是优化目标。

Step 5 · 配音合成

> ## ⚠️ 配音五问 —— 已在 Step 3.6 问过一次(v1.24.0 改:不再是开工时问)
>
> 音色(必须给推荐,不许默认)/ 句间停顿 0.2s / 开场留白 0.05s / 语速 1.2 倍 / 情感指令(从文案提炼)。
> 位置 = 文案定稿后、排镜之前(五问全项与理由见 Step 3.6)。
> 不许默认选、不许沿用上一条、不许按「上次用的」推断。
> 1~2 条 逐条问;批量(8~10 条)问分配方案。
> 问法、音色清单与用户原话 → references/voices-user.md(单点权威源,本节不重复)。
> 本节只写执行细节(换算规则 / 实测标定 / 情感指令分级)。

① 音色(用户的常用清单,voices_user.json,本人 2026-10-06 确认):

音色 ID 版本
小何 zh_female_xiaohe_uranus_bigtts 2.0
直率英子 zh_female_zhishuaiyingzi_uranus_bigtts 2.0
熊二 zh_male_xionger_uranus_bigtts 2.0
Vivi zh_female_vv_uranus_bigtts 2.0
清新女声 zh_female_qingxinnvsheng_uranus_bigtts 2.0

> ⚠️ 5 个全是 2.0(_uranus),都能用自然语言情感指令。
> 「清新女声」曾被误记为 _mars(1.0)—— 是按内置表同名条目推的,推错了。
> 教训:音色 ID 不许按名字推,必须用户明确给。

> ★ 音色必须给推荐,不许只摆清单(v1.23.0 新增):
> 问的时候是「我推荐 X(一句理由),想换 Y/Z 也可以」,不是丢 5 个名字让用户挑。
> 四条依据按优先级:① 画面里的可辨真人(最硬,一票否决)→ ② 骨架调性 → ③ 品类调性 → ④ 同批分开配。
> 正式推荐在 Step 3.0-前置(骨架定了)时补,Step 5 按确认结果执行。
> 完整规则、骨架→音色映射表、品类映射表、交付模板见 references/voices-user.md §二。

② 句间停顿 / ③ 开场留白:
- 句间停顿默认 0.2s(--gap 0.2)。0 会像机关枪,0.2~0.3 才是自然说话的节奏。
- 开场留白默认 0.05s(--head 0.05)。
- 对应 assemble_vo.py 的 --gap / --head / --tail(片尾留白默认 0)。

④ 语速:默认 1.2 倍(不是 1.3)。

> 换算规则(有实测依据,别记反):speech_rate 取值 [-50, 100],
> 语速比 ≈ 1 + rate/100(引擎 doubao_tts.py 第 17 行)。
> 所以 1.2 倍 → --rate 20;1.3 倍 → --rate 30。
>
> ⚠️ 2026-10-06 实测标定(小何 / 8.664s 基准样本):
> rate=+20 → 实测 1.195 倍(理论 1.20,准);
> rate=+30 → 实测 1.267 倍(理论 1.30,高段有衰减)。
> 1.2 倍这一档是准的;越高越不准。 换音色/换语速后要重量一次。

⑤ 情感指令(2.0 音色专属,用户口径:从文案提炼):

  • 2.0 音色(_uranus):用 context_texts 传自然语言指令,写成
    &quot;emotion&quot;: [&quot;用惊讶、替他肉疼的语气说,像刚发现了不得了的事&quot;]。
  • 1.0 音色(_mars/_moon):不支持自然语言,只能用 emotion 枚举
    (happy / angry / surprised…)+ emotion_scale(1~5,默认 4)。
    voiceover.py 会自动降级重试(去掉 emotion 再合一遍)。
  • 「从文案提炼」怎么落地:逐段读文案,判断这段该用什么语气,写进该段的
    emotion 字段。要点:
  • 按文案的实际情绪走,不要每段都加。陈述事实的句子不加更自然。
  • 钩子句(提问、反差、纠正认知)最值得加 —— 这是「不像机器人」的关键位置。
  • 指令要口语化、带场景(「用随口一问的语气说,像闲聊」),
    不要写「用开心的语气」这种抽象词 —— 抽象词模型只能猜。
  • 全片情感要有起伏,不能从头到尾一个调。
  1. 写配音脚本 JSON(work/vo_script_&lt;编号&gt;.json):{&quot;segments&quot;: [...]},每段可带 speaker / lrate / emotion / loudness / pause_after / sublines。
  2. 合成:
    bash python scripts/voiceover.py --script work/vo_script_A1.json \ --speaker zh_female_zhishuaiyingzi_uranus_bigtts --rate 20 \ --target 999 --tol 999 --force
    - --rate 20 = 1.2 倍(见上「语速换算」)。旧文档写的 --rate 8 已废弃。
    - --target 999 --tol 999 = 关闭自动调速(语速由你定,不要脚本来"凑时长")。
    - 改过文案后必须带 --force。默认逻辑是"分段音频文件存在就跳过合成",改了文字不加重合会静默复用旧音频,结果是"声音旧、字幕新"的假成功。
    - 只改了 sublines 分句、没改段文本 → 不要加 --force(不必重合成),只重跑 assemble_vo.py 即可刷新字幕轴;assemble_vo.py 读的是 work/tts/&lt;tag&gt;_r+20/segments.json 清单而非配音脚本,段文本未变时重跑 voiceover.py(不带 --force)就会刷新该清单。
  3. 静音治理 + 拼装 + 出字幕:
    bash python scripts/assemble_vo.py --dir work/tts/&lt;tag&gt;_r+20 \ --out output/配音_&lt;编号&gt; --trim --lead-margin 0.03 --tail-margin 0.04 \ --gap 0.2 --head 0.05 --inner-pause 0.2
    - 逐样本拼接(不是 ffmpeg concat),所以字幕轴零漂移。
    - 静音治理的意义:豆包每段 WAV 自带 0.3s 左右首尾静音,6 段就吃掉了全片 14% 的时长——这才是"听着拖"的真凶,不是语速。
    - 字幕分句靠逗号:sublines 的切分点落在真实内部停顿上(len(sublines)−1 == 检出的内部停顿数 时零漂移),否则退化成按字数估算。所以写文案时逗号就是分句意图,别乱加。
  4. 字幕切屏 = 说一句显示一句(v1.10.5,用户口径):

> 用户原话:「说一句显示一句」——「颗粒饱满金黄」就只显示这 6 字、「皮薄肉厚」就只显示这 4 字。
> 长句要按语义短语拆成多屏,不能让一句话从第 2 秒挂到第 11 秒。

由 engine/split_subs.py 在 assemble_vo.py 出 SRT 之前再细切一遍(动作顺序:
voiceover → assemble_vo(含细切)→ SRT)。规则:

规则 说明
切点优先级 ① 有实测内部停顿 → 按停顿切;② 无 → 按标点短语切(一个短语一屏)
「按语速」的落地 每屏停留 = 该屏字数 ÷ 语速 → 目标 0.8~3.0s/屏。实测口播匀速、误差小,所以按字数比例分配时长即可(不必逐字测速)
过短 < 3 字并入邻屏(防「的/了」这类单字闪一下)
过长 > 14 字按标点 / 虚词断,绝不拆词
对总时长的影响 零漂移 —— 只改「哪几字同屏」,不改每个字的起止时刻;实测 A1 从 5 条 → 18 屏,总时长仍 27.35s

为什么必须细切(不切的真实后果):一段 50 字从第 2 秒挂到第 11 秒,字号被自动压到
32px(标准 51px)、还挡画面。细切后全部 48px 标准字号、最长一行 624px(画面宽 1080),
不再缩字号、不再折行。
- ⚠ _greedy_pack 的收口判据别用「时长够不够」:短短语永远被判为"不够"从而被并成大屏。
正确判据 = 短语天然一屏,只有 < 3 字的才并(见 pitfalls.md P1-25)。
5. 对话类文案要双音色一问一答(同一段 JSON 里不同 segment 用不同 speaker),人味才够。

Step 6 · 七道闸门校验(跑不过不许出片)

前五道(时间与结构) 一条命令跑完,输出单一 PASS/FAIL,失败非零退出:

# 批量模式(默认):⑤ 只报不拦(用户 2026-10-05 定调,⚠️ 旧口径「硬门槛」已作废)
python scripts/gate_check.py A1 A2 A3 A4

# 精品模式 2~3 条:⑤ 只报不拦
python scripts/gate_check.py A1 A2 --overlap-mode warn

# 指定文件时:
python scripts/gate_check.py --edl work/edl_A1.json --edl work/edl_A2.json \
    --shots work/shots/shots_final.json
闸门 判据 不过怎么办
① 句首 = 刀界 每句台词开口落在某刀起点(画面可先行 0~2 帧) 改 EDL 的帧数分配,不许改字幕去凑画面
② 每刀单镜内 每刀完整落在单一原片镜头内 先查镜头表是否错了(shot_fixes.json),再挪刀位
③ 帧数 = 配音时长 画面总时长与配音时长差 ≤ 0.05s 补/减最后一刀帧数
④ 同镜头未重复取用 同一原片镜头不被两刀分别取用 换镜(避免成片里同一段画面出现两次)
⑤ 多片画面重合度 同素材「真实时间区间求交」(v1.8.1 改,不再是"起点相近"),判定分母 = 较短成片帧数:重叠帧 ÷ min(fa,fb) ≤ 50%。实现统一在 _qsh.overlap_stats,与 --compare 同源 换骨架/换借入点。两种模式都只报不拦(用户 2026-10-05 定调,见 references/production-modes.md §〇)—— ⚠️ 旧口径「批量模式=硬门槛」已作废,别再当红线无意义返工:实测守零重叠会把 11 句塞进 17 段长镜 → A2 拆到 16 刀/0.90s,用户评价「小分镜一闪而过,很难看」。交付说明里必须注明该值仅参考;只有 1 条时自动跳过;skip 完全不算

第 ⑥ 道(内容)单独跑 —— 前五道一条都不管画面内容:

python scripts/check_banned.py A1 A2          # 逐刀核 work/banned.json
python scripts/check_banned.py A1 A2 --json   # 结构化输出,便于流程路由
闸门 判据 不过怎么办
⑥ 内容禁用区间 每刀取用区间 [起点, 起点+帧数/fps] 不与 work/banned.json 的禁用区间重叠(1 帧容差) 换镜重排(回 Step 4)。不许把刀手写进白名单来绕过

> ⚠ ⑥ 的"防静默假通过"判据已改(v1.10.5):基准取「标注文件」,不是「禁用表」
>
> 旧判据是「禁用表 ∩ EDL ≠ ∅」—— 错。实测两连坑:
> - 坑 1:A1 用的素材恰好全部干净(没有一条进禁用表)→ 交集为空 → 被误判成"没生效"。
> - 坑 2:一度看到「禁用表只有 3 支、EDL 用了 5 支不同名」又差点误判 ——
> 核对 annot/annot.json 才看清:标注覆盖 12 支 / 265 镜,A1 的 5 支全在其中
> (陆总 (2) 11 镜、陆总 (4) 16 镜、3 支 [Original]_* 各 36/15/3 镜)。
> 它们确实全被判为干净,"不进禁用表"是正常结果,不是故障。
>
> 正解:基准取「标注文件的名字空间」,判据 = EDL ⊆ 已标注素材。
> 闸门真正要防的是「EDL 用了一支从未被标注过的素材」(那才是漏标),
> 不是「有没有命中禁用表」(干净素材本来就不命中)。
> annot.json 缺席时退化为旧行为(与禁用表做宽松归一比对),不因缺文件误拦。

> ⚠ 用角色卡锁定主角时,⑥ 必须带 --cast work/cast.json —— 否则
> ⑥(禁真人区)与 ⑦(主角要出镜)会直接打架:⑥ 会把主角自己的镜头也一并拦掉,新流程直接跑不通。
> 加了 --cast 后,脚本把该片主角 + 准入副人物出现的区间从禁用表里按时间区间相减,
> 剩下的才是真禁区(也就是"其他人出现的部分")。全片无人、或不出角色卡时不需要 --cast ——
> 真人区改由出片参数 --faceblur 放行(见铁律七·补)。命令与自检步骤另见 pitfalls.md「交付前最后一道自检」。

> ⚠ --cast 只豁免 person 类禁区(v1.8.1 修):价格 / 画面内文字 / 未分类的区间
> 不受角色卡影响,照拦。原因是旧实现按时间区间无差别相减 ——
> 禁用表 = 真人区 0–10s + 价格字幕 8–9s、主角区间 0–10s、刀取 8.2–8.7s 时,
> 禁区会从 2 条被挖到 0 条直接放行,而那个镜头里屏幕上就挂着价格。
> 类型从哪来:banned.json 条目写 &quot;type&quot;(person/price/text/other);
> 不写就从 why 文本推断(含「价格/块钱/包邮/元」→ price,优先于 person)。
> 需要时用 --exempt-kinds person,text 显式指定豁免范围(默认只 person)。

第 ⑦ 道(人物)单独跑 —— 前六道一条都不认识人:

python scripts/check_persons.py --cast work/cast.json 1 2 3   # 逐刀核人物一致性
python scripts/check_persons.py 1 2 3                          # 不给角色卡:仍判第 ② 级(人数上限)+ 报「用到谁」
python scripts/check_persons.py --cast work/cast.json 1 --json  # 结构化输出,便于流程路由
闸门 判据 不过怎么办
⑦ 人物一致性 ① 可辨正脸人物 ≤ 2 个 —— 无条件生效,不给角色卡也拦(铁律七第 ② 级「禁换人」的机器形式);② 有可辨真人的刀里,其人物必须都在 work/cast.json 角色卡的允许名单内(主角 + 副人物,需 --cast);③ 主角占比 ≥ 60%(在"有可辨正脸"的总时长里,需 --cast)。全片无人 → 三条自动满足,直接报 PASS 换镜重排(回 Step 4,优先换成"同一主角或无人"的镜头,其次才是给角色卡补准入理由 / 指定主角)

平权后 ⑦ 仍照判「人数上限」:没有角色卡时,脚本报「每条片用到谁」并照执行 ≤2 可辨正脸。
全片无人也直接 PASS(无人 / 用真人都合法,不再是"档位高低")。判定标准始终是
文案语义有没有被画面撑住 —— 真人出镜是手段不是目标,无人亦然。
(平权口径的完整理由与用户原话见 Step 4 铁律七,本节只重复"闸门怎么判"。)

> ⚠ ⑦ 的能力边界,别指望它替你判"叙事身份":它只判三条机器算得出来的事 ——
> 人数上限、允许名单、主角占比。而"这两个镜头里的人算不算同一个叙事身份"
> (比如镜头 A 是"我在分拣"、镜头 B 是"我老婆在装箱")机器判不了,
> 它要靠两样外部给的东西:work/persons/(机器聚类之后看总览图合并的人物表)
> 与 work/cast.json(角色卡)。⑦ 做的只是拿外部结论去对账。
> 所以别把 ⑦ 当成"端到端自动判定" —— 合并确认那一步省不掉(v1.15.0:由 AI 看总览图做,不推给用户),这也正是铁律七要写"主角锁定"的原因。

> ⚠ ⑦ 的输入是 work/persons/persons.json,缺它直接退 2 —— 所以 Step 1 第 3b 步
> 默认档也必须跑一次(v1.8.1 起不再是"备查")。退 2 是环境没备齐,不是"不过",
> 别拿它去改 EDL。

为什么必须有 ⑦:⑥ 只知道「这段画面有没有不能出现的东西」,它不认识人。
于是它拦不住最伤信任的一类错误 —— 两条画面都"干净",但一条片里前后换了个人:
头 3 秒白 T 男主播、第 8 秒花衬衣果农,即便产品一模一样,观众读出的是
「这不是同一个人」,信任当场断掉。而同一个人的画面重复出现反而无害,
甚至是加分的(有真人、有人味)。

角色卡 work/cast.json 长什么样(可选;只在确需真人时才写,闸门按它判):

{
  &quot;1&quot;: {&quot;lead&quot;: &quot;P01&quot;, &quot;support&quot;: [&quot;P03&quot;], &quot;note&quot;: &quot;室内分拣台 · 白背心女主讲&quot;},
  &quot;2&quot;: {&quot;lead&quot;: &quot;P04&quot;, &quot;support&quot;: [],      &quot;note&quot;: &quot;仓库装箱 · 灰夹克男主讲&quot;}
}

lead = 主角(唯一);support = 副人物名单(可空,须有准入理由,见铁律七)。

产物侧反查:闸门依据的是 work/persons/persons.json(Step 1 第 3b 步的机器聚类
+ 看图确认结果),判的是产物(EDL 实际取的画面落在谁的区间里),不是声明。

为什么必须有 ⑥:work/shots_final.json 是「镜头边界真值」,不是「镜头可用真值」——
一个镜头可以边界完整、单镜无跨切,内容却是真人正脸 / 带价格 / 片头碎片帧。实测两例:
素材6#3 边界干净却被报告判禁用;素材9#13 是真人正脸、报告
漏登,报告 §六 的亮点表还在推荐它。
→
体检报告的"亮点表"不能当画面内容来源**,报告本身也可能漏登记。

禁用表怎么来(v1.7.0 改版:真人区改为「机器全片扫候选 → 逐条看图确认」;v1.15.0:确认由 AI 做,不推给用户):

禁用类型(type) 来源 怎么定
person 真人正脸 / 真人出镜 scan_faces.py 机器扫候选取底 python scripts/scan_faces.py(全片 0.1s/帧密抽)→ AI 看 &lt;素材&gt;_sheet.jpg 逐段确认(v1.15.0:不推给用户;拿不准的回原片密抽帧看前后 1s)→ 写进 banned.json。候选 ≠ 禁用:YuNet 假阳性极高
price 价格信息 Step 1 第 4 步读图标注 抽帧目视(dense_probe.py),整段禁用不留侥幸
text 画面内嵌文字 / 贴纸 / 片头碎片帧 同上 同上

—— 不要再靠稀疏抽帧找真人:3s 一帧实测系统性漏标(本项目漏 5 段真人区、返工 40 分钟)。
编码成 work/banned.json。条目要带类型,它决定角色卡能不能把这条禁区挖掉
(person 可豁免;price / text / 未分类一律不豁免):

{
  &quot;bans&quot;: [
    {&quot;mat&quot;: &quot;素材1&quot;, &quot;start&quot;: 10.83, &quot;end&quot;: 12.42, &quot;why&quot;: &quot;真人女性吃枣近景&quot;, &quot;type&quot;: &quot;person&quot;},
    {&quot;mat&quot;: &quot;素材5&quot;, &quot;start&quot;: 126.10, &quot;end&quot;: 133.00, &quot;why&quot;: &quot;画面字幕含价格&quot;, &quot;type&quot;: &quot;price&quot;}
  ]
}

> 三种写法都认(扁平表 / {&quot;bans&quot;:[...]} / {&quot;素材名&quot;:[[起,止,原因],...]},可混用)。
> type 不写也行 —— 会从 why 文本推断(含「价格 / 块钱 / 包邮 / 元」→ price,
> 优先于「真人 / 正脸 / 出镜」→ person)。但建议显式写:推断只是兜底,
> 一条 why 里既提真人又提价格时,写清楚才不会让"主播出镜+屏幕挂价签"的镜头被误豁免。
> 格式细节见 check_banned.py docstring。

没有禁用表时脚本报错退出(退出码 2),不当作通过 —— "没登记"不等于"没有禁用内容"。

单独复查某一道时仍可用细分脚本:validate_edl.py(①)、check_sync.py(①②③)。

闸门失败 → 回到哪一步(流程路由) —— 闸门只负责"拦住",不负责"回去改哪":

失败 先分辨成因 回退到
① 句首 ≠ 刀界 字幕轴漂(画面与台词整体错位)/ 刀界排错(个别句对不上)——症状同、修法完全不同 轴漂 → Step 5;排错 → Step 4
② 某刀越出单镜 先核镜头表本身是否错了(work/shot_fixes.json 漏登该切点) 表错 → Step 1;表对 → Step 4 挪刀位
③ 帧数 ≠ 配音时长 配音是权威值 Step 4 补/减末刀帧数(刚改过文案 → 先回 Step 5 重合成);不许改语速去凑
④ 同镜头被两刀取用 找同卖点的替代镜头 Step 4
⑤ 重合度超 50% — Step 4 换骨架 / 换借入点
⑥ 撞内容禁用 — Step 4 换镜重排(不许用白名单绕过)
⑦ 人物不一致 混进了别人 / 主角占比不足 —— 症状同、修法不同 混进别人 → Step 4 换镜;占比不足 → 给主角多配镜位,或回头核角色卡是不是主角选错了(选了个全池只出现 5s 的人当主角,天生凑不够占比)
  • 退出码就是"该不该回去改"的信号:0 = 通过 / 1 = 校验不合格(按上表回退)/
    2 = 环境没备齐(缺镜头表 / 缺禁用表 / 缺 EDL / 缺依赖)。退 2 别当成"不过"去改 EDL ——
    先把环境补齐再重跑。check_banned.py 缺表退 2 是刻意的:「没登记」≠「没有禁用内容」。
  • ②/④/⑥ 换镜前必须回头核 Step 1 的判据:shots_final.json 是镜头边界真值,
    不是镜头可用真值(体检报告 §六 亮点表实测标错 2 处、漏登 1 处)。
    ⑦ 同理,换镜前回核 work/persons/:人物表本身也是机器出的,人还没确认过就换镜,
    可能是在改一个本来就错的判据。

逐句音画自查关(不是机器闸门,但必须做)· 逐句复核:

python scripts/qc_sync_frames.py A1 A2

在每句台词开口 +0.20s 处抽一帧拼图,看"说到哪句,画面是不是那句"。
这一步在合成配音之前做(先出无声画面 + 拼图),能把返工成本从"重出全片"降到"改一版 EDL"。
机器闸门查的是时间对不对,这一关查的是画面内容对不对 —— 后者机器至今做不到
(实测:台词「回购过好几次了」配了"真人吃玉米",五道机器闸门全部报通过)。

> ⚠️ 执行者是 AI,不是用户(v1.15.0 定死)。
> 用户 2026-10-08 明确:「这个我也看不来呀……基本上,我也就是看文案和最后成片的效果。
> 就像之前看那个排片素材一样,很多很多,我看不过来。」
> 所以:拼图 AI 逐句看、AI 判。只有真发现疑点时,才用大白话(一张图 + 一句话)摊给用户;
> 不许整批推过去让他"自己看" —— 那等于把这一关变成"没人看"。
>
> 这不是图省事,是把复核放在看得见细节的一方:用户看不出两帧画面的差别、也读不动 EDL,
> 而 AI 能逐帧看图、能对着台词逐句核。用户真正把关的两处是:① Step 3.5 文案终稿 ② 最终成片 ——
> 成片那关是保底:画面配错到"观众能看出来"的程度,用户在成片里一定能发现。
> (所以 AI 自查这一关不能省:等成片才发现,返工的是整条片子。)

Step 7 · 出片与交付

python scripts/cut_multi.py --edl work/edl_A1.json --vo output/配音_A1.wav \
    --out output/成片_A1.mp4 --clips output/片段_A1 \
    --compare work/edl_A2.json
  • --norm 1080x1920(默认)=逐刀即时归一化:等比放大铺满 → 居中裁切 → 统一 SAR → 统一 CFR。素材规格不一致时必须归一化,否则 concat 会错位/花屏。传 --norm off 可关闭。
  • --faceblur eye|face(v1.11.1,默认 off)=人脸打码:出片时逐帧给人脸打码(跟糊字幕同一趟逐帧管线,不多转一次码)。eye=双椭圆只盖两眼(推荐,正常尺寸下基本看不出)/face=整脸糊掉。默认按「认不认得出」分级 —— 整刀中位脸宽 ÷ 画面宽 < 4% 不打码(脸太小=认不出,打了也白打还留糊块);--faceblur-all 关掉分级、一律打。开了它,⑥ 闸门要配 --faceblur(person 类禁用区放行;价格/文字照拦)。详见 铁律七·补。
    > ⚠ v1.14.0:编排阶段真人镜头早已与无人平权("无人优先"已取消),--faceblur 现在纯粹是出片参数 —— 但打码与否仍建议在 Step 0/Step 1 定(Step 0「必问五 · 打码口径」);用户没说不开 → 默认开 eye。
  • --subs burn(默认)=原片字幕处理:目标一句话 —— 别人家的字全抹掉,只留我们的字(素材口播字幕 + 素材价格贴纸都要盖住,再配上本片自己的字幕)。做法 = 逐刀实测该刀原字幕矩形 → 只糊那一块 → 重绘本片该时刻的字幕(文字查 SRT,不用 OCR 猜);启用后所有刀都走 Python 逐帧路径(含没字幕的刀),保证全片归一化由同一套实现完成(素材帧率 ≠ 目标帧率时按目标帧率重采样,VFR 源天然安全)。
  • 五条纪律:① 逐刀实测、不跨刀取并集(P0-12);② 横向只按实测 span、不做全宽横条;③ 测不到字幕的刀不糊,但仍要绘我们的字幕(P0-26);④ 一刀内可有多段(字幕会在刀内移动,按抽样帧检出位置分段,P0-27);⑤ 只有一段时=原行为、零额外成本。
    > ⚠ ①禁的是跨刀取并集,④要的是一刀内分段 —— 两件事以前被混成一件,恰恰相反别搞反(跨刀并集会把每刀糊掉 21% 画面高)。
  • 两类文字的诉求相反(v1.10.4):口播字幕要"准"(原位重绘)→ 宁窄勿宽;价格贴纸要"全"(糊完画固定位置)→ 宁宽勿漏。详见 §既定参数「文字处理的两类口径」。
  • 改像素必须跑产物反测(铁律六):糊区内差异要大(原字幕被抹掉)、糊区外 ≈ 重编码噪声基线(实测 V03/V04/V12 区内 78/94/62、区外全部 0.00)。
  • 易漏的三种形态(出片前单刀自测 python strip_subs.py 出样片、逐帧看糊除框有没有跟着字幕走,只抽首尾两帧会漏掉中间段):① 一刀内换位/断档 —— 「有 → 空白 → 有」形态(本批 c02)旧版抽 3 帧全落空白期 → 整刀不糊(P0-34~36);② 长句折行 —— 长句会在刀内折成两行,糊框只有一行高则第二行残留,要求框跟着长高、两行都盖住(P0-39);③ 长刀(>6s)四坑 —— 整行没糊 / 整段没糊 / 换句处留 0.3s 空洞 / 字高被误杀,短刀踩不到(P0-41~44)。
  • 实现要点(改代码时别破坏):strip_subs.py::measure_band() 返回 track(时间分段轨道)、apply() 按刀内时间查段;SAMPLES 3→12(抽到空白期会整刀不糊)、段外扩半个抽样间隔、band 只取口播那一组行(把价格条包进来会糊掉中间一大片产品)。详解见 pitfalls.md P0-27 / P0-34~36。
  • --subs strip:只糊不绘 —— 走剪映草稿路线时用(字幕交给草稿字幕轨)。⚠ 草稿路线千万别用 burn(画面已烧字幕 + 草稿再加一层 = 重影);成片也别用 strip(成片就没字幕了,违反规则 A1)。
  • --subs off:不处理,走原来的纯 ffmpeg 快路径。--srt &lt;路径&gt;:字幕轴,默认从 --vo 推导 output/字幕_&lt;tag&gt;.srt(或 output/ 下任一个);burn 模式找不到 SRT 就自动跳过(没法重绘)。
  • 每刀裁完会硬校验帧数(期望 ≠ 实得就报错退出),并打印每条素材的原生规格。
  • 成片一律带 +faststart(v1.15.0):把索引写到文件头 → 点开就能播、不用等下完整个文件。
    > 为什么必须有它(实测证据):不加时 moov 落在文件尾(实测偏移 5210663 / 总 5225017),
    > 内置播放器/浏览器必须下完整个文件才出画面 → 表现为"点了没反应 / 黑屏转圈",
    > 用户会以为"视频不见了"。以前是另出一版 720p 低码率预览绕开它,现在成片本身就能播。
    > 纯封装层改动(-c:v copy 不重编码),帧数 / pts 一律不变,产物反测照过(实测 360→360 帧)。
  • 不再出 720p 轻量预览版(v1.15.0 用户定:轻量预览这一环删掉)—— 高清成片直接给,一个文件既是能播的、也是能上传发抖音的。旧参数 --preview 已从 cut_multi.py 删除。
  • --clips output/片段_XX 是剪映草稿的画面引用源,勿删。
  • --clips-clean output/片段_XX_净(v1.10.5)=「两套切片」:同一次出片同时产两套切片,
    解决"成片烧了字幕、草稿又加一层"的重影问题。
切片 内容 给谁用
主套 片段_XX/ 糊原字幕 + 绘我们的字幕 成片(--subs burn)
净版 片段_XX_净/ 糊原字幕 + 什么都不绘 剪映草稿(字幕由草稿字幕轨承担)

实现要点(改代码时别破坏):
- cut_one_subbed(clean_dst=...) —— 同一遍逐帧循环同时喂两个 ffmpeg 进程,
代价只是多一路编码,不用重读源片;
- 净版靠 SubStripper.without_draw()(浅拷贝 + 清空 srt)做到"只糊不绘",
且与主套共享同一份 OCR 缓存(不重复跑 OCR);
- ⚠ 成片必须用 burn,不能用 strip:strip(只糊不绘)是旧口径下"走草稿路线"的选择。
现在有了净版切片,那个理由消失 —— 成片若用 strip 就没字幕了,违反规则 A1。
- 抽帧验收(c07 实测):主套 vs 净版差异 21768 px,且只在字幕带 y278–363
→ 说明净版确实只差"绘/不绘"这一件事 ✓
- --compare 打印与另一条的画面重合度,目标 ≤50%。与闸门⑤ 同一份实现(_qsh.overlap_stats,区间求交 + min 分母),所以从哪一条上跑、参数怎么排序,结论都一致。

产物反测(铁律六;出片前改过像素 / 时轴就必须跑):

python scripts/verify_reencode.py --src &lt;源目录&gt; --out &lt;产物目录&gt; A1 A2
#   帧数逐条相等 + 每个切点落帧 pts ≤1 帧;不过 → 产物不可用,先修编码参数再出片

cut_multi.py 的逐刀帧数硬校验拦不住"源被悄悄改过"——它拿产物比目标,内部自洽。
只要出片前经过任何重编码(归一化 / 打码 / 加标识 / 转封装),这一步就必须跑。

交付流程(默认两步):

> ⚠️ A / B 选哪条在 Step 0 必问四已经问过(直出成片 / 剪映草稿 / 两条都要)。
> 本流程里那声"走哪条路"是确认,不是首次询问——
> 若 Step 0 问过用户选 A,这里不许再问一遍,直接按 A 走;
> 只有 Step 0 漏问(不允许,见必问四)才在此补问。

出片(1080×1920,自动带 +faststart)
   ↓
第 1 步 · present_files 推**成片本身** → 问一句「这条行不行?」
   ├─ 不行 → 改(回 Step 4 编排 / Step 3 文案)→ 重出
   └─ 行 → 第 2 步 · 问用户走哪条路:
        ├─ A. 直接出成品  → 高清 mp4 已在 output/,补交接文档即可(`--subs burn` 的字幕已烧在画面里,直接可发)
        └─ B. 生成剪映草稿 → 需处理源素材(见下);**字幕改由草稿字幕轨承担** → 先 `--subs strip` 重出一遍画面(只糊不绘),否则画面字幕 + 草稿字幕 = 重影

> v1.15.0:不再另出 720p 轻量预览版。 成片一律带 +faststart(索引写在文件头),
> 高清原片本身就点开就能播 → 推给用户的就是成片本身,不再有"预览"这个东西。
> 用户 2026-10-08 定:「720p 轻量预览 这个轻量的预览可以删掉了。」
> 好处是少一个中间产物、少一轮"先看预览再确认" —— 交付一步到位。

走剪映草稿路线前必须先说清楚(不许省略这一步,也不许提前清理中间产物):

  • 剪映草稿不是"把 mp4 塞进剪映",它引用的是 output/片段_&lt;编号&gt;/ 下的已裁切片段;
  • 所以 output/片段_XX/ 不能删、不能移动——移动后剪映打开会找不到素材;
  • 草稿由本技能自己生成(v1.5.0 起)。完整流程 + 10 项检查清单见
    references/jianying-draft-playbook.md;脚本模板 = 项目内 make_draft_&lt;项目&gt;.py
    (先跑体检模式看清单 1~7 能不能过,再加 --write 落盘);
  • 三条硬约束(违反任一条草稿就废,详见手册):
    ① 明文 info 路线 —— 只写明文 draft_info.json,绝不写 draft_content.json
    (剪映 11.3+ 的 content 是加密的;明文 content 会让它直接拒绝加载);
    ② 坐标语义 —— transform 原点在画面中心、x 右为正、y 上为正、单位是半个画布
    (像素换算:px_x = W/2 + x·W/2,px_y = H/2 − y·H/2);
    ③ 段长用累计帧数派生 —— start = round(累计帧数 × 1e6 ÷ fps),
    dur = 后一段起点 − 本段起点,不要每段独立取整(round(a)+round(b) ≠ round(a+b));
  • 不要再用 jianying-editor 技能的 JyProject —— 它写的明文 draft_content.json
    会被本机剪映判为损坏(见 pitfalls.md P0-7);
  • 在用户明确选 B 之前,高清成片 / 片段目录 / 配音 wav / SRT 全都留着。

交付清单:
1. present_files 推成片(已带 +faststart,点开就能播 —— 不再有"预览版")。
逐句核验拼图是AI 自查的产物,不推给用户;只有真发现疑点时,才拿一张图 + 一句话跟他确认。
2. 成片留在 output/(既是能播的、也是能直接上传抖音的)。
3. 交接文档 output/千枢汇-&lt;主题&gt;-&lt;日期&gt;.md:每条片的骨架/借入来源/时长/重合度/已知取舍。用脚本从 EDL+SRT 程序化生成,不要手抄(手抄必错)。
精品模式必须在文档里写明:重合度是参考值,⑤ 在精品模式下只报不拦 ——
所以「未超 50%」不等于"两条不会看起来像同一支",用户要按需自行判断。
4. 提醒用户在剪映内做最后一步:封面、字幕样式、BGM、导出。
5. 走草稿路线时,草稿落盘后必须提醒用户三件事:
- 完全退出剪映(含右下角托盘)再重开 —— 草稿列表是启动时扫描的;
- 三个"别动":output/片段_XX/ 不能删不能移、乙片草稿里的 AI 标识轨不能删
(片段文件本身不带标识,删了导出就缺合规标识)、转场不要在外部写进草稿;
- 转场为什么不能外部写:剪映转场资源 ID 是私有的,外部写进去静默失效(能打开、不显示、不报错);
而且「叠化」是重叠型——27 个接缝各加 0.1s 会让全片缩短 2.7s,破坏音画对齐。要加在界面里手动加。

既定参数(用户已确认,勿擅改)

> 用户已拍板、AI 不得擅自更改的默认值。分五组速查:A 配音 / B 素材与编排 / C 文案与商品口径 / D 合规与人物 / E 出片·字幕·交付。

A · 配音

项 值
TTS 音色 必须在 Step 3.6 问用户(文案定稿后·排镜前),不许默认选。 用户常用 5 个(全部 2.0):小何 zh_female_xiaohe_uranus_bigtts / 直率英子 zh_female_zhishuaiyingzi_uranus_bigtts / 熊二 zh_male_xionger_uranus_bigtts / Vivi zh_female_vv_uranus_bigtts / 清新女声 zh_female_qingxinnvsheng_uranus_bigtts。1~2 条逐条问;批量问分配方案。清单存 voices_user.json
配音五问 + 音色推荐(v1.23.0 / v1.24.0) 音色 / 句间停顿 0.2s / 开场留白 0.05s / 语速 1.2 倍 / 情感指令(从文案提炼) —— 在 Step 3.6(文案定稿后 · 排镜之前)一次问齐(v1.24.0 改:不是开工时问、也不是到 Step 5 才问)。音色不只必问,还必须给推荐 —— 问法是「我推荐 X(一句理由),想换 Y/Z 也可以」,⛔ 不许只丢 5 个名字让用户挑。四条依据有先后:① 画面里的可辨真人(最硬,一票否决)→ ② 骨架调性 → ③ 品类调性 → ④ 同批分开配。映射表与交付模板见 references/voices-user.md §二
文案时长双标注(v1.24.0 新增) 写文案按 1.2 倍速估句子长短;交付文案时每条必须标出两个档位的秒数 ——「按 1.2 倍 ≈ XX 秒 / 按 1.0 倍 ≈ YY 秒」。算式 净语音 = 字数 ÷ 语速、成片 ≈ 净语音 + (句数−1)×停顿 + 留白;常数(1.2 倍 ≈ 5.2 字/秒、1.0 倍 ≈ 4.3 字/秒)与标定要求见 references/voices-user.md §四
语速 1.2 倍 → --rate 20(换算:倍率 ≈ 1 + rate/100)。1.3 倍 → --rate 30。实测 +20→1.195x(准)、+30→1.267x(高段衰减)。合成时 --target 999 --tol 999 关闭自动调速
静音治理 --trim --lead-margin 0.03 --tail-margin 0.04 --gap 0.2 --head 0.05 --inner-pause 0.2
长段合成 多句并成一段(段内情绪连续,减少拼接点以降低念稿感);字幕按 sublines 切回分句

B · 素材与编排

项 值
切镜阈值 cuts.py 默认自适应:逐点 clip(3.1 × 局部中位数, 20, 45),--merge 0.45 --fps 12。换品类先看 diff 的阈值区间是否合理;旧行为用 --thr-mode global --thr 28 回退
生产模式 1~3 条 = 精品(全池镜头评级、择优不设配额)/≥4 条 = 批量(骨架配额;画面重复度只报不拦——用户 2026-10-05 定调)。用户显式说了条数以用户为准;3~4 条两可地带必须问
借入与镜头复用 借入上限:批量 30%(可调);精品不设上限。⚠ 复用次数不写死(用户:「我也没有规定一个镜头只允许复用两次」—— max_reuse=3 只是兜底值,选镜以文案为准)。镜头复用四条(v1.11.0):① 跨条允许 ② 条内禁止 ③ 复用优先取不同时段(整段用完才整段复现)④ 差异度按镜头算不按素材算。任两条片目标差异度 40~50%(底线 20~30%)。详见 edl-rules.md
刀长下限 ≥ 1.0 秒(30 帧) —— 用户 2026-10-06 订正(原 0.5s)。分档:长镜 ≥4s 首选 / 中等 2.5~4s 主力 / 短镜 1~2.5s 可用 / <1s 绝对禁用。⚠️ 下限与上限必须成对设
长镜不足的判据 排镜前先跑清点脚本拿真实储备 ÷ 需求,再按比值落档:宽裕(≥2) 随便排 / 紧张(1~2) 靠错开取段 + 跨片借入 + 复用 / 不足(<1) 先重排,仍不够才谈补素材。⚠️ 旧参考值 4.7 / 1.2 / 1.0 是玉米批单点推导(4.7 = 153.9s ÷ 33s,分子分母都来自那一批),换品类务必重算;分子分母口径统一按 &gt;=1.8s(与 edl-rules.md 长镜池脚本一致)。别拿「一句一刀」当硬指标算账
重合度 判据 = 同素材「真实时间区间求交」的重叠帧 ÷ 较短成片帧数 ≤ 50%(v1.8.1 统一到 _qsh.overlap_stats,闸门⑤ 与 --compare 同源)。两种模式都只报不拦(--overlap-mode warn)—— 用户 2026-10-05 定调:「只要两条视频画面不是一模一样就可以,有少许偏差就行」;真正要避开的只有「同素材 + 同刀位 + 同时长」(那才是同一条片子)。⚠️ 旧口径「批量模式=硬门槛」已作废。交付说明里必须注明该值仅参考、它从未作为门槛拦过任何东西
单条时长 20~40s(常规取 30s);精品模式可放宽。开工时要把这个取值摆给用户对一眼(用户没给就取 30s 并写明是默认值),不许默默取 —— 它决定后面所有配额

C · 文案与商品口径

项 值
文案通道 有现成文案 → 3A(只做分发/借入预算/钩子分配);无文案且用户明确要求 → 3B 熔炼。开工必问,不许静默选
文案产出 母版数 = f(目标条数),不是固定 2 条:1 条 → 1 母版(别浪费一条)/2 条 → 甲乙各一不派生/3~4 条 → 2 母版交替派生/≥5 条 → 2 母版 + 派生,单条只改一项。共享层的「≥60% 必进项」按 §三执行
骨架推荐(v1.22.0 新增) Step 3.0-前置 必做。骨架 = 从素材融合"长"出来(顺序:素材 → 文案 → 骨架),⛔ 不许先定骨架再找画面。推荐制 + 选择权两层都要给:①【我推荐用】按目标条数给首选 N 个(精品 = 条数/批量 = 条数÷2 向上取整)+ 一句理由;②【还可以换】必须附备选池,用户点名换 → 当场评估、不让他等第二轮。⛔ 不许丢空白菜单让用户自己挑。同骨架默认派生 2 条(必须把 1/3 条的选项摆出来);清单开放(素材长出菜单外的结构照用)。完整规则见 references/gujia-menu.md
商品口径 开工必问(v1.7.0 新增):产地 / 品种 · 规格 · 价格三项。素材标题里的产地 ≠ 用户卖的产地 —— 必须用户明说,不许从素材推断(实测:7 条素材标题全写「陕西大荔」、用户实际卖「山东沾化」,整批返工约 20 分钟)。口径变更 = 换池重做;画面与之冲突的贴纸 / 原片口播单独列给用户定(遮/换/原样保留)

D · 合规与人物

项 值
价格 只用用户告知的价格。素材里的价格一律不参考(底表列出来是为了避开 / 糊除,不是为了抄)。v1.10.5 起口径变更:带价格素材不再整条禁用 —— 改为「出片时糊除 + 重绘我们的价」(详见下一行的机制)。用户未告知 → 本轮不写价格,并避开带价格的画面区间
价格贴纸 · 机制(v1.10.5 口径变更) 原口径「素材带价格 = 商业诋毁红线 → 必禁、永不可豁免」已废(实测:本批 87 镜带价、能承载长句的长镜全在其中,禁掉后 A1 从 10 刀反弹到 15 刀 / 最短 0.43s)。新口径:带价格素材照用,出片时 糊除原贴纸 + 重绘为我们的价。落地:app/annotate.py::_auto_ban() 移除 price 判定(禁用表只剩 person 类);engine/price_relabel.py 糊掉原贴纸、重绘为用户给的价。两条路径:_price_mode(name) —— 有卖价 → relabel(糊 + 重绘);无卖价 → scrub(只糊不 P)("P 出去的价与实际不符"比"糊掉"更麻烦)。三参数:uniform(全片统一基准框)/ force_box(强制框)/ dry=True(预扫只测不计数,防计数翻倍)。⚠ 推翻的是「价格必禁」,没推翻「素材里的价格一律不参考」
价格贴纸 · 样式与规则(v1.10.5) ① 样式(用户截图确认):亮黄字 + 黑描边、无底块 —— 字色 RGB(234,231,33)、描边纯黑宽 ≈6px @1080、字高 ≈75px(⚠ 别从低清截图判样式,颜色会失真)。<br>② 四条规则:B1 有价素材 → 默认全刀加(保持价格条位置稳定),逐句可跳(空镜/纯手部特写/产地远景可跳过,判据写进交付说明);B2 全片无价 → 全刀都不加;B3 我们的价格条 = 全片统一基准框,不跟原贴纸走;B4 糊除区收紧到只盖住字 —— 净外扩只有一处:price_relabel.py 的 PAD_R/PAD_Y = 0.04/0.06(blur_price 自身 pad 已归零、不做二次外扩)。<br>③ 价格条与口播字幕各占一头:价格条按有价素材走(别跟原贴纸走),口播字幕固定放底部(y≈0.72–0.76)—— 否则原片字幕在顶部时两者会挤在一起打架(P0-28)
真人区禁用表 机器全片扫候选 + 逐条看图确认(v1.7.0 起;v1.15.0:确认由 AI 做,不推给用户):scan_faces.py 0.1s/帧密抽 → 看拼图逐段判真假 → 编码进 work/banned.json。不再用稀疏抽帧找真人(3s 一帧实测漏 5 段)。候选 ≠ 禁用:YuNet 假阳性极高。条目带 type(person/price/text/other,v1.8.1)—— 只有 person 能被角色卡豁免
人物一致性 真人与无人平权(v1.14.0,取消"无人优先") —— 编排按文案择优、不回避真人(用不用真人由 AI 按文案与排片自决)。唯一硬红线 = 同片禁换人,机器形式「可辨正脸 ≤ 2 个」由 ⑦ 闸门无条件执行(不给角色卡也拦)。默认不建角色卡;确需锁主角时在 work/cast.json 写一个主角,可辨正脸的刀必须取自该主角,副人物按准入三条(场景可区分 / 叙事有交代 / 只做环境)入片。判据 = Step 1 第 3b 步的 work/persons/(无论用不用真人都必须跑),⑦ 闸门回核。给角色卡后 ⑥ 闸门豁免该片主角/准入副人物区间(只豁免 person 类,价格/文字照拦);不给卡则真人区由 --faceblur 放行 person 类。真人出镜默认开打码;全片无人 = ⑦ 自动 PASS,不算缺陷。完整口径、用户原话与打码风险告知见 Step 4 铁律七 / 铁律七·补
人脸打码(v1.11.1) cut_multi.py --faceblur eye\|face(默认 off=与改动前完全一致)。出片时逐帧给人脸打码,与糊字幕同一趟管线(不多转一次码)。eye=双椭圆只盖两眼(推荐)/face=整脸;跟着头转 + 边缘羽化。默认分级:整刀中位脸宽 ÷ 画面宽 < 4% → 认不出 → 不打(--faceblur-all 关掉)。⑥ 闸门配 --faceblur → person 类放行(价格/文字照拦)。⑦ 闸门不用改。用前必读铁律七·补的两条警示(对查重无用 / 对著作权无用)

E · 出片 · 字幕 · 交付

项 值
出片规格 1080×1920 / 30fps CFR(--norm 1080x1920),逐刀归一化
成片封装 一律带 -movflags +faststart(v1.15.0):索引写文件头 → 点开就能播,不用等下完。取消了 720p 轻量预览版(旧参数 --preview 已删)
原片字幕(v1.9.0 起) 默认处理(cut_multi.py --subs burn);目标一句话 = 别人家的字全抹掉,只留我们的字。做法 = 逐刀实测字幕矩形 → 只糊那一块 → 重绘本片该时刻的字幕(文字查 SRT,不用 OCR 猜)。五条纪律:① 逐刀实测、不跨刀取并集(P0-12);② 横向只按实测 span、不做全宽横条;③ 测不到字幕的刀不糊,但仍要绘本片字幕(P0-26);④ 一刀内可有多段(字幕会在刀内移动,按抽样帧检出位置分段,P0-27);⑤ 退化原则:只有一段时=原行为,零额外成本。我们的字幕在原位重绘 + 全片统一字号(P1-32)。<br>实现要点(track 轨道 / SAMPLES 3→12 / 段外扩半个间隔 / band 只取口播那组行)与逐条踩坑(P0-34~36、长刀四坑 P0-41~44)详见 references/pitfalls.md
原片字幕处理的总目标(用户口径,2026-10-06 确认) 用户原话:「素材的字幕要盖住,价格字幕贴纸也要盖住,然后配上我们自己的字幕。」 —— 就三件事,不用管用什么算法:① 素材的字幕 → 盖住(别人的字全抹掉,不能漏);② 价格贴纸 → 也盖住(素材里的价全抹掉,不管它在哪、会不会移动);③ 配上我们自己的字幕(我们本片的口播字幕 + 我们的价)。一句话:别人家的字全抹掉,只留我们的字。<br>⚠ "位置会移动"的素材怎么办:多看几眼(一刀 10~15 帧)、跟着它走 —— 这是达成"不漏"的唯一路径,不是几个方案里挑一个。技术细节见 pitfalls.md P0-27(开头有同款"先说人话"段落)。
文字处理的两类口径(v1.10.4 新增,别混) 画面里的文字分两类,诉求完全相反,共用同一套测量机制但策略不同:<br>· 口播字幕 → 糊掉后要在原位重绘我们的 → 位置要"准" → 宁窄勿宽(贴实测 span);<br>· 素材价格贴纸 → 糊掉后我们的价格画在固定位置(不跟原贴纸走)→ 覆盖要"全" → 宁宽勿漏(可外扩余量);<br>· 水印 → 覆盖全,不重绘;<br>· 静态贴纸 / 包装印刷文字 → 不处理,交用户(见下一行)。<br>⚠ 价格贴纸的「糊除」与「画新价」解耦:糊永远只糊本刀实测到的贴纸位置,新价永远画在全片统一基准框(uniform 模式)—— 这样原贴纸移动/中途消失都不会让我们的价格条跟着跳
静态贴纸 / 包装印刷文字 不处理,交用户自行处理:它与口播字幕在像素层面分不开,糊它必然误伤产品(pitfalls.md P0-12)
剪映草稿 明文 info 路线:只写明文 draft_info.json,绝不写 draft_content.json;不跑 JyProject。详见 references/jianying-draft-playbook.md

Resources

> scripts/ 是全部可执行脚本;references/ 是规则详解与踩坑库。
> pitfalls.md 是踩坑的单一权威源(本文里凡是标注「详见 pitfalls.md P0-xx」的,正文只留结论,细节一律以那边为准)。

scripts/

  • solve_shots.py —— 文案-镜头双向求解器(v1.10.1 新增;v1.15.1 修默认镜头源:自动探测 work/shots/shots_final.json → shots.json,不再默认读单源工具的 shots_render.json/pool.json/manifest.json;manifest.json 只用于「素材N」编号、缺了照跑;probe 空表退 2、check 不合格退 1,不再静默假成功)。
    probe 模式做素材形态分型(小分镜拼接 / 混合 / 一镜到底);
    check 模式逐句校验「镜头实长 vs 配音实测」,全 OK 即句句一刀。
    详见 production-modes.md 第〇之二节。
  • _qsh.py — 公共路径解析(ffmpeg/src/root/fps/asr 模型)+ 镜头表定位 find_shots()(依次找 work/shots/shots_final.json → shots.json;显式 --shots 时只认它、不回退 —— 回退会拿另一张表校验出"假通过")。所有脚本都从它取路径,不写死。首次使用先跑它做自检。
  • cuts.py — 权威剪辑点表(v1.1.0 新增;v1.2.0 加自适应阈值 + 灰区候选):逐帧灰度差找硬切,scan/diff/check/shots 四个子命令。阈值默认逐点自适应(clip(k × 局部中位数, 20, 45),k=3.1):铝箔反光/快动段自动抬高、纯净静物段自动压低;未达判定线但值得一看的点记为 candidates,shots 遇长镜(>6s)时会列出来提示定点核验。配合 work/shot_fixes.json 修正表产出 work/shots/shots_final.json。排 EDL 的对齐基准以它为准。
  • scan_shots.py — ffmpeg 场景检测切镜(粗筛用):反光/快动会误报、软切会漏检,不单独作依据。
  • dense_probe.py — 对指定区间每 N 秒抽一帧拼图。软切定位、可疑区间复核、价格/文字排查都用它。低分辨率缩略图误判的解药。--calib 做抽帧自校准(请求时刻 → 实际落帧),要推翻既有结论前必须先跑;真逐帧用 --step 1/fps(60fps→0.0167,30fps→0.0334)。
  • probe_label2.py — 密集抽帧定位特定内容镜头(如配料表),末行自动补齐避免 vstack 失败。
  • scan_faces.py — 人脸候选扫描(v1.7.0 新增)· 禁用表 banned.json 的机器初筛:全片密抽帧(默认 0.1s/帧)+ OpenCV YuNet 逐帧检测,产出 work/facescan/(checklist.md 逐条确认表 + &lt;素材&gt;_sheet.jpg 强候选拼图 + &lt;素材&gt;_strip.jpg 时间条 + candidates.json)。参数:--score 0.5(强/弱分界)、--pad 0.5s、--gap 1.5s、--step/--width/--no-strip(提速旋钮)。模型随技能存于 references/face-model/(查找顺序 --model → $QSH_FACE_MODEL → qsh.json.face_model → 技能内副本)。⚠ 产出的是「候选」不是「禁用表」 —— YuNet 在农产品实拍上假阳性极高(素材3 的 170 帧全命中却零真人),判定权一律留给人;读图走 np.fromfile + imdecode(cv2.imread 遇中文路径静默返回 None → 假阴性)。耗时约 0.85s/素材秒(本机 6 核实测 7 条素材 / 594s / 5944 帧 ≈ 8.5 分钟,4 进程并行、可后台跑);逐条看图确认才是真瓶颈(v1.15.0:AI 做,不推给用户)。判据、假阳性实例与三个提速旋钮详见 Step 1 第 3a 步。
  • batch_transcribe.py — 批量口播转写(本地 faster-whisper,不走网络)。需配 asr_prompt 热词。
  • script_mine.py — 素材文案统计底表(v1.3.0 新增,3B 第一步):输入 N 篇口播文案,输出①卖点频次表(自定义词表 + 自动 n-gram,按 60/30 分层)①b 自动候选 ①c 低频词辨析(列出近似片段揪 ASR 错字)②各条开场口播(≈前 5 秒,供钩子归纳)③跨条共用话术片段(同源主判据)+ ③b 同源嫌疑排序 ④价格数字清单(列出来是为了避开)。纯 stdlib,无依赖;语义归并靠模型,脚本只做确定性统计。
  • voiceover.py — 豆包 TTS 分段合成。支持逐段音色/语速/情感/音量;--force 强制重合成。
  • doubao_tts.py — TTS 调用封装(voiceover.py 的依赖)。凭据只从环境变量或项目内 doubao_tts.json 读,不含任何明文密钥。
  • assemble_vo.py — 静音治理 + 逐样本拼装 + 生成零漂移 SRT。需 numpy。v1.10.5 起在出 SRT 前先调 split_subs.py 细切一遍(见下)。
  • split_subs.py — 字幕切屏(v1.10.5 新增):把「按逗号切出来的一句」再细切成一屏一个语义短语,落实用户口径「说一句显示一句」。在 assemble_vo.py 出 SRT 之前调用。规则:有实测停顿按停顿切 / 无则按标点短语切;每屏停留 = 字数 ÷ 语速(目标 0.8~3.0s/屏);< 3 字并入邻屏、> 14 字按标点或虚词断(不拆词)。零漂移(只改"哪几字同屏",不改字的起止时刻)。为什么必须有它:不切则一段 50 字从第 2 秒挂到第 11 秒,字号被压到 32px(标准 51px)还挡画面;切完 18 屏全部 48px 标准字号、最长 624px、不再折行。⚠ _greedy_pack 收口判据不能用"时长够不够" —— 短短语必然被判为不够而并成大屏,正确判据是「短语天然一屏」(pitfalls.md P1-25)。
  • cut_multi.py — 多源出片引擎:逐刀归一化 + 帧数硬校验 + 跨片借入 + 重合度核算 + 片段归档 + 成片一律带 +faststart(v1.15.0;同时取消了 720p 轻量预览版,--preview 参数已删) + 原片字幕处理(v1.9.0)。--compare 的重合度与闸门⑤ 共用 _qsh.overlap_stats(v1.8.1),所以口径一致、结果不受参数顺序影响。旧函数 overlap_frames() 保留为空壳仅为兼容,新代码一律用 _qsh.overlap_stats。--subs burn|strip|off 见下。
  • v1.10.5:新增 --clips-clean(两套切片,主套糊+绘 / 净版糊+不绘)、cut_one_subbed(clean_dst=) 同一遍喂两个 ffmpeg。
  • ⚠ 正式循环里必须补 prepare()(v1.10.5 修,P0-29):预扫循环(dry=True)跑完 relabeler._cur 停在最后一刀;
    正式循环若不重新 prepare,每一刀都在用上一刀的框 → c01 用了 c10 的框 → c01 什么都没糊。
    补 prepare(..., force_box=relabeler._force_box) 即可。"会翻倍"的顾虑是多余的 —— 预扫是 dry=True,
    在 prepare() 内部早退、不计数。
  • strip_subs.py — 原片字幕处理(v1.9.0 新增;v1.10.4 加一刀内分段;v1.10.5 换糊除算法;v1.10.6 track 落地):把素材画面里烧着的原口播字幕糊掉、换成本片自己的字幕。由 cut_multi.py --subs 调用(也可 python strip_subs.py 单刀出自测样片)。三步:① 逐刀实测字幕矩形(抽样 OCR,按(中心 y, 中心 x)二维聚类定行,多行自动合并成一块)→ ② 只糊那一块矩形(不是全宽横条)、四向羽化 → ③ 查 SRT 重绘本片该时刻该显示的那句。测量结果自 v1.10.6 起是 track(时间分段轨道)、apply() 按刀内时间查段;缓存 work/clips_&lt;tag&gt;/subs_bands.json(key 带 CACHE_VER,结构一改就升版本)。
  • 口径(默认处理 + 五条纪律 + 三类易漏形态 + 两类文字诉求相反)见 Step 7 --subs burn;糊除算法(垂直拉伸填充 vs 均质灰)、性能基线、track 三处新坑与全片统一字号见 pitfalls.md P0-12 / P0-26 / P0-27 / P0-30 / P0-34~37 / P0-39 / P0-41~44 / P1-25 / P1-32。
  • blur_faces.py — 人脸 / 眼睛打码(v1.11.1 新增):出片时逐帧给人脸打码,与 strip_subs.py 同构(同样 prepare / apply 两个方法,并进 cut_multi.py 的同一条逐帧管线 → 不多转一次码、不掉画质)。由 cut_multi.py --faceblur eye|face 调用(也可 python blur_faces.py &lt;源&gt; &lt;输出&gt; 单跑自测)。三步:① scan_track() 读本刀的帧(读帧方式与 cut_one_subbed 完全一致,采样点与成片帧一一对应);② build_track() 补断点(HOLD_SEC 0.55s 容差:低头/手挡时保持上次位置,超时就断,免得"脸走了码还钉在原地")+ 只在连续段内平滑(跨段平均会把码从一张脸拖向另一张)+ 逐帧插值;③ apply() 按刀内时间查表 → 画椭圆模糊。坐标一律在输出坐标系实测(复用 strip_subs.normalize_frame,与出片同一个函数,不做手算换算)。<br>参数:SCORE_TH 0.85(别调低,0.60 会在产品上打码 —— 见铁律七·补)、BLUR_MUL 2.0(用户 2026-10-08 在 5 档里选定)、EYE_A/EYE_B 0.34/0.20(椭圆=几何 × 两眼间距)、FACE_A/FACE_B 0.60/0.62、min_ratio 0.04(分级阈值,0=关)。缓存 work/clips_&lt;tag&gt;/face_blur.json(key 带 CACHE_VER)。<br>性能:检测半尺寸 + 每 2 帧(720p 实测 1.5~2.3s / 6s 素材);大核走「缩图模糊再放大」(整脸档椭圆半轴 ≈128px,直接用 cv2.GaussianBlur 单帧 460ms、180 帧要 83s;改后 14s,视觉等价)。
  • price_relabel.py — 价格贴纸糊除 + 重绘(v1.10.5 新增):OCR(RapidOCR)定位素材价格贴纸 → 降采样彻底打散字形(短边→3px)→ PIL 重绘为用户给的价。参数 uniform(全片统一基准框)/ force_box(强制框)/ dry(只测不计数);有卖价走 relabel(糊 + 重绘)、无卖价走 scrub(只糊不 P)。口径与四条规则(B1~B4)、样式(亮黄字 + 黑描边)、PAD_R/PAD_Y = 0.04/0.06 见 §既定参数「价格贴纸」两行。
    > ⚠ blur_price 的羽化曾是"糊不干净"的真凶(P0-31):改边缘固定带宽 band=max(2,min(10,短边*0.18))、核心区强制 alpha=1、模糊核按短边给 —— 框内平均像素差 6.33 → 44.33。函数签名里的 feather=0.35 已不参与计算,日后调羽化改 band 那行。
  • fix_rules.py — 失效特征规则引擎(v1.4.0 新增):读 references/shot-fix-rules.json + 项目 patches,scan 按规则扫全片出嫌疑段(软切长镜 / 反光快动高噪声段 / 过密切点),verify 回放 evidence 做回归自检,migrate 把 v1 表升级为 v2,show 打印规则库。纯 stdlib、不重新抽帧、毫秒级。规则只提示,永不自动改边界。
    verify 支持三种期望值:hit 正例必中 / miss 反例必不中 / fixed 已修复 —— 该现象已被补丁消除,校验的是「补丁还在不在」:不再命中=通过;又命中=补丁被误删/回滚,报「✗ 补丁丢了」。坑修好之后把那条证据改成 fixed,不要删。
  • scan_dupes.py — 素材同源查重 · dHash 感知哈希(v1.8.1 新增):Step 2 分支 A「顺手查一遍同源」的实现。每条素材按 --fps-sample(默认 2,即每 0.5s)抽帧 → 缩到 9×8 灰度算 64 位 dHash → 两两比对,重合率 = 命中采样数 ÷ 较短者采样数(与闸门⑤ 同分母口径)。走 ffmpeg -f rawvideo 管道,不落盘、不吃 Pillow/numpy(-an -sn 不解音频,省时间)。--hamming 默认 6、--fail-over 默认 50%(超了退 1)。它查的是「同一段画面被发了两遍」 —— 时间轴对不上,所以闸门⑤ 根本看不见,只有它能抓(实测遇过两条重合 67%,那种片子只能留一条)。
    ⚠ 它与 cluster_persons.py 是两个不同的问题,别混:本项目 7 条素材实测 —— 素材4/5 人物同源(共享面孔/白塑料箱/字幕版式)但 scan_dupes.py 报 0.0% 画面重合,两个结论都对(同一场拍摄的不同片段,画面本来就不一样)。输出是候选不是判决:缩略图级哈希对"同景别不同角度"会误判,删哪条请先自己看一遍两条片子。
  • cluster_persons.py — 人物聚类 · 认人(v1.8.0 新增 · Step 1 第 3b 步,无论走哪档都必须跑):回答「这是不是同一个人」—— YuNet 检测 + SFace 128 维特征 + 余弦相似度并查集聚类。产出 work/persons/:persons.json(分组 + 区间表)+ P01.jpg…(每人代表帧拼图)+ _overview.jpg(总览图)+ report.md(含「疑似同一人」对账表)。两个默认值是实测调的:--det-score 0.85(真脸 0.93+ / 枣误检 0.53~0.72)、--thresh 0.55(并查集是单链接,0.40 会链式合并把不同的人粘成一簇);--dump-sim 可导出相似度分布调阈值。模型查找顺序同 scan_faces.py。机器只分组、不下结论(既会并错、也会拆人)→ 必须配一步「看总览图合并」(v1.15.0:AI 看,不推给用户)。它是 ⑦ 闸门的输入,缺它直接退 2。阈值依据、拆人实例与对账表用法详见 Step 1 第 3b 步。
  • check_persons.py — 第 ⑦ 道机器闸门 · 人物一致性(v1.8.0 新增;v1.8.1 加人数上限无条件生效;v1.14.0 去"无人优先"表述):按 work/cast.json 角色卡({&quot;1&quot;: {&quot;lead&quot;: &quot;P01&quot;, &quot;support&quot;: [&quot;P03&quot;]}})逐刀核「这把刀里出现的人是否在允许名单内」,同时核「主角占比 ≥ --lead-min 60%」。判据取产物:把 EDL 每刀的 [起点, 起点+帧数/fps] 与 work/persons/persons.json 的人物区间对账(重叠 > --tol 0.10s 才算"这人出镜"),不是看声明。「可辨正脸 ≤ --max-persons 2」无条件生效 —— 不给 --cast 也拦(铁律七第 ② 级「禁换人」的机器形式;v1.8.1 修:此前它锁在角色卡分支里,不给卡时 3 人同片也判通过)。全片零可辨真人 = 直接 PASS,不是缺陷(无人合法,不是"更高级")。阳性测试过:①「角色卡指定主角 P02、画面却用 P01」→ 报「越权出镜 P01(4.0s,刀 1/2)」+「主角占比 0%」;②「3 人同片、不给角色卡」→ 退 1。缺人物表 → 退出码 2。
  • gate_check.py — 五道机器闸门一次跑完(v1.1.0 新增;v1.3.0 加 --overlap-mode;v1.8.1 改⑤判据):句首对齐 / 单镜约束 / 时长一致 / 无重复取镜 / 多片重合度,单一 PASS/FAIL + 非零退出。镜头表默认依次找 work/shots/shots_final.json → shots.json(与 check_sync.py / validate_edl.py 统一走 _qsh.find_shots())。--overlap-mode strict|warn|skip:批量硬门槛 / 精品只报不拦 / 不算;单条成片自动跳过⑤。容差常量:LEAD_TOL=2(画面可先行帧数)/ LATE_TOL=1(只吸收 SRT 毫秒→帧取整)/ SHOT_TOL_F=1 / DUR_TOL=0.05s。
    ⑤ 的判据 v1.8.1 换掉了:从「同素材 + 起点相近 ±0.35s」改为「同素材真实时间区间求交」,分母统一为较短成片帧数,实现收进 _qsh.overlap_stats(与 cut_multi --compare 同源)。旧实现有两个真问题:① 单向盲区 —— 起点差 >0.35s 时无论区间重叠多少一律计 0(实测"起点差 0.5s、重叠一半"报 0.0%,而观众眼里就是同一段);② 分母三处口径 —— gate_check 实算 max(fa,fb) 却打印 fa(短在前时输出「50 帧/50 帧 = 50.0%」自相矛盾),cut_multi 用"本条帧数"(方向不对称:同一对片从长的跑报 50%、从短的报 100%)。现在输出同时给判定值(÷较短者)与参考值(÷较长者,与旧口径可比),并标出同段/错位各多少帧。
  • check_banned.py — 第 ⑥ 道机器闸门 · 内容禁用区间(v1.6.0 新增;v1.8.1 加类型化豁免;v1.10.5 换基准):逐刀核 [起点, 起点+帧数/fps] 是否撞 work/banned.json 的禁用区间(真人正脸 / 带价格 / 片头碎片帧 / 顶部遮挡盖不住的强调字),1 帧容差。禁用表支持三种写法,end&lt;=start 自动按占位跳过;--json 输出结构化结果(banned_total + 逐刀 verdict),便于失败路由。找不到禁用表 → 退出码 2,绝不放行。另有两道防静默假通过:① 基准改成「标注文件的名字空间」(v1.10.5 修)—— 判据 = EDL ⊆ 已标注素材(基准取 annot/annot.json),不是「禁用表 ∩ EDL ≠ ∅」(干净素材本就不命中禁用表,旧判据会把"素材全干净"误判成"闸门没生效");annot.json 缺席时退化为旧行为(与禁用表宽松归一比对),不因缺文件误拦;② 条目类型化(person / price / text / other,不写则从 why 文本推断、价格优先),--cast 角色卡只豁免 person 类,价格/文字类照拦(--exempt-kinds 可改,默认 person)。
  • verify_reencode.py — 产物反测(v1.6.0 新增 · 铁律六的实现):任何重编码之后,核「帧数逐条相等」+「出片真正用到的每个切点,源与产物的落帧 pts 偏差 ≤1 帧」。专治 VFR 源静默丢帧(默认 CFR 编码会吞帧,实测 5~9 帧 / 漂 0.15s)。抽帧一律 -copyts(否则 pts_time 从 0 重算,看着像巨大偏移)。--no-pts 只比帧数(快)。
  • validate_edl.py — 闸门①(细):每刀是否落在单一镜头内。
  • check_sync.py — 闸门①②③(细):句首=刀界 + 画面帧数=配音时长 + 单镜约束。
  • qc_sync_frames.py — 逐句音画自查关(不是机器闸门;AI 自己看图判,不推给用户):逐句开口抽帧拼图。默认按编号挑 output/成片_&lt;tag&gt;*.mp4(v1.15.0 起不再找预览版),--mp4 可指定。

references/

  • script-synthesis.md — 素材文案熔炼(v1.3.0 新增):3B 通道全流程——触发铁律(先问有没有文案)、口播获取优先级与 whisper.cpp 部署、三层提取(口播层选举 / 画面层支撑 / 钩子层双冲击)、2 条母版规则、派生变体与撞钩子检测、前 5 秒六项专项检查、价格规则、文案评审关产出模板、与文案家族的边界表述。
  • production-modes.md — 双生产模式(v1.3.0 新增):批量 vs 精品的全维对照(优化目标/素材池用法/配比/闸门)、模式判定与两可地带的问法、Step 2/4/6 分叉、与文案能力的联动、交付流程与剪映草稿路线说明。
  • shot-fix-rules.json — 失效特征规则库(v1.4.0 新增):6 条规则(R1 软切长镜 / R2 高噪声段 / R6 过密切点 / R3 孤立性已被否 / R4 误报逐点判定不可分 / R5 短镜内单个漏切抓不到),每条带 feature 判据、why、advice、evidence(含反例)。跨素材可复用的判据来源;项目现场的修正不写这里,写 work/shot_fixes.json 的 patches。
  • shot-boundary-playbook.md — 镜头边界定位手册(v1.1.0 新增;v1.4.0 重写修正表一节):三把尺子的分工、软切/漏切/误报的识别、失效特征规则库的用法与「哪些失效自动层面无解」、容差设定、真实案例。
  • shot-audit-playbook.md — 素材体检手册:切镜/标注/画面主体筛查/价格信息排查的完整方法与判据。
  • gujia-menu.md — 开工骨架菜单(v1.2.0,2026-10-10 新增):带货文案骨架清单与推荐规则。十种常见骨架(开箱实测 / 溯源故事 / 自用分享 / 对比 / 单点爆破 / 答疑 / 反向劝退 / 认知纠正 / 身份点名 / 算账,开放式清单不限于此)+ 推荐个数算法 + 交付模板(必修推荐栏 + 备选池栏) + 不重样检查 + 借入清单解释。Step 3.0-前置 必读。
  • script-matrix.md — 文案矩阵:产量测算公式、借入预算、钩子分配、与文案家族技能的接口(3A 通道的细则)。
  • edl-rules.md — EDL 四铁律详解 + 反例 + 镜头复用四条规则 + 长镜池清点脚本(编排前必读)。含「刀长下限 1.0s」「刀长上限·一镜到底」「镜头复用(跨条允许/条内禁止/错开取段/按镜头算)」「长镜不足时怎么办」四章。
  • voices-user.md — 配音五问 + 音色推荐规则 + 用户 5 个音色清单 + 语速换算与时长标注口径 + 情感指令提炼要点(v1.11.1 新增,v1.23.0 补「音色推荐」,v1.24.0 补「时长双标注」+ 改时序;Step 3.6 问一次 / Step 5 执行细节必读)。
  • allow_cross.example.json — 跨镜头白名单格式示例(复制到 &lt;项目根&gt;/work/allow_cross.json 生效):key = &lt;成片编号&gt;|&lt;素材名&gt;|&lt;该刀起点秒&gt;,value = 为什么允许跨这次切点(必须写明已抽帧目视核验)。这是例外通道、不是常规手段;按素材生成,换一批素材必须重建(旧条目一律作废)。
  • pitfalls.md — 踩坑清单(P0/P1 分级 + 解法 + 验证命令)。
  • jianying-draft-playbook.md — 剪映草稿生成手册(v1.5.0 新增):三条硬约束(明文 info 路线 / 坐标语义 / 段长用累计帧数派生)、10 项落盘检查清单、模板保命约定、为什么不用 JyProject、复现命令与"草稿列表里没出现"的五步排障。
  • jianying-draft-template/ — 剪映明文模板副本(draft_info.json + draft_meta_info.json,共 59KB,不含素材视频):整台机器上仅有的明文样板之一。另一处在旧项目目录 output/剪映草稿包/ 下、易被误删,故随技能存一份;生成草稿的脚本优先读这一份。勿删。
  • face-model/ — 人脸模型副本(v1.7.0 新增 / v1.8.0 补齐,共约 39MB):face_detection_yunet_2023mar.onnx(检测,232KB,供 scan_faces.py / cluster_persons.py 用)+ face_recognition_sface_2021dec.onnx(特征比对,约 37MB,供 cluster_persons.py 认人用,源自 OpenCV Zoo)。原模型躺在另一个技能的目录里(ecommerce-quick-cut/resources/face/),跨技能依赖易断,故随技能存一份并优先读这一份。勿删。
    模型出问题需要重新下载时(OpenCV Zoo main 分支):
    https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx
    https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx
    (两者都留包是用户 2026-10-02 的决定;SFace 37MB 会让整个技能包约 37.7MB,超过 SkillHub publish 接口的 10MB 上限 —— 已知,未处理。)

与千枢汇技能家族衔接

  • 文案(上游):【千川素材:】qianshuhui-qianchuan-sucai|【新文案:】qianshuhui-xinwenan|【爆款文案仿写:】qianshuhui-baokuan-fangxie|【开头优化:】qianshuhui-kaipianyouhua。
    → 本技能不凭空写文案(没有商品信息、不做从零创作)、不内置合规词库;
    但它能从素材自身熔炼文案(3B)——素材是它唯一且充分的输入。
    3A 时只做分发/借入预算/钩子分配;3B 产出的文案若需广告合规,仍送 baokuan-fangxie 的分层合规门禁。
  • 草稿工程(下游):qianshuhui-hunjian(千枢汇·带货素材自动混剪)。
    → 本技能出「EDL + 配音 + 片段目录 + 成片」;剪映草稿自 v1.5.0 起由本技能自己生成
    (明文 info 路线,见 references/jianying-draft-playbook.md),不再交给 hunjian ——
    它的 JyProject 路线写的明文 draft_content.json 在本机剪映会被判为损坏(见 P0-7)。
  • 两者都涉及"文案配画面"但尺度不同,选择依据见文首「职责边界」表。

版本变更记录(已迁出)

> 完整历史在 references/CHANGELOG.md(2026-10-06 迁出,约 780 行)。
> ⚠️ 历史记录里的旧数值(0.5s、≤50% 硬门槛、≤2 次复用、先出 2 条母版、价格必禁)
> 都是已作废的口径,现行规则以本文「现行口径速查」和「既定参数」为准,别按历史执行。

版本主线(详情看 CHANGELOG):
- v2.0.0(2026-10-10)技能页整页重排:既定参数拆 5 组速查、九个章节补二级小标题与速查表、7 组重复段合并去重(内容零丢失)、简介压到约 580 字符。这是 v1.9.1 → v1.24.0 共 25 次演进后的首次发布(本地攒了 25 版未发,本次一次累积上线)
- v1.12.0(2026-10-06)「不写死」定调落地 · Step 3.0 改「矛盾才上报」· 文档-代码三层对齐 · 结构重组(CHANGELOG 迁出+速查节)
- v1.11.x(2026-10-06)刀长下限 1.0s · 复用不设上限 · 配音五问 · 文案与画面关系定调 · 「矛盾才上报」
- v1.10.x(2026-10-05/06)价格贴纸改「糊除+重绘」· 字幕分段轨道 · 品名贴纸判据 · 画面重复度只报不拦
- v1.9.x(2026-10-05)原片字幕逐刀实测替换
- v1.8.x(2026-10-04)人物一致性三级 · 重合度口径统一
- v1.3~1.7 · 双生产模式 · 商品口径必问 · 真人禁用表

沉淀在历史里的重要教训(编号可 grep):P0-12 静态贴纸别糊 / P0-22 抽帧目视核验 /
P0-24 只设下限会滑向碎镜 / P0-27 一刀内字幕可分段 / P1-32 全片统一字号

常见问题

5 问
答案由本站依据条目字段整理
千枢汇·多源融合混剪引擎怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_1518b4a4/qianshuhui-duoyuan-hunjian。安装方式为未标注。装完刷新技能列表或重开客户端。

千枢汇·多源融合混剪引擎支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

千枢汇·多源融合混剪引擎权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

千枢汇·多源融合混剪引擎收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

千枢汇·多源融合混剪引擎用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。