关于 flux-3-product-ads
flux-3-product-ads 是面向广告创作者的 FLUX 3 产品广告制作技能,涵盖生成画面与旁白的协作,以及确定性剪辑。它还说明如何设计镜头、依据音频安排时序,并检查视觉与同步问题。
主要功能
- 01设计适用于生成视频的镜头
- 02生成画面素材与旁白
- 03筛查旁白并据此安排时序
- 04确定性剪辑与母带处理
- 05通过测量指标检查成片
适用场景
- 01规划 12–60 秒广告的镜头
- 02让剪辑与生成旁白对齐
- 03诊断反转片段后的同步问题
- 04核对参考静帧间的产品身份
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ black-forest-labs/ skills --skill flux-3-product-ads安装后在 Claude Code 中输入/flux-3-product-ads确认已加载。
附带文件metadata.jsonreferences/pipeline.md
详细介绍
FLUX 3 产品广告
一支成片包含两项工作,而不是一项。FLUX 3 生成画面和语音;确定性处理流程则负责剪辑、计时、添加字幕并完成母版制作。明确划分界限:模型处理只有模型才能完成的工作,所有计算机能够精确计算的内容都不要交给模型。
这项技能所依赖的路由信息位于 flux-3-generate 中。请先阅读其中关于 /v1/flux-3-video、轮询和下载行为的说明。续写行为(包括 v2v 链接实际返回的内容)见 flux-3-keyframes-continuation。
这里的所有流程都已在 12、30 和 60 秒时长下运行过。只有在某种时长下才成立的规则都会特别注明。不要假设为 10 秒、三镜头广告撰写的任何内容,不经长时长重新测试就能直接适用:在产生本次修订的运行中,两项在 10 秒时正确的计时逻辑,被发现分别存在一个隐蔽的正确性错误和一个复杂度错误;只有在更长的旁白中才会出现。
工作结构
- 设计能够经受生成的镜头。
- 在同一轮中生成画面素材和 VO。
- 先用机器筛查 VO,再亲自收听。
- 根据音频推导计时。
- 以确定性方式组装。
- 根据测量结果进行验收,包括那些看似通过的失败情况。
1. 镜头设计
三个镜头撑起一支 10 秒广告:揭示、证明、收束。揭示部分呈现物体,证明部分展示它完成文案所声称的那件事,收束部分落到品牌。
时长较长的广告需要更多节拍和更多画面素材。一段素材在计入转场溶解后,可提供约 4 到 5 秒的可用中段,因此镜头数量应为时长除以约 4.5 后向上取整;素材不足无法平滑弥补:构建会直接失败,无法合法放置剪切点。实测结果:12 秒用了 3 段素材,30 秒用了 6 段,60 秒用了 11 段。用 9 段素材规划的 60 秒广告完全无法剪辑。
在 30 秒及以上时长下,揭示/证明/收束已不足以填满时间。效果良好的结构是:聚焦材质的钩子、完整呈现物体、细节、运作机制、状态变化、产品为你带来的改变、品牌。重要的是每个节拍都要有自己的镜头,而不是结构必须分成三部分。
以动作的起止位置为锚点。 生成片段的首帧和末帧值得信赖,中间部分则具有创造性。起止位置能够限定中间动作的镜头通常表现良好;需要模型自行创造几何结构的动作则不行。
可行:高光在表面移动,环状部件旋转一小段弧度后停下,手柄升起后停下,盖子稍稍打开。
两个看似可行、实际不行的镜头:一只手在纸上画出一条墨线,以及一部手机降入画面并落在产品上。两者都曾被预测会因“移动”或“物体进入画面”而失败。实际生成的画面看起来正确,通过了所有信号验收,也被用于母版制作,但最终都因视觉效果不合格而被拒绝。笔尖尚未到达,墨迹就已经向前延伸,纸张则在下方滑动;那部“手机”只是一块没有任何特征的板子,宽度和它落下的垫子一样。抵达不等于正确,这正是陷阱所在:几乎可实现的镜头,其失败模式不是信号出错,而是物体本身不对;任何测量都无法发现这一点。请参阅第 6 节的语义验收。
不可行:多圈旋转,以及两个物体同时旋转。要求曲柄完整旋转 2 到 3 圈,结果只转了约 180 度,随后发生变形,并在手臂遮挡自身时消失。要求带滚花的环状部件旋转两圈,同时让它所在的头部倾斜,结果完全没有动作:两个动作都没发生,片段静止不动。
决定成败的不是移动,也不是遮挡,而是模型是否必须创造它从未见过的几何结构。穿过画面的手是一个轮廓已知的刚体。下降的手机也是刚体。曲柄旋转 720 度时,模型必须绘制它的背面;它就在这里失败了。设计时要避免需要创造几何结构,而不是避免移动。 四分之一圈并不是旋转镜头的安全备用方案,而是一个看不出来的方案。 失败的旋钮镜头采用安全方案后,技术上虽然成功了,却仍然无法使用,因为在微距画面中,滚花环轻微旋转看起来就像什么都没发生。旋转镜头失败时,替代镜头应该是光线扫过静止物体。这是整个系统中最可靠的动态效果,也始终能让画面看起来有生命力。
物体必须进入画面时,就生成它离开画面的镜头,然后倒放片段。 这是本节最有价值的技巧,因为它把一个创造物体的问题转化成了一个平移物体的问题。同一个镜头尝试了三次,每次只改变一个变量:
| 尝试 | 方法 | 结果 |
|---|---|---|
| 1 | 描述手机向下落;关键帧里没有手机 | 变成了和垫子一样宽的板状物 |
| 2 | 更详细地描述手机(垫子直径的三分之二、厚 8mm、深色玻璃正面、金属边框、圆角,明确要求不要变形);关键帧里仍然没有手机 | 还是板状物,只是现在倾斜着,边缘还伸出了垫子 |
| 3 | 关键帧中已经有一部比例正确的手机;生成手机向上离开的画面;后期使用 ffmpeg -vf reverse | 手机正确、比例正确,整个移动过程中始终保持一致 |
增加提示词细节并不能解决凭空生成物体的问题。去掉凭空生成这一步就解决了。如果物体已在关键帧中,模型只需要移动它已经看见的东西;比例也不会漂移,因为模型从未需要决定它的比例。代价:一个滤镜。
有两点需要留意。所有光线变化都要按倒放后看起来正确的方向来设计;还要检查源静帧的摄像机高度是否与相邻镜头一致,因为为其他目的拍摄的静帧未必能和它们顺畅衔接。
**倒放会把动作移到片段的另一端,而你之前推算的任何时序现在都不再准确。**这是这个技巧掩盖的代价,它会以同步失败的形式出现在一个此前正常的位置。升起动作的峰值出现在一段 6.04s 片段的 5.79s 处,也就是结束前四分之一秒。倒放后,同一峰值会出现在 0.17s 处。其他一切都没变:时长相同、帧数相同、文件大小等级相同。
这很重要,因为素材只能在片段中向后滑动,不能早于它的第一帧。因此,动作可触及的时间窗口会收窄到大约 [peak - segment_slack, peak],而出现在 0.17s 的动作最多只能落在片段最开始的一小段时间内。为倒放前素材选择的锚点词在几秒之后,因此永久无法触及;构建过程也正确地将其报告为夹紧:
slip : shot 3 in=0.00s -> action 14.32s vs word 15.62s (-1.30s)
CLAMPED (reachable 13.00-14.32s, word at 15.62s)
陷阱在于,这看起来像是漂移。素材与通过测试的那次完全相同,VO 未作改动,时长也精确到采样点,因此所有“有没有东西动过?”的检查都毫无问题,只有数值与一天前写下的备注对不上。发生变化的是文件内部的内容。
由此得出两条规则。任何会改变动作在片段中位置的后期处理步骤之后,都要重新推算锚点,尤其是上述倒放;并且要把倒放视为一份新素材,而不是对旧素材的编辑。还有,倒放素材需要较早发生动作时,要把它锚定到较早的词上:峰值出现在前几帧的落下动作,应该锚定到该句的第一个词,而不是片段正放时描述动作的那个词。
**要验证预测,而不是盲目信任预测。**在同一份简报中,为高风险镜头提供两种提示词:一个 hard_prompt,一个安全的 prompt;两种都生成,并都保留下来。每个高风险镜头多生成一次,才能在模型不断改进的过程中确保本节的判断经得起检验;这也是如何发现上文两个“看似不可能”的镜头的。
**在每条提示词中明确写出支撑物。**明确提到产品的接触阴影和倒影。产品即使能完美保持外观和运动一致性,也仍可能看起来像是贴在画面上,因为没有任何描述能确保它的阴影。这种画面能通过外观一致性检查,但人一眼就会觉得是假的。 镜头锁定仅具有指导作用。“镜头锁定、不推进、不平移、不变焦”仍无法避免视差和漂移。设计镜头时应考虑能容忍少量移动,而不是指望提示词能禁止移动。
1b. 先准备参考静帧,并听取模型的意见
每个视频素材都会继承其静帧,因为 i2v 会将关键帧视为实际内容。静帧即使只是有一点问题,也会污染基于它生成的每个片段,因此必须在启动任何视频任务前准备好参考素材包。
**当产品是真实产品时,素材包应从照片衍生,而不是从零开始编写。**这条路更简单,也能跳过下文所述的整类失败情况,因为不必用一段不变特征描述,让模型据此构建物体。将提供的照片作为标准静帧,然后使用 FLUX 2 input_image 保留身份特征,从该照片生成其余角度,并设置种子以确保素材包可复现。仍然要编写不变特征描述,方法是从照片中读取这些特征:后续的身份和语义检查会据此进行验证。在一次基于单张真实产品照片的运行中,以这种方式生成的三个角度保留了所有指定特征,没有任何静帧需要重新生成。
这种做法无法解决两件事。静帧忠实于原图,视频仍然会漂移,因此下文的内部帧和身份检查仍然适用。此外,真实照片通常是在无缝白色背景下拍摄的产品目录图,没有可供剪辑切换的布景:如果镜头在构图和比例上没有区别,每个素材都会看起来像同一张照片,因此应设计出能够真正呈现不同裁切效果的素材包。
要预料模型会推翻规格说明,并将此视为信息。在一次包含三款产品的运行中,有两款产品的输出都被模型悄然替换成了自己的设计:规格说明中要求不点亮的导光槽在每一帧中都亮了起来;规格说明中要求带两段式弯臂的灯具,在全部七个角度中都被渲染成带轭架安装灯头的单杆结构。
两次拒绝都前后一致:模型采用了一种替代设计,并在每个角度中始终如一。这就是信号。模型随机反对,只会带来噪声;模型连续七次以相同方式反对,则是在告诉你,不变特征描述写的是它无法构建的东西。**重写规格说明,使其符合模型能够稳定构建的内容,然后重新生成。**对这种一致的拒绝硬碰硬,只会浪费任务并导致失败。
当错误会被视频阶段放大时,应重新生成静帧:例如道具上出现杂乱文字、字标位置错误,或物体从底座上悬出。
要检查整个素材包中的身份一致性,而不是逐张检查静帧。每张素材单独看都可能很干净,但整个素材包仍可能不一致,因为“这是不是一张拍得不错的灯具照片?”与“这些是不是同一盏灯具?”是不同的问题。以上面的灯具为例,素材包中的不同角度混杂了两种不相容的设计;每张静帧单独看都不错,而基于它们生成的每个素材都会继承其关键帧所携带的设计。选一张静帧作为标准图,然后依据明确且可证伪的特征,而非整体印象,将其余每张静帧与标准图进行比较:
base: shallow domed profile curving in one arc, vs a flat cylindrical puck
with a vertical side wall
post: smooth and unbroken from base to head, vs a collar, ring, knurling
or joint partway up
head: plain green cylinder roughly twice as long as wide, vs short/fat
or a knurled metal barrel
ring: exactly one knurled ring, at the FRONT of the head encircling the
lens, vs any knurling on the post or base
每项特征都指出正确形态以及容易与之混淆的错误形态,因此判断结果可以核验。对最终素材也进行同样的比较,每项特征至少检查两次,并像第 6 节中的语义检查关卡那样,只有结论一致时才通过。在一次包含 14 个素材的运行中,结果为 13 个一致、1 个偏离模型;问题是一个细金色边框改变了灯头的比例。该素材通过了所有信号检查。作为上文所述安全/冒险配对生成的硬动作对应素材干净无误,且已保存在磁盘上,因此修复不花分毫。
这项检查值得在生成前后各做一次,因为两次检查回答的是不同问题:第一次可阻止有问题的素材包污染后续结果;第二次则能抓出仍然发生漂移的素材。 绝不要让失败步骤留下的陈旧输出成为下一步的输入。 链接中的某一步失败时,运行器拾取了前一天同名的文件,并将其传给后续步骤;后续步骤接着成功了,生成了一段看似合理、实际却基于错误素材的片段。失败后旧文件仍留在原处,对下一步来说就和成功没有区别。请检查链式输入是否比正在使用它的运行任务更新,或者将链接写入带运行任务标识的名称,这样文件缺失时就会明确显示缺失,而不是误用陈旧文件。
2. 同时生成画面和 VO
成品广告都带有配音。请在第一轮生成时就安排好配音,切勿等画面锁定后再补:VO 决定广告片的时长,因此最后才生成 VO 意味着必须重新剪辑所有内容。
生成配音、音乐底轨、音频分层、口播流畅度检查和确定性音频处理时,请使用 flux-3-audio-dialogue。这项技能涵盖广告专用的计时与组装:VO 如何决定广告片时长、如何在设计好的停顿处衔接段落,以及母带处理后的分轨如何进入剪辑流程。
通过纯音频任务获取 VO:生成一段录音棚场景,舍弃画面并提取音频。至少针对两种说话人档案生成两份脚本,因为不同录制版本不能互换,你需要真正有所选择。
成品广告片中不要使用原生画面音频。生成画面时应保持静音。
duration 是节奏控制参数,不是时长估算值。 片段返回时长会恰好等于你指定的时长,而口播会拉伸以填满这段时长。相同的 27 词脚本、相同的说话人,分别指定三种时长:
| 指定时长 | 返回时长 | 词/秒 |
|---|---|---|
| 11s | 11.01s | 2.45 |
| 14s | 14.00s | 2.11 |
| 18s | 18.02s | 1.50 |
每次都能完整、准确地读出脚本。变化的只有语速;到了 18s,系统不会用静音填充,而是拖慢口播。因此,先选定所需语速,再推算时长:duration = words / rate,以每秒约 2.1 至 2.5 词的速度朗读,听起来从容而自信。估算时不要为了“留出呼吸空间”而增加时长;这样做会拖慢口播,而不是增加停顿。
单个音频任务最多 20 秒,以合适的语速计算约为 45 词。 30 秒的广告片需要约 75 词,60 秒的广告片需要约 150 词,因此更长的口播应当每个段落单独生成一个任务,再在后期制作中于设计好的停顿处拼接。这也能让文案写得更好,因为广告本就需要停顿。拼接前,请将每个段落裁剪到只保留对应的口播;叠加录音棚底噪会产生明显的接缝。
当广告片时长超过约 20 秒时,也应以同样的方式生成音乐底轨。10 秒时段落间的静音听起来没问题,到了 60 秒就会显得断裂。音乐底轨应通过不含语音提示词的纯音频任务生成,再通过交叉淡化循环至所需时长,并使用由 VO 触发侧链压缩器的方式压低配音下方的音量。先降低底轨音量,再让压低效果作用于已经足够轻的底轨:如果底轨响到需要大幅压低,每个短语播放时都会出现明显的抽吸感。
3. 先用机器筛选画外音,再听一遍
转录每条录音,并根据脚本计算词错误率。这样可以低成本地发现漏读和错读。
虚构的品牌名需要做语音匹配,而非精确匹配。 ASR 从未见过你的产品名称,所以可能会拼出看似合理、实际错误的形式:“Ferrolane” 被转录成了 “Feraline”、“Feralaine” 和 “Fairlane”。精确词元检查会拒绝所有正确的录音。应在滑动窗口中按语音相似度给品牌名打分,并将相近匹配视为名称已被读出的证据。
机器筛选不能批准录音。发音、节奏和合成伪影都需要人耳判断。在有人听过之前,所有虚构名称都应标记为未验证。
从简报中推导品牌词元,而非从表格中读取。 将产品名称硬编码在筛选步骤中,只适用于编写该步骤时针对的那些产品,无法复用。应推导词元:产品名称的第一个词是品牌名,字母加数字的词元是型号代码。
型号代码需要双向折叠数字词。“P2” 约有一半的情况会被转录为 “P two”,未折叠的比较会把本不应计入的词错误算在正确录音上。
注意真正的数字静音处是否有尾部异常。 六条录音中有一条的最后 0.35 秒处于 -91 dB:这不是室内底噪,而是空缓冲区;其余五条的电平都在 -30 到 -40 dB 之间。尾音截断检测会查找结束时仍然响亮的语音,这恰好与此处的问题相反,因此会轻松放过这种情况。如果录音棚录音的尾部没有室内底噪,那么段落拼接处的噪声底就会与相邻录音不一致。
4. 根据音频推导时间
画外音是主时钟。其他所有内容都根据它来测量。
根据能量而非词语时间戳确定语音结束位置。 转录工具给出的最后一个词时间戳,表示该词何时变得难以辨认,而非其能量何时降至噪声底。在一条真实音轨中,转录工具报告最后一个词在 9.76 秒结束,但可听到的衰减持续到约 9.9 秒。在此处裁切会截掉主音轨末尾的词,而所有时长和响度检测仍然都会通过。
应在真正的噪声底处检测静音,并且只计算持续到文件末尾的静音。取最后一个静音区间是另一个更隐蔽的错误:在同一条音轨中,最后一个间隙位于最后一个词之前,因此按它裁切会比按时间戳裁得更短。
逐条录音测量噪声底;固定阈值什么也检测不到。 这些录音棚录音的噪声底并不相同。一条录音测得 -33.2 dB,因此 silencedetect 使用 -45 dB 阈值时,在一条包含四个可听停顿的录音中检测不到任何静音区间,导致所有基于停顿的剪辑位置都无从确定。使用 astats 读取噪声底,并将阈值设为高出几 dB:该录音在噪声底 +6 dB 时能识别出四个清晰的句间停顿;在噪声底 +4 dB 时会将它们拆成六个,而在噪声底 +8 dB 时则开始吞掉轻声辅音。应推导这个数值,并记录所交付剪辑所依据的噪声底。
在测得的间隙处安排剪辑。 优先选择停顿中心:先选噪声底较深处的句间停顿,再选噪声底较浅处的词间间隙。绝不要在词中间剪辑。如果找不到合适位置,就明确报错并说明原因:解决办法是延长静帧、换一个镜头或缩短朗读,而不是在词中间剪切。
剪辑位置的评分应为间隙质量减去节奏不均衡度。只看间隙质量,会选出整段朗读中最不容易察觉的单一剪辑点,结果轻易造成开场镜头仅 1.6 秒,而中间部分长达 4.9 秒。
使用动态规划搜索,而非扫描所有组合。 导致组合数暴增的两个输入都会随广告片时长增长:朗读越长,可选的停顿越多,所需的剪辑次数也越多。
| 广告片时长 | 候选位置 | 剪辑数 | 组合数 |
|---|---|---|---|
| 12 秒,3 个镜头 | 29 | 2 | 406 |
| 30 秒,6 个镜头 | 69 | 5 | 11,238,513 |
| 60 秒,9 个镜头 | 90 | 8 | 77,515,521,435 |
| 暴力扫描在 10 秒时还可以接受,30 秒时很慢,到了 60 秒就不会返回,而是卡住失败:这是最糟糕的失败模式,因为看起来只是很慢。评分中的每一项都是对片段或选定切点求和后再除以一个常数,因此评分可按片段分解,最优解可从左到右构建,复杂度为 O(shots x candidates squared)。 |
如果更快的搜索选出了不同的切点,那是退步,不是优化。对于规模小到足以扫描的案例,断言快速搜索返回的结果与暴力搜索相同;比较并列结果时按评分,而不是按列表身份。
每个片段都必须适配它所属的素材。检查这一点。曾有一次手动测量的切点要求从一段 5.04s 的素材中取出 5.72s 的片段。
调整每段素材的位置,让其中的动作落在点名它的词上。 这是最具杠杆效应的剪辑决策,而从素材中间取片段会白白浪费这一机会。
测量动作发生的位置:signalstats 的 YDIF 可提供逐帧亮度差,将其平滑五帧后,就能作为判断动作何时发生的实用指标。跳过首尾各四帧,否则解码边界和淡入淡出会被误判为峰值。然后逐个镜头声明动作对应哪个口播词,并选择入点,让两者重合。
在这套方法出现之前,我们曾测量过一对真实广告素材:外壳在口播说出“平展打开”后 1.70s 才完全打开,衣领在“干脆的一声”后 2.33s 才咔嗒一声扣上,手柄则比对应词语提前 1.00s 抬起。观众说不出具体原因,但这就是广告与配上旁白的素材之间的差别。
也要把锚点纳入切点搜索。一个切点即使能很好地遮掩转场,但如果不给镜头留出调整位置的空间,也不如一个稍微显眼些、却能让画面和旁白同时表达同一件事的切点。
对结果设置门槛。如果动作与对应词语相差超过约 0.6s,就判定失败。如果素材本身无法让动作赶上对应词语,就说明可达时间窗口:解决办法是重新生成素材,让动作更早发生,或改为锚定到素材实际能够匹配的词语;这两种做法都坦诚可靠。默默接受偏差则不行。
先测量素材,再选锚点词,不要在写脚本时就选。 选一个富有感染力的名词,然后寄希望于素材能匹配,结果在两条广告的九个镜头中有三个没能做到。生成的素材中,动作发生得比编剧预想的早得多:有一段素材在 0.21s 时达到峰值,而锚点词在 0.84s 才出现,因此可达时间窗口在说出这个词之前就已经关闭。可达时间窗口可以在确定词语之前算出,所以先算出来。
从实际效果来看,重新锚定往往也是更好的剪辑选择。将刻有文字的特写从锚定“看见”改为锚定品牌名,既能匹配素材,也更符合镜头所展示的内容。
为了移动动作而重新生成素材,就是制作一段新素材,因此必须再次通过语义门槛。 遇到时间限制时,显而易见的解决办法是重新提示生成镜头,让动作提前发生。这确实解决了时序问题,却破坏了画面内容:我们要求生成一个在最初半秒向下转动、随后保持不动的杠杆,重新生成的片段里,杠杆却从水平位置开始上抬,再落回原位,因此测得的 0.92s 峰值对应的是抬起,而不是关闭。所有数值都改善了,片段呈现的内容却错了。最终采用的素材是原始素材,只是将锚点从“开关”改为“水”;这样,关闭动作与对应词语只差 0.05s,而且也更贴切,因为正是杠杆关闭这一动作留住了水。先试试重新锚定,再考虑重新生成:这不会消耗任何生成任务,而且一段已经通过门槛的素材,比一段尚未检查的新素材更有价值。 按单调顺序解析锚点。 对每个锚点,选取它在前一个锚点之后最早出现的位置,因为镜头沿着文稿推进,锚点对应的词也必须如此。只有在没有词语重复时,查找首次匹配才正确;这只是短文稿中的偶然情况:一段 30 秒的口播中,“light” 出现了两次,相隔十秒,而结尾镜头锚定到了第一次出现的位置,结果偏差达 10.18 秒,无论怎样调整都无法弥补。
并非每个镜头都有锚点,凭空编造锚点比省略更糟。 如果镜头只是轻微移动,而非发生明确事件,就没有哪个词是它所对应的。较长的广告片中,这类镜头更多。将锚点留空,并从素材片段中段截取。
按文稿顺序排列镜头,并将镜头顺序作为调整时长的手段。 镜头只能锚定到自身片段中的词,因此,动作名称对应文稿中较晚位置词语的素材片段,不能放在剪辑的前面。一个拨杆特写在第二段中与“switch”相隔 1.8 秒,但放到第三段就能对上;把它与宽景收尾镜头交换后,无需重新生成就解决了锚点问题。重新排序无需成本,因此先尝试这种方法,再重新提示:约束在于词语落在哪个片段,而不是素材片段本身。
只有在没有适用锚点时,才从素材片段中段截取。 生成片段在开头几帧(画面尚未稳定时)和结尾处效果最弱。
5. 确定性地完成组装
生成后不会再调用模型。输入相同,成片就相同。
通过清单驱动组装,清单只包含内容:使用哪些素材片段、用哪段 VO、文案是什么。剪辑点、广告片时长、响度目标和尾卡处理都在构建时根据媒体内容推导。配置文件中为每个产品单独设置的数值,意味着下一个产品还得有人手动重新测量。
根据测得的亮度决定尾卡。 对文字将占据的区域进行采样,仅在背景亮到白色文案难以辨认时添加暗幕。一款浅沙色外壳上方的白色文字几乎难以辨认,而同样的文字放在深色布景上则无需处理。通过测量即可区分这两种情况,无需添加标记。
如果需要暗幕,让渐变延伸至画面边缘。悬浮色带有两条可见边缘需要隐藏;贴边渐变则只有一条。
设定素材实际能够达到的响度目标。 这些音轨受峰值限制,而非电平限制:其中一条测得的综合响度为 -21.3 LUFS,真峰值已达到 -4.2 dBTP。若要达到 -14 LUFS,需要提高约 +7 dB,这会使真峰值远超上限,因此归一化器会进行限幅,无论目标设定为何,最终响度都会低于目标。压缩只提高了 0.4 LU,却损害了已批准的口播。
使用归一化器首轮报告中在峰值上限下可达到的响度,并以此进行门控。不要根据单个瞬态的采样峰值推算上限,这会过于保守。也不要为了让门控变绿而降低目标;这不算通过,只是掩盖了失败。
6. 根据测量结果设置门槛
时长、分辨率、帧率、是否有音频、响度和真峰值都是基本要求,但也远远不够。还要添加能捕捉那些表面上通过检查的故障的门槛:
- 结尾被截断。 测量收尾淡出前最后四分之一秒内的能量。如果那里的语音仍然很响,说明成片在一个词说到一半时就结束了。
- 正片中出现黑帧。 丢失的画面或错误的转场偏移会导致画面变黑,而其他所有门槛都可能放过它。排除预期的收尾淡出。
- 接地感。 裁剪并放大产品底座的中景。缺失的接触阴影无法通过主体身份和运动检查发现。
- 中间帧。 在多个时间点采样,而不只是第一帧和最后一帧。几何形状会在中段逐渐变形,而这恰恰是只比较首尾帧看不到的地方。
用已知有问题的文件验证门槛。 从未失败过的门槛只是猜测。把成片从一个词说到一半处硬切开,确认门槛会判定失败:在真实素材中,完整文件在该时间窗口内测得 -91 dB,损坏文件则为 -34 dB,因此 -30 dB 的阈值会让损坏文件通过。先通过检查选定阈值,再用对照文件确认。
没有结尾的成片无法检测结尾是否被截断。 如果语音刚好延续到文件结束,完整成片在最后四分之一秒内测得 -15.3 dB,而刻意硬切的副本测得 -13.8 dB。两者只差 1.4 dB,无法用任何阈值区分,因此这个门槛形同虚设。解决方法不是设计更巧妙的阈值,而是给片段添加真正的结尾:延长尾音并做淡出。之后,同一项测量显示完整成片为 -inf,而对照文件为 -13.8 dB。广告成片本来就需要这样的淡出,这正是问题被掩盖的原因:缺少结尾是创意缺陷,还顺带让一个门槛失效了。
信号门槛无法理解含义。添加语义门槛。
上述每个门槛测量的都是信号属性,因此它们都会放过描绘了错误事物的画面。一次运行中有两个测量案例:
- 一支笔“正在画线”,但墨迹跑到了笔尖前面,笔尖与线尾之间露出一段空白纸张。纸在滑动,笔几乎没动。
- 一部手机“落在充电板上”,但充电板只是一块毫无特征的灰色板子,宽度与整个充电板的直径相同。手机落下的动作很干净,正因如此,动作同步门槛才会判定通过。
这两个案例都通过了时长、分辨率、帧率、响度、真峰值、黑帧和同步门槛,进入了成片阶段,却被第一个观看它们的人一眼否决。门槛本身没有错;它们回答的是这个文件是否损坏? 但没有人问这是不是我们所说的那个东西?
解决方法是另设一道门槛:对带标签的帧进行采样,将它们拼成一张联系表,并让视觉模型根据简报中的可证伪断言进行判断。要让这道门槛值得信任,应遵循以下规则:
- 编写这样的断言:错误的画面一出现,断言就会判假。“片段看起来不错”毫无用处。“所有可见墨迹都在笔尖后方或正下方,而且笔尖与画出的线条末端之间始终没有间隙”才是门槛。
- **要求引用帧。**评审者必须指出哪些帧决定了每项判定,否则就无法核查判定。
- **每张画面至少检查两轮,并严格综合结果。**只有一致通过才算通过。任何失败都会阻止放行,轮次之间意见不一则标记为不稳定。评审者连自己的答案都无法复现,就什么也没检查;这并非假设:在一张已知有问题的画面上,五项断言中有两项在同一份画面的两轮评审中给出了相反判定。多数投票或只评审一轮,结果都只能靠碰运气。
- **每张产品画面都默认检查通用的四项:**接触阴影存在、各帧的几何形状和材质保持不变、文字没有乱码或重复、没有空白或损坏的帧。然后由需求撰写者写出针对每个镜头的断言,明确画面有问题时哪些说法会变成谎言。
- **通过只是证据,不是证明。**它不能取代人工检查。它能阻止明显错误的画面送到人工面前,从而腾出更多审核能力。
**断言集才是攻击面,不是评审者。**这次运行中代价最高的错误,并非判定有误,而是对不完整的问题给出了正确判定。重试画面中的手机看起来很逼真,其宽度确实小于垫子的直径,因此宽度断言诚实地判定为通过,画面也亮起绿灯;但手机最终斜着搁在边缘上,两侧都伸出了垫子。断言集里没有任何一项询问手机是否平放,或是否落在垫子的轮廓范围内。每项判定单独来看都有道理,但这道关卡还是放行了错误的画面。
断言集不够全面却给出错误的通过判定,比完全没有语义关卡更危险,因为它还附带帧引用。两条习惯可以解决这个问题:
- **断言最终静止状态,而不只是运动过程。**物体最终停在哪里(是否平放、是否在轮廓范围内、是否接触)才是观众会觉得不对劲的地方,也是只关注运动的断言集容易漏掉的地方。
- **如果肉眼发现画面有问题,先找出本应捕捉该问题的断言,再编写新的提示词。**如果没有任何一项能捕捉到,漏洞就在断言集里。本次运行的四次拦截中,有两次准确指出了缺陷;另一次因其他问题的判定不稳定而拦截,但真正的缺陷却无人提及。理由错误的正确答案不算覆盖;一旦不再碰巧出现这种情况,它就会悄无声息地失效。
断言可能从构造上就是错误的,却看起来很严谨。“手机在移动过程中始终保持大小和形状不变”拦截了一张正确的画面。刚体从接近竖直旋转至平放时,必然会发生透视缩短,因此没有任何真实片段能满足这句话,而评审者给出的理由也准确反映了帧中内容。应断言物理上的合理性(边缘是直的、角是方的、没有独立下垂),并明确说明透视变化是预期现象。在同一轮运行中,用已知有问题的素材测试每一项改写后的断言:如果改写后有问题的画面不再被判失败,那就是削弱了断言,而不是修正了它。
看到不喜欢的判定后再改写断言,是关卡失效的开始。有时这样做是正确的,如上所述。要保持诚实,关键在于采用机械化流程:将已知正确和已知错误的画面保留为固定测试样本,每次编辑断言后都重新运行两类样本。错误画面必须仍然因同一个明确理由而失败。这也解释了为什么这个循环在运作良好时值得信赖:重试画面通过了自失败以来未作任何改动的断言,才是真正的证据;只有在改动了断言后才通过,就不是证据。
在相信关卡的判定之前,先亲眼检查一次关卡自身的证据。
这个工具的第一个版本通过将六个单独的输入传给 ffmpeg 的 tile 滤镜来制作联系表。tile 会处理单个流中的连续帧,因此它只平铺了第一帧,其余部分留黑,随后以 0 退出,并写出一张看似合理的 JPEG。评审者看到一帧,却被要求判断六帧中的动态效果,还是给出了答案。退出代码对此毫无提示。悄无声息地失败的 QC 工具比没有 QC 工具更糟,因为它会凭空制造信心。
**绝不要为了让运行结果变绿而放宽关卡。**修复素材,或者说明失败。还要留意一种更隐蔽的情况:检查触发时,人们很容易把它抱怨的数值调低,直到它不再触发。一次碰撞警告导致有人把标注停留时间缩短到 0.5s,虽然消除了重叠,却让文字短到无法阅读。关卡变绿了,广告却变差了。如果某项修复是通过让作品变差来使检查通过,那就不算修复,而且关卡衡量的也不是正确的东西。
没人采取行动的警告,是关卡中的一个 bug。“标注持续时间超过镜头时长”原本只是警告,但某次渲染仍然交付了:标签跨越剪辑点继续显示,指向屏幕上已不再出现的功能。如果某种情况意味着输出有误,那它就应该是错误。
**QC 文件必须与控制台输出一致,否则人们会相信文件。**构建器针对一个有两项同步失败的版本打印了 FAILURES PRESENT 并以非零状态退出,却在该版本对应的 master-qc.json 中写入了 "pass": true。同步检查改变了本地判定,但持久化记录是根据信号关卡的通过标记生成的,而该标记并不知晓同步状态。任何只读取产物、不查看标准输出的人都会看到一个通过的版本。应写入综合判定,并将失败项一并写入,这样无需重新运行构建也能审计记录。
**针对单个条目的运行不得抹去未构建条目的记录。**每次调用都会从空字典重建同一个文件,因此 --only kestrel 会悄悄删除 stonewell 的条目。随后,文件看起来描述的是整个项目,实际上只记录了一个版本——这更危险:不完整的记录看起来却是完整的。应合并已有内容,为每个条目标记其构建时间,并明确说明哪些条目来自较早的运行。
这两种情况与上面的联系表 bug 本质相同,只是由不同途径导致:检查正确运行了,报告却撒了谎。当关卡与其产物可能不一致时,应通过故意制造一项失败并读取文件(而不是终端)来测试它们是否一致。
文案
屏幕文案比画面更容易凭空编造主张,因为写出一份看似合理的规格说明毫无成本。
每一行文案都必须有依据,并注明依据类型。“可见”表示标签所指的画面中能看到它。“规格”表示它属于参考设计。“口述”表示经批准的 VO 中有这句话。没有依据的文案不得交付。
两条标签在实际项目中违反了这一要求:“TWO-STAGE LOCK”和“COLD-FORGED”。它们指的是从未设计、生成或说过的机制和工艺。这些标签读起来像是言之凿凿的规格说明,实际上却是凭空捏造的;对于一部展示工作流的作品来说,这比文案含糊更糟。
把证据写进名词或数字里。“38 litres”胜过“容量充足”。说清材料和部件:不锈钢主体、胡桃木套筒、炭灰色拉链带。结果类形容词(顺滑、精准、轻松、可靠)所宣称的内容无法从画面中看出,因此必须有 VO 作为依据,否则就应删掉。
**用人们日常会说的方式称呼部件。**没人会用“伸缩杆”来称呼把手。
剪辑
三个一模一样的叠化不叫剪辑,只是默认设置。它对每一组镜头都表达同样的意思,尽管镜头之间的关系各不相同。
精简处理方式,并让每种处理各司其职:两个同一物体的不同视角之间使用硬切,此时连续性一目了然,重点在于传递确定感;场景尺度或主体发生变化时使用短暂的叠化;进入关键画面时使用两帧的闪白,让剪辑有抵达目的地的感觉。闪白的颜色取自素材画面自身的高光。在暖色布景上使用白色,看起来会像画面过曝。
让镜头的运动有始有终。 如果整个镜头都以恒定速度推进,看起来就像软件生成的。让运动缓入,在较早时到位,然后停留:正是这段停留让镜头运动显得经过设计。
添加生成画面缺少的瑕疵。 生成的素材画面在光学上毫无生气。在变换上添加亚像素级的固定种子噪声(两个八度,在 960px 分辨率下约为一个像素),能让画面看起来像由摄影设备拍摄,而非焊接而成;少量颗粒则能抖动平滑渐变,避免它们在 H.264 编码后出现色带。两者都应难以察觉,只有缺少时才会被注意到。为它们设置固定种子,确保重新构建后字节完全一致。
渲染器选择
ffmpeg 足以处理切镜、叠化、字幕、遮罩、淡入淡出、响度和封装,而且它已经安装在所有环境中。
当片尾卡片发展成真正的设计时,Remotion 值得考虑:它支持布局、Web 字体、数据驱动的变体和多种尺寸。它基于 React,因此渐变只需一条 CSS 声明,无须生成 alpha 渐变后再按计算出的偏移叠加;其 Studio 还提供可拖动时间轴的预览。
选择它之前,有两点需要了解。许可方面:Remotion 对个人和三人及以下的公司免费,四人及以上的公司则需要购买 Company License。音频方面:浏览器会直接播放音轨,不会进行响度标准化,因此未经母带处理的音频会以原始电平渲染。先用 ffmpeg 处理好音频,再交给 Remotion 一条完成的音轨。
两种渲染器都可以使用相同的派生时序。将测量结果集中保存在一处,让渲染器成为可选项,而不是重写工程。要让两者完全一致,需要格外留意:字幕滤镜按字形框定位,而 CSS 会计入字体的上升部行距,因此文字位置会有差异;交叉叠化必须从切点开始,而不是在切点结束。
参考
references/pipeline.md 是一份参考设计和实现蓝图,包含清单架构、派生时序导出、两种渲染器,以及列出测量阈值和负向对照的 QC 门槛清单。文中描述的模块并未随此仓库发布;Agent 会根据其中的约定构建这些模块。