有声书 TTS API:成本、分段与制作流程
一本 300 页的书约 450,000 个字符:用 speech-2.8-hd 按刊例价合成需要 $45.00,按当前 5% 的分组折扣是 $42.75,成品音频约 8 小时 20 分钟。本页逐步算清这笔账,说明让长篇书稿可以稳定复现的分段与文件命名规则,并给出“先出草稿、再出母带”的两遍制作流程。
试听旁白示例
以下为英文示例:同一段文字分别由两个模型生成,经本站中转,未做任何后期处理。多数制作者用 turbo 出草稿、用 hd 出母带,下面两段之间的差别,就是你要做的取舍。
音色:English_expressive_narrator。
按一本 300 页的书算一笔账
以一本普通的平装书为例:300 页,每页约 250 个单词,共 75,000 个单词。英文算上词后的空格,平均每个单词约 6 个字符,所以实际提交的书稿约为 450,000 个字符。这两个数字是规划用的估算值,不是实测值。真正计费的只有你发送的字符串长度,在拿到 API Key 之前就可以用 len(text) 算出来。
YiduoChan 上的 MiniMax 语音模型按输入字符计费,价格与 MiniMax 官方公布的按量付费价一致。speech-2.8-hd 为每百万字符 $100(每 1,000 字符 $0.10);speech-2.8-turbo 为每百万字符 $60(每 1,000 字符 $0.06)。目前所有账号都在倍率为 0.95 的分组里,实际扣费比刊例价低 5%。请把它当作当前的分组折扣,而不是永久承诺;向客户报价之前,先到语音价格页核对一下。
| 项目 | speech-2.8-turbo | speech-2.8-hd |
|---|---|---|
| 每百万输入字符刊例价 | $60.00 | $100.00 |
| 按当前 5% 分组折扣的实际单价 | $57.00 | $95.00 |
| 450,000 字符书稿,刊例价 | $27.00 | $45.00 |
| 450,000 字符书稿,5% 折扣后 | $25.65 | $42.75 |
| 单章 15,000 字符,刊例价 | $0.90 | $1.50 |
| 单章 15,000 字符,5% 折扣后 | $0.86 | $1.43 |
| 每小时成品音频(约 54,000 字符),刊例价 | $3.24 | $5.40 |
| 每小时成品音频,5% 折扣后 | $3.08 | $5.13 |
表中不足一美分的零头已四舍五入显示。精确值为:折后单章分别是 $0.855 和 $1.425,折后 turbo 每小时音频是 $3.078。
时长也用同样的方法估算:英文语音每分钟约 900 个字符,所以 450,000 个字符约为 500 分钟,即 8 小时 20 分钟的成品音频。换算成每小时约 54,000 个字符;出版方给你的是目标时长而不是字数时,用的就是这个换算。
为什么按字符计费让长篇内容的成本可预期
账单只取决于你发送的输入,而不取决于返回的音频。一部 450,000 字符的书稿在 speech-2.8-hd 上按刊例价是 $45.00,按当前 5% 的分组折扣是 $42.75;无论最终生成八小时还是九小时、请求 mp3 还是 wav、旁白读得快还是慢,都是这个价。正是这一点,让有声书预算变成一道表格计算题,而不必先做一个试点项目。把定稿的字符数统计一遍、乘上单价,第一个请求发出之前,你就能算出精确到美分的成本。
这也意味着花一个小时清理文本是值得的。计费会计入你提交的每一个字符,包括空格、标点、页眉、脚注标记,以及源文件里残留的 Markdown 标记。把 450,000 字符的书稿删掉 2%,就少了 9,000 个字符,在 speech-2.8-hd 上按刊例价折合 $0.90,按当前分组价折合 $0.855。更大的好处是:你不用再花钱让旁白把你的星号念出来。
长时间批量生成时,第二个关键特性是失败的请求从不计费。一整本书要发几百到几千个请求,持续数小时。第 22 章时连接断开、某个片段返回错误、重试循环连试三次才成功——这些都不消耗额度。只有你真正收到的响应才计费。所以可续跑的生成循环可以放心地激进重试:遇到任何错误就重试,某个片段反复失败就拆小再试,你的成本模型始终等于那些真正在磁盘上生成了音频的文本字符数。
书稿怎么分段
/v1/audio/speech 没有公布单次请求的字符上限。既然上限没有写进文档,就不要围绕一个猜出来的数字做设计。把书稿分段,让每个请求都保持在宽裕的小尺寸;某个过大的片段报错时,把它当作需要继续拆分的信号,而不是一笔开销。
先按章
首先按章节边界切分。章节是编辑讨论问题的单位,是听众跳转的单位,也是某个专有名词读错时你要重新生成的单位。在示例书里,30 章、平均每章 15,000 个字符,合计正好 450,000;按每分钟 900 字符估算,每章约 16 分 40 秒音频。按章发请求还自然形成一份进度日志:30 行输出,每行带一个字符数,可以和账单逐项核对。
再按段落
如果某一章长到让你不放心,就再按空行切开,把完整的段落装进不超过固定上限的分块里——8,000 字符是一个保守的起点。永远不要在句子中间切开。韵律是按请求生成的,在从句中间断开,接缝处能听出来;在段落之间断开,则正好落在本来就该有短暂停顿的地方。装箱逻辑要保持贪心且确定,这样对没有改动的章节重新运行切分程序,得到的分块逐字节相同。
让文件名按播放顺序排序
每个序号都用前导零补齐到足以容纳最大值的宽度:从 ch001.wav 到 ch030.wav,段落分块则用 ch014_p0007.wav 这样的名字。不补零的文件名在任何 shell 通配、任何 sorted() 调用和任何文件管理器里都会排成 ch1、ch10、ch2,而这个错误要到拼接那一步才会发现,那时钱已经花出去了。书前内容单独占一个位置 ch000_frontmatter,让它排在第一章之前。每一遍的输出放在各自的目录里(draft/、master/),不要把模型名写进文件名,这样同一份排序列表对两遍都适用。
只重新生成一章
按章的粒度让修改保持便宜。在 speech-2.8-hd 上重新生成一章 15,000 字符,按刊例价是 $1.50,按当前分组价是 $1.425;在 speech-2.8-turbo 上分别是 $0.90 和 $0.855。所以修正第 14 章里一个读错的姓氏只要 $1.50,而整本生成要 $45.00——正好是全书的三十分之一,与这一章所占的字符比例一致;如果请求中途失败,则一分钱都不花。要是把整本书放进一个请求,为了改 40 个字符,你就得重新生成 450,000 个字符。
保持音色与节奏一致
八小时音频的一致性是配置问题,不是调参问题。整本书固定用一个音色 ID,中途绝不更换:英文旁白用 English_expressive_narrator,或者用其他官方音色 ID,例如 male-qn-qingse、female-shaonv。你也可以通过 /v1/minimax/voice_clone 用一段样本克隆出旁白音色,再固定使用它返回的音色 ID。无论哪种方式,旁白的身份就是你固定的那个音色 ID,所以相隔几个月生成的同一本书,听起来仍是同一位朗读者。
MiniMax 专有参数也一样处理。构造一个包含 voice_setting.emotion 和 audio_setting.sample_rate 的 metadata 对象,在模块级只定义一次,整本书的每个请求都传入同一个对象。逐章改变情绪,会在章节交界处产生听得出的变化,除非你本来就想要这种效果;改变 sample_rate 则会迫使拼接时重新采样。把模型 ID、音色 ID、输出格式和 metadata 对象写进音频旁边的 manifest.json,这样六个月后重新生成时,能复现第 13 章和第 15 章当初所用的设置。另外,同一本成品书里不要混用 speech-2.8-turbo 和 speech-2.8-hd。
格式:母带用无损,发布用 mp3
response_format 支持 mp3、wav、flac 和 pcm,默认 mp3。由于按输入字符计费,选哪种格式都不影响价格——示例书的 wav 母带按刊例价同样是 $45.00,与它的 mp3 草稿一样。
母带用 wav 或 flac 生成。两者都是无损格式,做音量标准化、裁剪静音、拼接分块都不会因反复编码而损失音质;flac 保存的是同样的采样,文件比 wav 小。只有在把原始采样直接送进 DSP 处理链、并且已经知道采样率和位深时才用 pcm,因为它没有容器头来告诉你这些信息。mp3 只在最后生成一次,由完成的无损母带编码而来——而不是向 API 要 mp3、剪辑后再重新编码。一次性的草稿那一遍可以直接用 mp3,那些文件听一遍就会删掉。这个接口没有文档说明支持流式音频,所以把生成程序写成批处理任务,批量生成本来也适合这样写。
按章生成音频的脚本
下面的循环先给整个任务报价,再把各章文本生成为编号文件,已经在磁盘上的文件会跳过,所以中断后重跑可以接着来,不会重复付费。它使用 OpenAI 兼容的 Base URL https://yiduochan.com/v1,由 SDK 带上 Authorization: Bearer <your API key>;Node 的等价写法见 SDK 配置说明。
import glob, json, os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["YIDUOCHAN_API_KEY"],
base_url="https://yiduochan.com/v1",
)
LIST_USD_PER_1M = {"speech-2.8-turbo": 60.0, "speech-2.8-hd": 100.0}
GROUP_RATIO = 0.95 # current 5% group discount
VOICE = "English_expressive_narrator"
METADATA = {
"voice_setting": {"emotion": "neutral"},
"audio_setting": {"sample_rate": 44100},
}
def quote(chapters, model):
chars = sum(len(c) for c in chapters)
listed = chars / 1_000_000 * LIST_USD_PER_1M[model]
return chars, round(listed, 4), round(listed * GROUP_RATIO, 4)
def split_paragraphs(text, max_chars=8000):
"""Pack whole paragraphs into parts; never split a sentence."""
parts, buf = [], ""
for para in text.split("\n\n"):
if buf and len(buf) + len(para) + 2 > max_chars:
parts.append(buf)
buf = para
else:
buf = f"{buf}\n\n{para}" if buf else para
if buf:
parts.append(buf)
return parts
def render(chapters, model, fmt, outdir):
os.makedirs(outdir, exist_ok=True)
for i, chapter in enumerate(chapters, start=1):
for j, part in enumerate(split_paragraphs(chapter), start=1):
path = os.path.join(outdir, f"ch{i:03d}_p{j:04d}.{fmt}")
if os.path.exists(path): # resume; failed runs cost nothing
continue
audio = client.audio.speech.create(
model=model,
input=part,
voice=VOICE,
response_format=fmt,
extra_body={"metadata": METADATA},
)
with open(path, "wb") as f:
f.write(audio.content)
print(path, len(part), "chars")
with open(os.path.join(outdir, "manifest.json"), "w") as f:
json.dump({"model": model, "voice": VOICE,
"response_format": fmt, "metadata": METADATA}, f, indent=2)
chapters = [open(p, encoding="utf-8").read()
for p in sorted(glob.glob("manuscript/ch*.txt"))]
print(quote(chapters, "speech-2.8-hd")) # (450000, 45.0, 42.75)
render(chapters, "speech-2.8-turbo", "mp3", "draft") # pass 1
render(chapters, "speech-2.8-hd", "wav", "master") # pass 2
两遍制作:turbo 出草稿,hd 出母带
一遍成书的典型翻车方式是:听到第六个小时才发现,旁白把一个反复出现的姓氏读错了;书稿里本来指页码的数字被读成了“eighteen forty-two”;或者把一个残留的 Markdown 标题念了出来。这些全都是书稿的问题,你希望用便宜的价格把它们找出来。
第一遍用 speech-2.8-turbo 把整本书生成为 mp3,放进 draft/,唯一的用途是倍速试听。改好书稿文本后,第二遍用 speech-2.8-hd 把修正后的文本生成为 wav,放进 master/。
| 遍次 | 模型 | 格式 | 字符数 | 刊例价 | 5% 折扣后 |
|---|---|---|---|---|---|
| 1 — 草稿与质检 | speech-2.8-turbo | mp3 | 450,000 | $27.00 | $25.65 |
| 2 — 母带 | speech-2.8-hd | wav | 450,000 | $45.00 | $42.75 |
| 合计 | — | — | 900,000 | $72.00 | $68.40 |
总成本是单遍 hd 的 1.6 倍:按刊例价多花 $27.00,按当前分组价多花 $25.65。盈亏平衡点很好算。按刊例价,hd 重新生成一章要 $1.50,所以草稿这一遍只要避免了 18 次按章重做就回本了($27.00 ÷ $1.50 = 18)。按折扣价算,比例完全相同:$25.65 ÷ $1.425 = 18。对一本 30 章的书来说,这相当于 60% 的章节。
开通账号,核算你自己的数字
使用方式是预付美元额度,按量付费,无订阅;新账号注册即送 $0.10 试用额度,约合一分钟的 hd 旁白,正式使用需要充值。最低充值 $5,预设档位有 $5、$10、$20、$50、$100、$200 和 $500,也可以自定义金额,额度有效期 12 个月。$100 档足够覆盖 $68.40 的两遍示例,还留有重新生成的余量。在 /register 注册,在 /pricing 查看价格;规划一批书目之前,先把你自己的字符数放进费用计算器算一算。
更短的内容也用同一个接口、同一套计费方式:短内容的做法见视频配音 TTS,参数细节见 speech-2.8 模型页,对话模型见 MiniMax 模型总览。调用 GET /v1/models 可以确认你的 Key 能访问的确切模型 ID;如果估算和账单对不上,请发邮件至 support@yiduochan.com。
常见问题
把一本 300 页的书做成有声书要多少钱?
一本 300 页的书约 450,000 个字符,按刊例价在 speech-2.8-hd 上是 $45.00,在 speech-2.8-turbo 上是 $27.00。按当前 5% 的分组折扣,分别为 $42.75 和 $25.65。
单次请求有字符数上限吗?
官方没有公布单次请求的字符上限,所以先按章、再按段落切分,让每个请求保持较小。如果某个过大的片段返回错误,把它拆开重试即可——失败的调用不计费。
失败或重试的请求要付费吗?
不用。失败的请求从不计费,所以出错就重试的可续跑生成循环,唯一的代价只是多花些时间。
母带应该用什么输出格式?
母带用 wav 或 flac 生成,最后再从这份无损母带编码一次 mp3。格式不会影响价格,因为计费按输入字符计算。
可以克隆旁白的音色吗?
可以。/v1/minimax/voice_clone 接收一段样本,返回一个可以固定用作旁白的音色。整本书固定使用一个官方音色 ID,例如 English_expressive_narrator,并在每个请求里复用同一个 metadata 对象。
有免费额度可以测试吗?
有,但不多:新账号注册即送 $0.10 试用额度,约合一分钟的 hd 旁白。此后需要使用预付美元额度,按量付费,最低充值 $5,额度有效期 12 个月。