B-roll 系统实况复盘

2026-08-04 · 复刻《开工前必买 5 样》(源片 7662255885925748010,博主「张师傅讲装修」)过程中暴露的问题、修法,以及系统流程总览

一条 64 秒的片子要 13 个 B-roll 镜头。素材库只供上 5 个,8 个靠生成兜底。 这个比例逼出了三个结构性问题——都不是「素材不够」,而是系统在空转而指标不报错。 本文按「生产过程碰到什么」和「系统层面是什么毛病」两条线记录,最后附整套流程设计。

13
B-roll 需求
5 / 8
库内命中 / 生成兜底
23% → 77%
top-1 对题率
3820 → 4550
检索放行池(段)
63.5%
has_face 标注错误率
$2.07
本条总花费(上限 6)

一、生产过程中碰到的问题

按产线顺序排。红线 是会造成合规事故的, 已修 是本次改掉的,待办 是还挂着的。

A取材:素材库能不能给出货

A1素材库映像中途掉盘,检索静默返回空待办

现象
会话过半时外接映像变成「未挂载」,是用户提醒才发现。
为什么危险
检索不报错,只是返回空结果——看起来像「库里没有这个镜头」, 于是直接走生成兜底,白花钱。这是「空输入被当成干净输出」的典型形状。
修法
broll-retrieve.py 起手应自检挂载状态并硬失败。 目前只能人工先跑 mount-broll.sh status

A2被复刻的源片就躺在素材库里,而且没拉黑红线已开单独任务

现象
按物件词查库时翻出一条「钥匙密码盒+阻尼片+隔音棉」的产品摆拍组图, 解说词跟本条源片同一选题同一话术。顺藤摸瓜查到库里存着 张师傅讲装修 视频/004_7662255885925748010.mp4——文件名就是源片 ID, 时长同为 112.965s,第 9 秒帧逐像素一致。
为什么难发现
库内 md5 是 aee77ff7…,重新下载得到的是 3c954549…—— 同一条片子两个 md5,按 md5 查撞车会漏掉。
风险面
该源在库里有 55 个切片,2 条已标注,其中 1 条 approved=1 会被正常检索到, 黑名单里没有它。全库只有 61% 的切片算过 pHash,「pHash 邻域」这层对其余 39% 根本不生效。
本条影响
逐条核过 37 个候选来源,实际引用 0 次,未违规。
为什么是红线
越对题的镜头越可能就是原片自己的镜头——用了等于没换。

A3系统从不说「我没有」已改善

现象
13 个需求,检索给出 7 个 ok、6 个 weakno_match 恒为 0。而实际上 8 个需求库里真没有对题素材。
根因
向量检索天生「永远能排出个第一名」。及格线模块自己的文档就承认: ≥0.62 那一档仍有 71% 不可用
修法
加了「主体线」判据(见 E4)。但根治要靠看图精排, 所以 skill 那条「命中 ≥1 也必须逐条打开看」是硬规矩,不能省。

A4两类货全库为零:翻车缺陷 & 产品单品摆拍待补采

实测
把 8 个缺口在全库(不限放行池)搜了一遍:生锈 4 条、纯铜地漏 4 条、 水封芯 1 条、前置过滤器 5 条(且都只是解说词提到,画面里没有)、 烟道止逆阀 15 条(同上)。
根因
库是按装修工序(水电/瓦工/木工/美缝…)攒的施工实拍; 而这条源片给的是手持产品单品特写。拍施工的人不会专门去拍一个生锈的地漏。 这也是 skill「第 0 步:先把源片 B-roll 看一遍」要解决的—— 需求侧错的不是关键词,是景别
好消息
产线在自愈:这条片子生成的 8 张兜底图交付后已自动入库并放行。 实测搜「生锈地漏」「水封芯」,排第一的就是它们(相似度 0.74 / 0.73)—— 下条片子遇到同样需求不用再花钱生成
B选材:候选到底能不能用

B1切片内部跨了剪辑点,没有任何闸门覆盖只能靠眼睛

现象
s10 选中的切片中点帧是「开孔机切瓷砖」,但我要的前 102 帧是「铺贴」—— 3.5 秒的切片里有一个镜头切换点。合成后才在联系表里发现。
为什么闸门查不出
闪切闸门只扫 A-roll 切片;撞车闸门做跨片段比较; 人脸闸门只看有没有脸。没有一道在看「一条 B-roll 内部有没有换镜头」
修法
选材时必须抽首/中/尾三帧看,只看中点帧会漏。 本条另一条 s03 也跨剪辑点,只用了前 1.6 秒避开。

B2两个镜头选到同一面墙 → 会撞车

现象
s11 的最佳候选与 s02 出自同一条源片的同一面墙,成片里就是同一画面播两遍。
修法
换成另一条源片的阀件特写。去重前移到选材期比事后比图有效得多—— 同一源片 ≤2 条、同一切片全片只用一次。

B3库内源片帧率不统一,按帧切会切错

事实
同一批候选里有 25 / 29.97 / 30 / 60 fps 四种trim=start_frame=N 作用在源片帧号上,60fps 源取 56 帧、输出 30fps 后只剩 28 帧。
修法
滤镜链最前面fps=30 再 trim,切完 ffprobe -count_frames 逐条核对。本条 13 条全部帧数精确匹配。

B4烧录字幕:能裁不擦,而且要量描边不量白字

处置顺序
B-roll 一律(从顶部保留、放大填满),不擦。 擦是算法在猜,裁是 100% 干净。
易错点
抖音字幕是「白字 + 黑描边」,画面上最上面一行像素是描边不是字。 按白字上沿裁完底部会留一排黑尖角。本条 s03 裁到 1240、s10 裁到 1682,都留了描边余量。
C生成兜底:库里没有时怎么造

C1/edit 改不动整个空间主体

现象
s13「真漏了泡了家具更亏」,第一版生成图只是一间地面发潮的空房,看不出积水, 翻车后果立不住。
根因
/edit编辑不是重画,会保留参考底约 90% 的内容。 我给的底是一张广角空间照,它只能做局部微调,换不掉整个空间主体。
修法
木地板特写底,prompt 写死「积水铺满画面、板缝起拱、踢脚线水痕」,一次就对。 规律:加/换一个物件→同一张空间底改得动;换空间主体→必须换底; 特写→配特写底并写死 fills the entire frame

C2一个需求一张参考底,不能复用

为什么
同一张底喂多次,出来的几个镜头会看着是同一个地方(历史上被打回过:26 个 B-roll 里 8 个同一个客厅)。
本条做法
8 张参考底来自 8 个不同源文件;prompt 统一写死拍摄条件 (手机竖拍/自然光/无文字无品牌无人脸);静止图一律挂 zoompan 缓慢推近到 1.10× (必须显式给 x/y,否则往左上角推)。
D审片:闸门自己也会出错

D1撞车闸门误报

报警
s03 与 s13 疑似撞车。
实况
s03 是银白隔音棉包下水管(工地),s13 是深色泡水木地板,画面毫不相干
根因
闸门比的是 16×16 灰度构图,两者恰好都是「一条斜向长条占画面大半」。 与既有记录的「同工序素材整批误报」是同一形状。
处置
人眼核对后放行,结论填进 review-log.jsonlverdict

D2看图理解闸门是单点阻塞结构问题

现象
另一个会话的 VL 标注任务占着单实例锁跑了 1 小时 20 分,审片只能干等。
为什么不能抢
两个 Qwen3-VL 抢同一块 MPS 不是慢一点,是双方都停摆(活锁)。 锁本身是对的。
真正的问题
产线上只有一块 MPS,而标注任务和审片任务都要用它。 本条改为轮询等待、对方释放后自动补跑,最终 14/14 全覆盖通过。

二、系统层面的三个结构性问题(已修,PR #94)

上面那些是「这一条片子的具体麻烦」。下面三个是系统一直在空转、而所有指标都不报错的问题。

E1政策改了,存量没跟着改放行池 3820 → 4550

现象
1021 个段挂着 needs_human=1 从不参与检索。
不是审核积压
2026-08-04 人审校准 130 段之后口径改了: 「有脸/有字」不再是池子级一票否决(路人工人可用、字幕用前裁掉, 真红线只有第三方水印和被复刻博主本人)。检索器已按新口径走, 但按旧口径拦下的那批从来没人放它们回来
怎么认出来的
放行池 91% 是「无脸无字」,被拦那批 622 条有脸、537 条有字, 而且画质分反而更高(锐度 2.27 vs 1.59)。画质更好却被扣着 = 不是画质问题。
修法
新增 readmit-held-segments.py。关键决定:不信标签,逐条抽帧实测

E2「有没有脸」这个标注 63.5% 是错的已用实测取代

实测
用 YuNet 逐条抽帧复核:标注为「有脸」的 614 条里, 390 条实测没有可辨认的脸(错误率 63.5%); 标注为「无脸」的 364 条里也有 23 条实测有大脸(6.3%)。标签两个方向都会错。
处置
放行 731 段,仍扣 291 段(实测确有 ≥900px² 的清晰大脸)。 扣着的理由:「被复刻博主本人」这条红线目前只靠一份残缺的黑名单挡着,宁可漏放不可错放。 留了 jsonl 回滚记录。

E3交付后回填的新素材是隐形的已修 + 存量已补

现象
这条片子交付后回填,14 个素材入库并置 approved=1, 但一个字的描述都没有
根因
入库时描述取自分镜的 _need 字段,而那个字段只有走标准 emit 流程才有。手写分镜的片子(画中画、对照清单这类版面特殊的)绕过它 → 描述为空 → 建出来是一份空文档的向量 → 素材永远搜不到。
为什么最阴
它以 approved=1 的样子躺在池子里,看起来像已经做完了—— 比不入库更糟。花钱生成的素材下条片子还得再买一次。
修法
没描述就不放行并显式报警;从 expect.jsonneeds.json 捞回描述;入库后自动建向量(以前只打印一句「记得跑」,没人跑)。

E4标注记「画面里有什么」,检索要的是「主体是什么」已加主体线

现象
要一个「马桶冲水」的镜头,库里 3 条候选的标注里都写着马桶—— 但一律排在 6 个元素里的第 5 位vl_subject 其实是 刮腻子/刷涂料/包烟道管。马桶只是角落里恰好入镜。
根因
现有两路向量(文本 embedding、视觉 vl_embedding) 都把「主体」和「画面里还有啥」混在一份文档里,分不开。
修法
新增第三路 subj_embedding只由主体+动作构成; 及格线加「主体线 0.54」,主体不命中降级为存疑——只降不拦 (主体标注本身也可能标错,最终由人眼定夺)。
阈值怎么定的
6 个人工判定样本(可用最低 0.575 / 不可用最高 0.508,取中点)。 样本量小这件事写进了代码——CALIB 表 + 自检 + 「经验下限不是统计推断」的警告, 每条片子交付后往里加样本重画线。
一条方法教训。我第一版诊断报的是「目录只编了 15%,最大杠杆是补目录」——这个数是错的。 我拿「有多少切片是某个放行段的代表帧」当了覆盖率。真实结构是 25,875 个切片只来自 1,035 个场景(每场景约 25 个重叠窗口),段已覆盖 98.5% 的场景,按切片算是 87.6%。 切片/场景/段/代表帧是四个粒度,挑错一个能把 88% 说成 15%,把人往完全错误的方向带。 报覆盖率之前先问「分母是什么」。

三、修复效果

指标修复前修复后说明
检索 top-1 对题率23%77% 拿本条 13 个需求端到端重跑
放行池(可检索的段)3,8204,550 +730,重新入池 731 段
被扣着的段1,021291 剩下的实测确有清晰大脸
放行但没有向量(搜不到)140 回填素材已补描述并建向量
有「主体」向量的段03,262 9.7 秒建完,空闲工人每批自动增量
回头客本(学习回路)290 此前几乎无人做交付后写回

四、B-roll 系统流程设计总览

整套系统分入库检索使用回流四段, 外加一个「机器闲了自动干活」的旁路。

① 入库 源视频 1,208 条 切镜头 → 切片 25,875 个重叠窗口 归组 sibling_group 1,035 个场景 标注(文字 + 看图) 4,842 段 放行判定 4,550 进池 / 291 扣 ② 建向量(三路) 文本向量 embedding 动作·事实·物件清单·搜索短语 视觉向量 vl_embedding 主体·动作·物件·场景(模型看过帧) 主体向量 subj_embedding ★新 只有主体+动作 → 分开「主体」与「陪衬」 ③ 检索 口播 → 画面需求 写「看得见的东西」 带景别、带证据层 编码 + 三路混合 打分 → 打散去重 及格线 retrieval_gate <0.52 报缺货|<0.62 存疑 主体分 <0.54 降级 ★新 ok / weak → 逐条打开看 no_match → 生成兜底 ④ 使用(每一步都有闸门) 裁字幕 / 归一 30fps 按帧切,逐条核帧数 人脸闸门 YuNet 逐帧 撞车闸门 跨窗口比构图 看图理解闸门 对题/撞车/店招 ⑤ 回流(交付后必跑) 战绩回填 + 库外素材入库 带描述才放行 → 自动建向量 ★新 回喂放行池 旁路 · 空闲工人 idle-worker.sh 负载低 + 没人剪片 + VL 锁空闲 → 自动补标注并建主体向量;有人一用就让路(两个 VL 抢同一块 MPS 会活锁)

各环节的关键约束

环节要点踩过的坑
入库 源视频切成 3.5 秒重叠窗口,同场景归一个 sibling_group, 质量分(锐度/稳定/光照)+ pHash 去重 只有 61% 的切片算过 pHash,黑名单的「pHash 邻域」对其余无效
标注 文字标注(主体/景别/动作/物件清单/搜索短语)+ 本地 VL 模型看图标注 (主体/工序/物件/场景) 物件清单是并列的,「在画面里」和「就是主体」分不开 → 已加主体向量
放行 红线只有三条:第三方水印、被复刻源片黑名单、待删。 有脸/有字不再一票否决,往下传成 needs_erase/has_person 标记 口径 2026-08-04 才改,1021 段存量此前一直没跟着放 → 已补
检索 需求要写画面话不是口播原话;搜物件不搜工序; 证据层三要素=物件+动作+位置 no_match 恒为 0——它永远排得出第一名,所以命中也必须逐条打开看
使用 fps=30 归一再按帧切;能裁不擦;人脸闸门必须扫最终处理链之后的画面 锐化会把原本检不到的脸检出来;一条 B-roll 内部跨剪辑点无闸门覆盖
回流 成片交付 = 里面每个镜头都过了人眼那关,是质量最高的标注数据。 库内段记「回头客」,库外素材入库并放行 没描述就入库 = 隐形素材,比不入库更糟 → 已改成硬拦

还挂着的三件事