Goal1 · 音质研究 · test-only

同一条阿语脚本,两种合成方式,你来听

问题只有一个:把 6 段脚本切开各合各的,和拼成一整条一次合成,哪个听起来更像真人?

素材:ultra/23uCHB.json —— 一条 36.9 秒的阿拉伯语游戏解说,6 段时间轴,带 [excited] / [fast] / [gasp] 情绪标记。两边用同一个 voice、同一个 eleven_v3 模型,都不做变速拉伸。唯一的变量就是"切不切段"。

先听,再看分析

A / B 试听

方式 A

分段

6 段各调一次 → 原样拼起来

总长 35.50s · 6 次 API 调用
6 个拼接硬边界
方式 B

总体

拼成一条 → 只调一次

总长 37.41s · 1 次 API 调用
段间自然停顿 0.14–0.28s
方式 C

总体 · 换一家

Fish Audio 整段一次出

总长 33.46s · s2-pro 模型
解说腔音色 · 见下方说明

方式 C 不是干净对照,先说清楚,免得你听岔:

  • 换了 provider(Fish Audio,不是 ElevenLabs)也换了音色(فارس عوض / Fares Awad,阿语足球解说腔)——所以它和 A/B 不是只差"切不切段"一个变量
  • 情绪 [excited]/[gasp] 标记全剥掉了:Fish 的标记词表和 ElevenLabs 不一样,怕它念成字面,喂的是干净阿语
  • 整体响度低约 4dB(-21.2 vs -17.4),听感会偏轻,落地要补一道电平归一

它回答的是另一个问题:"另一家把整段一口气说出来,是什么味道"——解说腔、连贯度、自然停顿值不值得换。

重点听三个地方:① 段与段衔接处——A 是不是有"换气重起"的突兀感,B 是不是顺下来的;② 情绪的连贯——同一句兴奋劲儿有没有断;③ 句子之间的停顿是不是像人说话的节奏。

客观数据

四个数,先有个底

6 → 1
API 调用次数
+1.9s
总体比分段长
1.7 dB
分段各段响度差
100%
总体对齐还原

响度这项 A/B 打平(分段各段最多差 1.7dB,总体 -17.4dB)。所以 A/B 这场胜负不在音量,在韵律——衔接和停顿才是耳朵能听出来的地方。

方式Provider调用总长情绪tag响度字符级对齐
A 分段ElevenLabs v36 次35.50s保留-17.4dB逐段各自
B 总体ElevenLabs v31 次37.41s保留-17.4dB100% 还原
C 总体·换家Fish s2-pro1 次*33.46s剥离-21.2dB词级 33 词

* Fish 一次请求,内部自动分 3 个 chunk 流式吐(condition_on_previous_chunks 保持前后音色一致),对外仍是"整段一次出"。它的对齐是词级segments[] 带 text/start/end),ElevenLabs 是字符级——两种都能切字幕,词级反而更省断词功夫,但中日泰这种无空格语种要另算。

方法

两条路,到底怎么走的

方式 A · 分段

每段从零起调

  • 把 6 段 script 各自单独发给 ElevenLabs
  • 每段是一次独立生成——模型不知道前后还有别的话
  • 每段自带它自己的起音、换气、收尾
  • 6 个 mp3 用 ffmpeg concat 硬接,接缝处没有过渡
方式 B · 总体

一口气说完

  • 先给每段补上句末标点,再用空格拼成一整条build_combined_text
  • 整条只发一次——模型看得到上下文,自己安排轻重缓急
  • 句与句之间是模型自然吐出的停顿,不是拼出来的
  • 事后用 with-timestamps 的字符级对齐切回每段时间轴

拼出来的那一整条长这样(396 字符,6 句连在一起喂给模型):

[excited] هل تبحث عن لعبة ممتعة حقا شاهد هذا. [excited] نقطع الخشب بالليزر ونجمع الموارد بسرعة فائقة هذا شعور مرضي جدا. [fast] نحولها إلى ألواح خشبية ممتازة وننقلها بالشاحنات لترقية القاعدة فورا. [gasp] انظر إلى هجوم الزومبي نستخدم الخشب لبناء أبراج دفاعية قوية لحمايتنا. [excited] نرقي الأبراج باستمرار لصد الموجات الضخمة اللعب سلس بدون توقف. [fast] حمل اللعبة الآن مجانا وابدأ بناء دفاعك الخاص.

逐段对照

每段多长,停顿在哪

分段时长总体时长总体·段前停顿脚本开头
03.87s3.92s[excited] هل تبحث…
16.69s7.16s0.16s[excited] نقطع الخشب…
27.31s7.26s0.14s[fast] نحولها…
37.00s6.88s0.16s[gasp] انظر…
46.77s6.92s0.28s[excited] نرقي…
53.87s4.44s0.04s[fast] حمل اللعبة…
合计35.51s37.41s≈0.78s

逐段时长两边几乎一样(差几百毫秒),所以总体方式没有牺牲对齐。差别全在那列"段前停顿"——这 0.14~0.28s 是分段方式里根本不存在的东西:分段是把 6 个独立片段怼在一起,接缝是零,反而显得急、像机器。总体多出来的 1.9s 基本就是这些自然停顿攒出来的。

这次研究要验的

"输入更长 = 更好" 站得住吗

  • 韵律连续:整条进去,eleven_v3 能把一句话的轻重、升降、情绪走向一气呵成;分段每段都从中性语调重新起,攒不出"一个人连着讲"的劲
  • 停顿是真的:句间换气由模型按语义吐出,不是我们硬塞的静音
  • 对齐可信:这条总体的字符级对齐100% 还原了输入文本,切段稳,不用担心时间轴错位
  • 情绪过渡[gasp] 那种"先惊后定"的转折,在连续语流里才接得住,切开就断了

理论上总体占优。但这页不替你下结论——最终听感由你的耳朵判。上面两个播放器,来回切几遍。

不能只说好处

总体方式的代价

所以真正落地多半是"总体优先、塌缩回退分段"的混合——这也正是 mai-combo-runner-wholecontent-test 那条原型在走的路。


素材 ultra/23uCHB.json · A/B: ElevenLabs eleven_v3 voice EkK5I93UQWFDigLMpZcX · C: Fish s2-pro ref 79b0fd32(فارس عوض)· mp3 128k · 无变速 · test-only,线上未动