数字人待机/口播素材怎么做:无声循环、锚点闭环与“举手姿势”这个坑

2026-09-29 · AI智工坊 · 数字人素材产线实录

很多人第一次给数字人做素材,思路是“录一段带声音的视频,播的时候对着放”。这条路走不通,而且是在上线之后才会发现走不通——因为它错在最开始的定义上。

我们把数字人素材这条链路从零做到稳定交付,中间踩的坑基本可以分成两类:一类是概念性的,比如素材到底是什么形态;一类是审美性的,比如轮廓那圈亮边到底要不要修。第二类比第一类更费钱,因为技术上门门都对,成品还是被判“看着不对”。这篇只写我们真实踩过的,每个结论后面都有当时的实测数字。

一、先把定义钉死:素材是“无声 + 可循环”的两段视频

数字人前端的标准形态是三层同屏叠加:

层元素职责
画面·下待机 <video>常显,循环播放,负责“人在那儿”
画面·上口播 <video>循环播放,靠透明度 0/1 显隐,负责“人在说话”。音轨在代码里被强制静音
声音独立的音频元素唯一声源。后端把语音分段推给音频队列,顺序播放

看清楚这张表,几个结论就自动出来了:

我们在这条上学到的元教训是:不要向人追问“这个素材怎么用”,去读正在跑的前端代码。集群里跑着的代码就是权威答案,问人得到的往往是回忆,代码给出的是事实。

二、素材四要:四条能直接判定合格与否的硬线

要求判据
无声用 ffprobe 检测,必须没有音频流
无缝循环尾帧到首帧的像素差,约等于一帧的正常运动量
锚点闭环口播首帧 = 待机首帧 = 同一个临界点(详见第三节,只考核一半)
姿态可维持源图里的姿态必须是一个人能长时间自然保持的(详见第四节)

规格不用自己发明,直接抄成品:我们线上实际引用的两支素材是——待机 204 帧 / 8.16 秒,口播 262 帧 / 10.48 秒,都是 1080×1920 @25fps,都没有音轨。口播那 262 帧是 131 帧往返折返出来的,所以单程 131 帧 = 5.24 秒。

这个 5.24 秒容易被误解。它不是“每句话要说 5.24 秒”,而是它定义了嘴动的节奏——循环素材的语速感由单程长度决定,跟某一句话实际多长没关系。

三、锚点闭环:为什么只考核一半就够

前端代码的注释写的是“首尾帧已统一(锚点闭环),无需等待机循环到首尾帧,立即切换”。但用线上标尺实测反推,真实约束比注释更精确:

也就是说,锚点闭环这件事只需要保证一半。知道这一点,能省掉大量“为什么首帧对不上”的无效返工。

顺带说切换的实现细节,它是“为什么不闪”的关键:切的时候先建新元素并 load(),等到 loadeddata(或 readyState ≥ 2)才开始 0.16 秒交叉淡化,200 毫秒后把另一个元素载入同源并同步 currentTime 续播,另有 2 秒兜底强制交换。切回待机时还带 3 秒(放歌场景 5 秒)的语音活动检测冷却,防止它自己的声音触发新一轮。

四、源图姿态铁律:举手是一颗定时炸弹

“一个人正常情况下,不可能一直把手举起来。口播视频也不可能一直举着手说话。”

这句话把问题说透了。一次性动作不能进循环素材——举手的拇指手势、比划、叉腰、指方向,全都是“拍照那一瞬”的姿态。待机要循环 8 秒、口播要循环 10 秒,而用户会一直看着它,任何摆拍动作在三秒内就会露馅。

允许的姿态只有一种:静态站姿 + 双手自然垂放体侧(可以含轻微的自然眨眼和眼神)。

更麻烦的是,举手多半是源图自带的,渲染只会沿用,剪帧也剪不掉,所以没有省事的路,必须在源图上改、然后重新渲染。我们一次到位的做法是:

  1. 用图生图,输入已定版的立体源图,提示词只描述要改的部位,其余逐项声明“保持完全一致”。
  2. input_fidelity = 0.6——实测既真的改了姿态,又保住了人脸、服装和整体风格。
  3. 再走一遍本地精修(压纯黑背景、人物提亮、去水印)。
两个必查项:
① 改完查水平居中。原图往往靠单侧举手形成视觉平衡,手臂放下来之后人物会整体偏移——我们实测偏了 +48 像素。纯黑底素材上直接用 cv2.warpAffine 平移校正即可,无损、无痕迹、不必重新生成。
② 提示词的正负向要跟着翻。举手版的负向里通常写着“放下手臂、垂手”这类词,改成垂手版后必须删掉,并把“抬手臂、举手、竖起大拇指、挥手、做手势”全部加进负向。写反了,模型会按旧方向把手又抬起来。

五、轮廓那圈浅色亮边:默认不处理,因为它是特征不是缺陷

重绘姿态之后,人物轮廓外缘(耳后、下颌线、肩线,还有袖口)会出现一道宽 5~9 像素的浅灰白细边。在纯黑底上放大看非常像瑕疵。

我们前后试了四轮处理方案,全部被否。这不是技术问题,是审美判断:

方案做法副作用
沿法线取色替换沿边缘向内 10px 取色覆盖出现硬化白块
开运算削峰亮度 120 → 65纯白细线仍在
挖掉后修补去掉亮像素再修补边缘发糊,人工感明显
只降亮度不碰形状,亮度削 27%(α=0.88)形状零变化、边缘像素相似度 0.9999,技术无瑕——仍被判“看起来不正常”

最后一行的结论值得记住:反光恰恰是人物立体感的来源,把它压掉,整个人就假了。所以最终定版是——

源图原样使用,不做任何处理。

更普适的元教训:症状看着像缺陷时,先确认它是不是特征。这类问题必须问出图的人,不要按“像素异常 → 该修”的直觉自己动手。每一次重渲的代价是 85~140 分钟。

六、生产链路:从源图到成品素材

1. 源图裁切

裁或补成 9:16(1080×1920)。补边要用纵向均匀色带——取边缘若干行列的均值,做横向高斯平滑,再加约 45 像素的过渡融合。不要用“拉伸行复制”,那会留下明显条纹。

2. 驱动音频(纯耗材,不交付)

用 edge-tts 合成,拼成“静音 + 语音 + 尾静音”,严格铺满输出时长。一个实操坑:edge-tts 命令行不支持调节语速,必须走 Python 接口:edge_tts.Communicate(text, voice, rate="-12%", pitch="-2Hz")。沉稳男声可以用 zh-CN-YunjianNeural。

3. 渲染

走 ComfyUI + Wan2.1 图生视频 + MultiTalk 的口型驱动。几条实测经验:

4. 提示词口径

七、一个容易被忽略的翻车点:同名素材 ≠ 同一个数字人

如果你的集群里跑了不止一个数字人,请注意:不同实例的素材文件名可能一字不差,而它们对应的形象、音色、部署位置完全不同。我们曾因此整轮改错对象。

可靠的判别方式是认音色,不认文件名:去目标机读它的语音配置,看用的是哪个音色标识,而不是看素材叫什么。动手前的 30 秒核查,能省掉一整轮白工。

另一条配套纪律:改之前先读该实例的经验库文档。数字人素材的调参历史非常长——同一支素材可能已经迭代了十几个版本,每个版本的结论都建在上一个的教训上。跳过历史,等于把别人踩过的坑重新踩一遍。

八、一页纸的素材验收清单

这套东西做完,素材就从“看起来能动”变成“能长期挂着不出事”。数字人这个行业真正的门槛其实不在模型,而在这些每一条都能被一句话验证、但事前完全想不到的细节上。

看看我们的方言词库产品 →

常见问题

数字人的待机视频和口播视频,是不是各做一段带声音的就行?

不是。正确形态是两段无声、可无缝循环的视频素材,声音由主程序另外配。口播素材是循环素材,语音讲多久就循环多久,所以不需要和某句话等长,也不需要带音轨。判断标准很硬:检测不到音频流才算合格。

素材为什么要做成循环(往返折返)而不是单程播放?

因为切换时要对得上帧。前端切回待机是等口播播到时长一半才切,切回后待机从 0 帧起播;两段素材首尾帧不重合,切回去就会跳帧。往返折返让尾帧与首帧的运动量差约等于一帧,切换才看不出来。

素材里人物一直举着手,为什么看起来不对?

因为那是一次性动作。待机循环 8 秒、口播循环 10 秒,用户会一直看着它,任何拍照瞬间的摆拍动作都会立刻违和。允许的姿态只有静态站姿加双手自然垂放体侧。而且举手通常是源图自带的,渲染只会沿用、剪帧剪不掉,只能在源图上改并重新渲染。

改了源图姿态之后人物看起来偏移了,怎么办?

先量再动。原图常靠单侧举手形成视觉平衡,手臂放下来之后人物会整体偏移,我们实测偏了 +48 像素。纯黑底素材上用平移校正即可,无损无痕,不需要重新生成。同时记得把提示词的正负向一起翻过来,否则模型会按旧方向把手臂又抬起来。

人物轮廓外面有一圈浅色亮边,要不要修掉?

默认不处理。那通常是灯光反光(轮廓光),本身就是立体感的来源。我们试过四种消除方案,其中一种形状零变化、边缘像素相似度 0.9999,技术上无瑕,成品仍被判“看起来不正常”。结论是源图原样使用。这类问题属于审美判断不是技术缺陷,必须问出图的人。