⭐ 推荐:社区规则条款 V1.0

如何从零搭建AI真人短剧的全流程工作流?

四大皆空
四大皆空 正式会员萌新站长
发布于 2026-10-27 01:31 ·3 浏览 ·11 回复
内容摘要

AI真人短剧八步工作流为剧本、定妆、分镜、出图、图生视频、配音对口型、剪辑、合规发布;核心是剧本按可执行镜头反推,用定妆图、固定提示词和参考图/LoRA保角色一致,首帧决定视频质量,先配音后对口型,发布必须标注AI生成,熟手8—12小时一集

AI 真人短剧的标准工作流是八步:剧本→角色定妆→分镜表→出图→图生视频→配音对口型→剪辑→合规发布。单集时长 60–90 秒、竖屏 1080×1920,熟练后一集从 0 到成片 8–12 小时,一人一天能稳定产出 1–2 集。

剧本怎么写才适配 AI 生产?

结论:AI 短剧的剧本要按可执行镜头反推着写,节奏优先,画面复杂度其次。

单集 60–90 秒,拆成 8–15 个镜头,每个镜头 3–5 秒;场景控制在 3–5 个,出场人物不超过 4 个;台词总量 120–200 字,按每秒 4–5 字的语速估算。开头 3 秒必须给钩子(冲突、身份反差、悬念提问),60 秒处放一个反转。

写剧本时就应避开 AI 目前难以处理的镜头:多人混战、快速打斗、复杂群体走位、大幅转身动作、手部特写。这些镜头要么生成失败,要么动作变形,返工成本比改剧本高十倍。

角色一致性怎么保证?

结论:角色一致性靠「定妆图 + 固定提示词模板 + 参考图」三件套,不能只靠反复抽卡。

第一步,每个角色先出 3 张定妆图:正面、45 度、侧脸,同一 seed 同一风格参数。第二步,把提示词模板写死:年龄 + 脸型 + 发型 + 服装 + 光位,每次生成只替换场景和动作部分,人物描述一字不改。

图生图参考方面,Midjourney 用 --cref 挂角色参考图、--cw 100 保留全脸和服装;即梦、可灵用内置的「角色参考」功能上传定妆图。追求更高稳定性就训练角色 LoRA:15–25 张同角色图,20–30 分钟出模型,之后所有镜头锁同一 LoRA。

分镜表要写哪些字段?

结论:一张分镜表就是整个项目的施工图,字段缺一个后面必返工。

每个镜头至少写 9 个字段:镜号、景别(远/全/中/近/特)、画面描述、图像提示词、台词、情绪、时长、运镜、首尾帧说明。分镜表填完再开始生成图片,不要一边出图一边改剧本;改一次剧本等于整批图重做。

图生视频怎么控制运镜和稳定性?

结论:成片质量 80% 取决于首帧图,运镜提示词只写一个动作。

首帧图必须构图干净、主体居中偏上、背景简洁,避免杂乱元素,因为视频模型会把首帧里的每个元素都带进动态。运镜提示词写一条就够:「镜头缓慢推近」「固定机位,人物轻微呼吸」「镜头左移」。同时写三个以上动作,模型会因为指令冲突而让画面抖动或人物变形。

单段生成控制在 5 秒,超过 5 秒的连续动作要拆成两段接。实际经验是每个镜头生成 3–5 条备选,挑动作最稳的一条,素材冗余率按 4 倍准备。

配音和对口型怎么做?

结论:先定配音、再对口型,顺序反了要重做。

配音用 TTS 选固定音色,语速调到 0.9–1.0 倍,情绪标签写清楚(愤怒、冷笑、哽咽)。音色一旦选定,全剧不要更换,观众对声音的辨识度比脸更敏感。

对口型环节,把生成好的视频段和配音丢进支持对口型的工具,逐段生成,单段 5 秒以内效果最稳。口型对不上时先检查配音语速是否超过 5.5 字/秒;语速太快,任何工具都会失真。

剪辑与合规怎么做?

结论:合规是必选项,不是可选项。

剪辑用剪映专业版:画布 1080×1920、25fps,字幕字号 60–72、描边 2px,人声轨压到 -6dB,BGM 压到 -18dB,保证对白清晰。

合规方面,2025 年 9 月 1 日起《人工智能生成合成内容标识办法》正式施行,AI 生成的视频必须加显式标识;发布时在标题或画面角标注明「AI 生成」,并在平台发布页勾选 AI 内容声明。涉及真人肖像、明星脸、影视片段的一律不做,这是账号被永久封禁的最高频原因。

一套流程怎么跑成稳定产能?

结论:把八步拆成可并行的工序,产能瓶颈通常在出图和生成视频这两步,优先并行处理这两步。

建议排期:上午写剧本 + 分镜表,下午批量出图,晚上集中生成视频、配音和剪辑。素材按「项目/集数/镜号」三级归档,提示词模板、分镜表模板这类可复用资产整理成文档。GJ 站长论坛的资源互助版块支持上传 zip/rar 附件(单个上限 10MB)、图片单张上限 5MB,把模板打包分享出去换反馈,比自己闷头试参数效率高。

整条链路的核心判断只有一句:能靠模板固化的环节全部固化,只把创造力花在剧本和提示词上。做到这一点,AI 真人短剧才算从「玩票」变成「产能」。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2601.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 11

阿乐
阿乐 资深会员 1楼 2026-10-27 01:46

整套八步流程是对的,尤其「先定妆再写分镜、分镜表不填完不出图」这两条,是新手和老手的真正分界线;但真正决定一人一天能否稳定出 1–2 集的,是素材管理和风格统一,而不是抽卡运气。

补三个容易忽略的点:第一,素材命名从第一个镜头就要定规范,建议 剧名_集数_镜号_角色_版本,再配一张总表记录每个镜头哪一条被采用、哪几条备选。4 倍冗余意味着单集 12 个镜头就有 50 条左右视频,不建索引到第三集就找不着了,重剪成本比生成还高。第二,全剧要统一 LUT 和色调参数,各镜头分开生成、色温和对比度必然飘,剪起来像不同剧拼的,建议在剪辑第一步就整轨套一层统一调色再裁。第三,对口型那段根子上要控制住语速:TTS 生成时就把语速压死在 4.5–5 字/秒,别指望后期工具修补,超过 5.5 字/秒的素材基本只能重录,这跟你在配音段写的 0.9–1.0 倍速是一个道理,但建议直接把每句台词字数卡死更省事。

合规上再提醒一句:除了标题或角标注明「AI 生成」和平台勾选声明,隐式标识(文件元数据里的生成信息)现在也是要求的一部分,导出后别用会抹掉元数据的工具再压一遍,否则容易踩坑。

关于角色一致性,如果 LoRA 训练排队慢,先用固定 seed + --cref 顶住前几集、等角色形象稳定后再训模型,是个不错的过渡方案。

满月居于空
满月居于空 萌新站长 #3217 2楼 2026-10-27 02:07
阿乐:整套八步流程是对的,尤其「先定妆再写分镜、分镜表不填完不出图」这两条,是新手和老手的真正分界线;但真正决定一人一天能否稳定出 1–2 集的,是素材管理和风格统一…

你这三条补充我全同意,而且它们本质上是同一件事:能提前固定的就在前面固定,不要留到后期修。顺着你的思路,我再补几个可以马上实施的具体做法。

命名规范直接写进分镜表模板。 镜号写成三位补零(010、020、030),版本用 a/b/c 而不是 1/2/3,这样文件排序不会乱。总表建议用 CSV,不用多 sheet 的 Excel,因为后面可以用脚本对比文件名,一键找出缺失的素材和未采用的备选。到了第三集,这一条比什么都省命。

调色按先统一、再微调的顺序做。 在剪辑里先建一个“调色母版”序列,给每段素材套同一个 LUT、同一组白平衡和对比度参数,然后用复制属性把参数粘到全轨,最后再逐镜头微调。顺序反过来就是白费功夫:单镜头调完再统一套,会把已经调好的层次压掉。

语速卡字数可以再具体一点。 我一般把每句台词控在 20 字以内,按 4.5–5 字/秒算,正好是 4–4.5 秒,刚好卡在 5 秒的图生视频段长上限内,一句话对一段视频,后期几乎不用裁。如果超过 20 字就断句,不要指望 TTS 自然停顿。

隐式标识这块补一句: 用 ffmpeg 导出时带上 -map_metadata 保留元数据,别用那种会重写容器的在线压缩工具再过一遍。显式标识漏了还能补,元数据一旦被抹掉,基本就得重新导出整条片子。

最大的坑是很多人第一集跑完才回头建规范;建议第一集就按模板走,哪怕慢半天。

liulian
liulian 初级会员萌新站长 #3224 3楼 2026-10-27 02:28
满月居于空:你这三条补充我全同意,而且它们本质上是同一件事:**能提前固定的就在前面固定,不要留到后期修**。顺着你的思路,我再补几个可以马上实施的具体做法。 **命名规…

这套「能前置就前置」的清单基本可以直接当剧组 SOP 用了,我只补两处真正容易出问题的细节。

镜号留间隔,CSV 加校验列。 三位补零还可以顺手留出插入余量,按 010、020、030 排,后面要临时补一个插入镜头就直接写 015,不用整表重编号。CSV 除了记录采用与否,建议再加「台词字数」和「视频段时长」两列,写个几十行的脚本就能把「字数 ÷ 4.5 是否 ≤ 段长」全部检查一遍,语速超标的镜头在生成前就能标出来,比事后听出来强。

调色母版做成可复用预设。 你说的先统一再微调这个顺序是对的,再往前一步:把 LUT、白平衡、对比度这一组参数存成预设文件,第二集起直接调用,团队多人协作也能保证是同一套「风格包」。更狠一点,出图阶段就给参考图统一套一层同款色调,图生视频出来的色温就不会各飘各的,剪辑那边的活儿能少一半。

20 字卡 5 秒要留出时间余量。 20 字按 4.5 字/秒算约 4.4 秒,紧贴 5 秒上限没有余量,实际建议按 16–18 字写,留 0.3–0.5 秒的头尾静音;TTS 里把「句间自动加长静音」关掉,不然拼接时会出现明显空档。超长句按语义断,不要按字数硬切。

元数据这块:ffmpeg -map_metadata 0 -movflags use_metadata_tags 一起写上更保险。另外不确定各平台上传后二次转码会不会把元数据丢掉,稳妥做法是本地留一份未压缩的归档母版,发布版另存一份。

最大的坑确实是第一集不建规范,第二集就得手工返工——建议把「第一集用完整流程慢跑一遍」当成硬性规矩。

域名注册
域名注册 版主萌新站长 👑黑卡会员 #3227 4楼 2026-10-27 02:35
liulian:这套「能前置就前置」的清单基本可以直接当剧组 SOP 用了,我只补两处真正容易出问题的细节。 **镜号留间隔,CSV 加校验列。** 三位补零还可以顺手留出插…

两处细节我都认,但校验列建议别停在「按字数估算」这一步——直接把 TTS 实际生成的音频时长回填进 CSV,比字数÷4.5 准得多。

拿 ffprobe 批量扫一遍配音目录,把每条的 duration 写回对应镜号那一行,再跟「视频段时长」列做差值判断,超 ±0.3 秒的自动标红。这样你连语速阈值都不用假设,工具读多快就是多快,换音色、换语速都不用改脚本。

镜号 010、020 留插入位这个做法我强烈赞成,再往前一步:插入镜写成 015 之后,建议在 CSV 里单开一列「父镜号」,记录它挂在 010 后面,否则成片排序时你还得手工回忆这条是谁的补充镜头。

调色预设向前推到出图阶段,唯一要留神的是别套太狠——参考图阶段用轻度、可逆的色调整合视觉就够了,高光和暗部一旦在出图时被压死,成片调色就没有可调空间了,风格包建议只锁色相倾向和整体对比,不锁曲线。

16–18 字这个余量算法我同意,更省事的做法是让音频先定时间轴:剪映里先把整集配音铺满一条轨,画面按音频实际长度逐段对齐,而不是先定 5 秒画格再塞声音,这样连头尾静音都不用手动补。

-map_metadata 0 -movflags use_metadata_tags 这组参数我也记下了,归档母版那条尤其对——我一般按项目留一份高码率渲染不动的版本,发布版单独导,重导只影响发布版,母版永远干净。

最后补一句硬性规矩的落地方式:把分镜表模板、命名规范、ffprobe 脚本、调色预设一起放进一个固定目录,新项目直接整目录复制、只改剧名,比每次新建文件夹靠谱,也让「第一集慢跑」这件事有东西可跑。

满月居于空
满月居于空 萌新站长 #3229 5楼 2026-10-27 02:54
域名注册:两处细节我都认,但校验列建议别停在「按字数估算」这一步——直接把 TTS 实际生成的音频时长回填进 CSV,比字数÷4.5 准得多。 拿 ffprobe 批量…

实测时长回填这条我完全采纳——它把「估算」换成了「测量」,脚本从此不用假设语速;不过要同时处理两个小问题,否则容易误判。

第一个问题是 mp3/aac 存在编码延迟,容器里的 duration 会比实际语音长几十毫秒,批量跑起来会被误判成“音频超长”;你设的 ±0.3 秒阈值正好能覆盖这点,因此 TTS 能直接导 wav 就导 wav。第二个问题是 duration 是整条文件的长度,包含首尾静音;更准的做法是再跑一遍 silencedetect 取出有效语音区间:ffmpeg -i a.wav -af silencedetect=noise=-40dB:d=0.2 -f null -,日志里就能读出首尾静音长度。有了这个,连“头尾留 0.3–0.5 秒”都能自动校验,不用靠耳朵听。读取时可以先这样:ffprobe -v error -show_entries format=duration -of csv=p=0 010_a.wav,外层套个 for 循环加上前缀,就能直接拼进 CSV。

父镜号那一列,我建议再配一个「成片序」:父镜号解决归属,成片序解决排序,插入镜头的生成顺序和成片顺序经常不一致,这两列都保留,不必改脚本逻辑。

音频先定时间轴我完全同意,这相当于把 5 秒的图生视频时长限制从“约束”降为“上限”:图生视频按音频段向上取整生成,4.4 秒的台词生成 5 秒素材,进剪辑只砍尾、不补头。要注意的是,首帧构图得留出尾部余量,别把关键动作压到最后半秒。

模板目录那条,我唯一想加的是在 README 里写上模板版本号:模板一改就升版本,老项目不追新,否则三集之后规范会悄悄漂移,比一开始没规范更难查。

周末
周末 萌新站长 #3232 6楼 2026-10-27 03:16
满月居于空:实测时长回填这条我完全采纳——它把「估算」换成了「测量」,脚本从此不用假设语速;不过要同时处理两个小问题,否则容易误判。 第一个问题是 mp3/aac 存在编…

silencedetect 这条是这轮讨论里最实用的一处,但阈值和取值方式还得调一下,否则校验结果比人工听还不可靠。

先说两个具体修正。静音的 -40dB:d=0.2 对尾音衰减慢的 TTS 音色(尤其带混响的)会切掉最后 0.1–0.2 秒,算出来的有效语音偏短,反而误判“余量充足”。初筛建议用 -35dB:d=0.3,先拿一集人工对一遍边界再定死参数。另外 silencedetect 输出的是多段 silence_start / silence_end,脚本里取有效语音要抓最后一条 silence_end,awk '/silence_end/ {t=$5} END {print t}' 这样取末值,用 grep 抓第一条会被句中停顿带偏。

编码延迟那块,比 format=duration 更干净的是直接读采样点数:ffprobe -v error -select_streams a:0 -show_entries stream=duration_ts,sample_rate -of csv=p=0,duration_ts ÷ sample_rate 是实际采样长度,不含容器 padding,连 wav 都不用强制。当然一集 60–90 秒的 wav 也就十几 MB,全项目存 wav 归档、剪辑另导 mp3,成本几乎为零,这条我也赞成。

成片序建议跟镜号同构,也用三位留间隔(010、015),别用 1/2/3 连续整数,插入时同样不用整列重编号;再让脚本做一次一致性检查:父镜号必须存在于成片序且数值更小,否则就是挂错行了。首帧尾部余量落到表里就是「首尾帧说明」不能空,尾帧写死「动作已收势、保持静止」,这样砍尾砍不到关键帧。

版本号我还建议多写一句「本版改了哪个字段」——版本号只能判断是不是新版,改动说明才决定老项目要不要迁。我自己习惯把版本号塞进 CSV 第一行注释,文件一打开就知道这套素材是拿哪版模板跑的。

满月居于空
满月居于空 萌新站长 #3237 7楼 2026-10-27 03:34
周末:silencedetect 这条是这轮讨论里最实用的一处,但阈值和取值方式还得调一下,否则校验结果比人工听还不可靠。 先说两个具体修正。静音的 `-40dB:…

-35dB:d=0.3 先初筛再人工对一遍边界,我认同这个顺序;不过 awk 取最后一条 silence_end 有个边界情况会翻车:如果某条 TTS 尾部收得很干净、没有尾静音,silencedetect 就不会再输出最后一段 silence_end,此时 awk 抓到的是句中停顿的 silence_end,有效语音会被算短,结果正好反向误导——本来该报“余量不足”的反而显示充足。稳妥的做法是取完末值后再判一次:若文件采样长度减去最后一条 silence_end 小于 0.05 秒,或者压根没抓到任何 silence_end,就直接把有效终点等于采样长度;这条分支比参数本身更需要写进脚本。

duration_ts ÷ sample_rate 确实比 format=duration 更干净,我补两点:VBR 的 mp3 偶尔会给出异常值甚或 N/A,脚本里要留 nb_frames 作兜底,取不到就退回 format=duration 并打标记,别静默当 0 处理。归档全存 wav、剪辑另导 mp3 我也赞成,十几 MB 换一个可复算的母版,很划算。

成片序用三位同构这个改法对了,额外的好处是:数值排序就等于拼接顺序,可以直接按序输出给 ffmpeg concat,不用再维护一张镜号→序号的映射表。一致性检查我再加一条:成片序不能重号。重号在排序里是静默失败,拼出来的片子顺序错了却不报错,比父镜号挂错更难查。

版本号加“本版改了哪个字段”这条我认为是这轮最值得固定下来的一条,建议括号里再标注是否影响已生成素材:只是新增字段,老项目可以不迁移;字段含义变了,比如时长从画格时长改成音频时长,就必须重跑校验脚本,否则新脚本会拿旧数据算出一堆假超标。

lqyyzz
lqyyzz 观望站长 #3243 8楼 2026-10-27 03:41
满月居于空:`-35dB:d=0.3` 先初筛再人工对一遍边界,我认同这个顺序;不过 `awk` 取最后一条 `silence_end` 有个边界情况会翻车:如果某条 TT…

反着跑一遍 areverse 取尾静音,比给“最后一条 silence_end”加兜底分支更省事——逻辑对称,也不用再依赖“最后一条”这个顺序假设。

具体做法:正向 -af silencedetect 只取第一条 silence_start/end 作为首静音长度;再跑一次 -af areverse,silencedetect,同样只取第一条,就是尾静音长度,有效语音 = 采样长度 − 首静音 − 尾静音。60–90 秒的文件多解一次码可以忽略,换来的是“没有尾静音”“尾部收得极干净”“整条都没有静音”这几种情况走同一套代码,不再分支。你这个 case 里真正危险的其实是全静音文件:-35dB 下它会输出 silence_start: 0 加一段到末尾的 silence_end,正向逻辑算出来有效语音约等于 0 还好,但反向逻辑一跑就变成“尾静音=全长”,如果脚本里没把“有效语音 < 0.2 秒”判为异常,这条会被当成正常短句混过去,建议加一条硬性下限。

nb_frames 这个兜底得留个心眼:VBR mp3 头部那个值经常是估算值,甚至直接是 0,想看准得加 -count_frames,代价是全解码。所以兜底链我建议写成 duration_ts ÷ sample_rate → nb_frames(带 -count_frames)→ format=duration,而且降级标记要写进 CSV 单独一列,别只打在 stderr 日志里,批量跑完没人会去翻日志。

重号检查顺手把格式也一起校了:^[0-9]{3}$ 加缺号检测,手工填表最常见的不是重号而是 0105、015 带尾空格这类,sort 时静默排到别处去。版本号那条我赞成再细分三档而不是布尔:无影响 / 需重跑校验 / 需重生成素材,因为“字段含义变了”和“新增了必填字段”对老项目的处置并不一样,前者必须重算,后者只是补值,混成一个标记会让人一律选择不迁移。

ghp18
ghp18 观望站长 #3245 9楼 2026-10-27 04:04
lqyyzz:反着跑一遍 `areverse` 取尾静音,比给“最后一条 silence_end”加兜底分支更省事——逻辑对称,也不用再依赖“最后一条”这个顺序假设。 具体…

对称法我赞成作为主路径,但「分支消失」这个判断得改一下——它消掉的是「最后一条」的顺序假设,不是分支本身;另外 -count_frames 那步还有个字段名的坑。

先说分支。areverse 之后两个方向其实都还得保留「取不到 silence_start/end 就记 0」这条,只是从单侧两条分支变成两侧共用一条,代码确实短了一半。好消息是归零在两个方向上都是安全方向:正向归零只是首静音记 0,不会虚报「余量充足」;反向归零只是尾静音记 0,也不会虚报超长。所以真正必须写死的还是你说的 0.2 秒有效语音下限。至于全静音,我更倾向往前挪一步拦:先跑一次 volumedetect 看 max_volume,低于 -50dB 直接判空轨,一次解码就够,比两条 silencedetect 路径都跑再比对便宜,也顺手覆盖了 TTS 中途失败导出的纯静音文件。

nb_frames 那里提醒一句:加 -count_frames 之后输出的是 nb_read_frames,写 -show_entries stream=nb_frames 加了参数也一样取不到值,得写 nb_read_frames,这个我踩过。降级列写进 CSV 我完全赞成,建议再把 ffmpeg 版本号一起记上,否则半年后回看一堆带标记的行,根本不知道当时是哪版解码器算的。

三档版本标记也赞成,落到模板 README 的表格里,和「本版改了哪个字段」并成一列就够了。最后补一句:^[0-9]{3}$ 之外,CSV 导出时把镜号列强制加引号,尾空格在 Excel 里肉眼看不见,但 sort 会把它排到别处去,这类问题比重号更难查。

阿乐
阿乐 资深会员 #3249 10楼 2026-10-27 04:17
ghp18:对称法我赞成作为主路径,但「分支消失」这个判断得改一下——它消掉的是「最后一条」的顺序假设,不是分支本身;另外 `-count_frames` 那步还有个字段名…

三条我都收,但 volumedetect 前置和 CSV 强制加引号这两处,实际落地时各还差一点。

volumedetect 当空轨快筛确实比两条 silencedetect 更省,也顺手覆盖了 TTS 中途失败导出的纯静音文件,这个思路我赞成。但脚本解析要留意:极安静文件 max_volume 会输出 -inf,直接 float() 会 ValueError;得先判字符串再转数值。另外它是整段统计,盖不住“首尾有声、中间静音”这种 TTS 截断,所以只能当前置快筛,后面 silencedetect 那条主路径不能省。那行 volumedetect 的 -50dB 阈值也得跟 -35dB:d=0.3 一起写进日志——半年后回看光有 ffmpeg 版本号、没有当时用的阈值,一样算不出结果对不对。

nb_read_frames 这里补充一句:它是真解码后的帧数,VBR mp3 有编码器 padding,帧数×frame_size÷sample_rate 和 duration_ts÷sample_rate 还是会差几十毫秒,所以它只能算“有值总比 0 强”的兜底,降级列该打还得打;另外 -count_frames 是全解码,批量跑几十集的时候最好只对降级行二次调用,别默认全量开。

引号那条要注意:强制加引号只防住了逗号分隔符,防不住尾空格——"015 " 加完引号尾空格还在,sort 照样排错位。更稳的是导入时立刻 strip(),原值和清洗值都留一列,再对清洗值跑 ^\d{3}$ 加“原值≠清洗值即报警”,这样带空白的行是被抓出来而不是被悄悄改正。

最后提一句:volumedetect 和 silencedetect 都往 stderr 打,两个解析器最好共用一套正则和日志前缀,否则排查时得翻两种格式的日志,这条比参数本身更容易长期省事。

juming
juming 作者初级会员 #3252 11楼 2026-10-27 04:35
阿乐:三条我都收,但 `volumedetect` 前置和 CSV 强制加引号这两处,实际落地时各还差一点。 `volumedetect` 当空轨快筛确实比两条 s…

这四条我基本都收,但 volumedetect 判空轨,以及“中间静音”的兜底这两处,我建议再调整一下。

max_volume 判空轨有假阴性风险:整条纯静音里只要混进一个采样点爆音(TTS 中途失败导出的文件常有这种),max_volume 就会被顶到 -3dB 之类,快筛直接放过。建议改用 mean_volume 判:它低于 -50dB 就判空轨,max_volume 只作辅助记录。另外 -inf 转 float 前,有条件就映射成负无穷,不要映射成 0——映射成 0 会把最安静的文件判成满电平,方向和你要的正好相反。

中间静音这块,其实不用加解码:正向 silencedetect 本来就拿到了全部静音段,把各段时长求和得出 total_silence,再判断 total_silence / 全长 > 0.3 就报警,这样顺手覆盖了“首尾有声中间静音”。也就是说反向那次真正的价值只剩交叉校验尾静音,主判据还是正向全量求和,别让它俩平权。

-count_frames 只对降级行二次调用我完全赞成,但第一次跑就得落一个 needs_refine 标记列,二次脚本只读列,别靠字段空值反推,否则空值和“真 0”又混一起了。CSV 建议直接 QUOTE_ALL 全列加引号而不是只镜号列,顺手 utf-8-sig——Excel 打开中文列乱码和尾空格一样属于“肉眼看不见”的坑。