news 2026/9/10 15:24:17

Puter TTSVoice 对象详解:AI 文本转语音音色元数据与实战调用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Puter TTSVoice 对象详解:AI 文本转语音音色元数据与实战调用指南

Puter TTSVoice 对象详解:AI 文本转语音音色元数据与实战调用指南

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

TTSVoice是 Puter AI 平台中描述"某个文本转语音(TTS)供应商可用音色"的数据对象。本文以 TTSVoice 对象文档 为骨架,完整讲解其idnameproviderlanguagecategorylabelssupported_modelssupported_engines等全部字段的语义与可选性,并对照 txt2speech.listVoices()、txt2speech() 两个接口文档及仓库后端源码给出可运行的调用示例。读完本文,你将掌握如何在浏览器、Node.js、App 或 Worker 中枚举、过滤并挑选语音,把正确的 voice id 传入语音合成调用。

背景:TTSVoice 在 Puter AI 语音能力中的位置

Puter 将多家第三方 TTS 供应商(AWS Polly、OpenAI、ElevenLabs、Gemini、xAI、Speechify)抽象成统一接口puter.ai.txt2speech。当你想让应用"开口说话"时,通常需要先回答两个问题:

  1. 该供应商当前提供哪些音色(voice)?
  2. 某个音色支持哪些引擎/模型、语言与附加元数据?

TTSVoice对象就是第 1 个问题的标准答案格式:它是 listVoices 接口返回数组的元素类型。根据 后端类型定义,ITTSVoice在源码中的结构为:

export interface ITTSVoice { id: string; name: string; language?: { name: string; code: string; }; description?: string; category?: string; provider: string; labels?: Record<string, string>; supported_models?: string[]; supported_engines?: string[]; }

该接口由统一的puter-ttsdriver 的list_voices()方法调用各供应商listVoices(args)后归一化返回(见 TTSDriver.ts);当传入provider: 'all'时,driver 会遍历所有已注册 provider 并拼接结果。对象文档中带May be absent(可缺失)字样的字段在 TS 类型中恰好对应?可选标记——这说明同一数组内的对象字段并不完全同构,不同供应商返回的元数据详略差异很大,消费端代码应做空值防御。

属性详解

下文逐字段说明 TTSVoice 文档 定义的 9 个属性。

id(String,必有)

传给puter.ai.txt2speech()的音色标识符。它是整个对象最关键的字段:枚举音色的最终目的,就是拿到一个能在合成调用中被识别的 id。典型取值如 OpenAI 的'alloy'、AWS Polly 的'Joanna'、ElevenLabs 的'21m00Tcm4TlvDq8ikWAM'(Rachel 示例音色)、Gemini 的'Puck'、xAI 的'eve'等。

注意 id 通常是供应商侧定义的原始值(大小写、连字符、下划线都可能保留原样),不要臆测规范化规则,直接回传即可。

name(String,必有)

人类可读的音色名称,例如"Alloy""Joanna"。它用于展示层(下拉菜单、设置面板、列表 UI),而真正传给合成接口的是id。在 listVoices 示例 中两者的配合非常典型:console.log(voice.id, voice.name)就是"面向机器取 id、面向用户显示 name"的用法。

provider(String,必有)

该音色所属的供应商,例如'aws-polly''openai''elevenlabs''gemini''xai'。当调用listVoices({ provider: 'all' })一次性拉取所有供应商时,这个字段是你按来源分组/过滤结果的唯一依据。供应商的"官方 id + 常见别名"全部定义在后端 providerAliases.ts 中:除六个规范名外,'eleven''google''grok''polly''simba''aws'等别名也会被normalizeTTSProvider()归一化到对应规范名;传入无法识别的供应商名时,接口会以bad_request错误拒绝。

language(Object,可选,可缺失)

描述音色语言的嵌套对象,包含两个 String 属性:

  • name:人类可读语言名,如"English (US)"
  • code:语言代码,如"en-US"

文档强调May be absent——例如 OpenAI 等偏向"中性音色"的供应商通常不提供语言字段。因此当你想用语言代码展示音色时,应先判断voice.language是否存在,官方示例即采用这种防御式写法:

const lang = voice.language ? ` (${voice.language.code})` : ''; console.log(`${voice.id} - ${voice.name}${lang}`);

典型含此字段的返回项如下(来自 listVoices 文档 的示例响应):

{ "id": "Joanna", "name": "Joanna", "provider": "aws-polly", "language": { "name": "English (US)", "code": "en-US" }, "supported_engines": ["standard", "neural"] }

注意:AWS Polly 对同一音色的语言归属非常明确,因此在与语言相关的合成参数上,Polly 还有独立的language参数(默认'en-US'),二者语义要区分开。

description(String,可选,可缺失)

音色的简短文字说明。例如 OpenAI 示例返回项中的"description": "A balanced, neutral voice"。适合做 UI 中的悬停提示或辅助选择文案,缺失时应做降级处理。

category(String,可选,可缺失)

音色类别,文档给出的示例值是'premade'(预置音色)。该字段常用于筛选"预置/自定义"音色。

labels(Object,可选,可缺失)

供应商自定义标签的键值对象。不同供应商会携带不同粒度的信息,后端类型将其建模为Record<string, string>(见 types.ts)。由于内容是 provider 专属的,跨供应商代码不应假设其中存在某个固定键。

supported_models(Array,可选,可缺失)

该音色可配合使用的模型 id 数组,元素为 String。例如某个音色可能仅支持['eleven_multilingual_v2']。若该字段存在,可用于在 UI 中禁用不兼容当前模型的音色;缺失时通常表示不限制。

supported_engines(Array,可选,可缺失)

该音色支持的引擎类型数组,元素为 String。在 AWS Polly 场景下取值如["standard", "neural"],恰好对应 txt2speech 文档 中 Polly 的engine参数可取值'standard'(默认)、'neural''long-form''generative'。这个字段非常适合做"选好音色后列出可用引擎供用户切换"的动态联动 UI。

如何获取 TTSVoice 数组:listVoices() 接口

TTSVoice对象只能通过puter.ai.txt2speech.listVoices()获得。该接口支持两种调用形态:

puter.ai.txt2speech.listVoices() puter.ai.txt2speech.listVoices(options)

参数说明

参数类型说明
optionsObject(可选)支持providerengine两个键,详见下表

options内可用项:

Option类型说明
providerString要查询的 TTS 供应商。默认'aws-polly'。接受'aws-polly''openai''elevenlabs''gemini''xai',以及'all'(一次性列出所有供应商);常见别名如'eleven''google''grok'同样有效。无法识别的 provider 会被bad_request拒绝
engineString引擎/模型过滤条件(供应商相关,部分供应商忽略)

一个便捷规则:options以普通字符串传入时,会被当作默认(AWS Polly)供应商的engine过滤器

返回值

Promise,resolve 为TTSVoice对象数组。provider: 'all'时的示例响应(含可选字段缺失的情形):

[ { "id": "alloy", "name": "Alloy", "provider": "openai", "description": "A balanced, neutral voice" }, { "id": "Joanna", "name": "Joanna", "provider": "aws-polly", "language": { "name": "English (US)", "code": "en-US" }, "supported_engines": ["standard", "neural"] } ]

可以看到第一条 OpenAI 音色没有languagesupported_engines,第二条 Polly 音色没有description——这正是"可选字段可缺失"字段语义在真实数据中的体现。

完整可运行示例

浏览器(HTML)中列出某个供应商的音色:

<html> <body> <script src="https://js.puter.com/v2/"></script> <script> (async () => { const voices = await puter.ai.txt2speech.listVoices({ provider: 'openai' }); puter.print('OpenAI voices:'); for (const voice of voices) { puter.print(` ${voice.id} - ${voice.name}`); } })(); </script> </body> </html>

Node.js 中列出默认(AWS Polly)全部音色并带语言代码:

const voices = await puter.ai.txt2speech.listVoices(); for (const voice of voices) { const lang = voice.language ? ` (${voice.language.code})` : ''; console.log(`${voice.id} - ${voice.name}${lang}`); }

Node.js 中列出 Gemini 音色:

const voices = await puter.ai.txt2speech.listVoices({ provider: 'gemini' }); for (const voice of voices) { console.log(voice.id, voice.name); }

在自托管场景下,该接口在服务端对应 TTSDriver.ts 的list_voices()实现:单供应商模式直接转发给目标 provider,'all'模式则遍历聚合。若需要进一步了解每个供应商侧的listVoices归一化逻辑,可查阅 src/backend/drivers/ai-tts/providers 下各 provider 目录(awsPolly、openai、elevenlabs、gemini、xai、speechify)及其同名测试文件。

实战:从 TTSVoice 到实际发声

拿到 TTSVoice 数组只是第一步,最终要用其中某个voice.id发起合成。下表将 txt2speech() 支持的主流供应商与音色/模型默认值汇总,帮助你理解不同 provider 的 TTSVoice 对象"语言与引擎字段为何呈现差异":

Provider典型 voice 值默认 model / engine语音风格相关参数
aws-pollyJoanna(默认)等,Polly 官方音色表engine:standard(默认)、neurallong-formgenerative;language 默认en-USssml布尔开关
openaialloy(默认)、ashballadcoralechofablenovaonyxsageshimmermodel:gpt-4o-mini-tts(默认)、tts-1tts-1-hd;输出mp3/wav/opus/aac/flac/pcminstructions风格引导
elevenlabs21m00Tcm4TlvDq8ikWAM(默认,Rachel)model:eleven_multilingual_v2(默认)、eleven_flash_v2_5eleven_turbo_v2_5eleven_v3;输出默认mp3_44100_128voice_settings(stability、similarity boost、speed)
geminiKore(默认),另有ZephyrPuckCharonFenrirLeda等 30 个音色model:gemini-2.5-flash-preview-tts(默认)、gemini-2.5-pro-preview-ttsgemini-3.1-flash-tts-previewinstructions自然语言风格指令
xaieve(默认、充满活力)、ara(温暖)、rex(自信)、sal(流畅)、leo(权威)language 默认'en',支持'auto'自动检测与 20+ 语言;输出mp3/wav/pcm/mulaw/alaw内联标签[pause][laugh]<whisper>text</whisper>
speechifygeffen_32(默认)、dominic_32harper_32hugh_32imogen_32model:simba-3.2(默认)、simba-englishsimba-multilingual;输出mp3/wav/ogg/aac

调用返回一个Promise<HTMLAudioElement>,其src指向包含合成音频的 blob 或远程 URL。下面是一个综合场景:先在页面上枚举某个 provider 的音色,再让用户选中并播放。核心是voice.id塞回options.voice

<html> <body> <script src="https://js.puter.com/v2/"></script> <button id="play">播放所选音色</button> <select id="voiceSelect"></select> <script> const text = '你好,欢迎体验 Puter 的文本转语音能力!'; (async () => { // 1) 拉取 TTSVoice 数组 const voices = await puter.ai.txt2speech.listVoices({ provider: 'gemini' }); const select = document.getElementById('voiceSelect'); // 2) 用 name 做展示,用 id 做回传 for (const voice of voices) { const opt = document.createElement('option'); opt.value = voice.id; opt.textContent = `${voice.name}${voice.language ? ' (' + voice.language.code + ')' : ''}`; select.appendChild(opt); } })(); document.getElementById('play').addEventListener('click', async () => { const voiceId = document.getElementById('voiceSelect').value; const audio = await puter.ai.txt2speech(text, { provider: 'gemini', voice: voiceId, model: 'gemini-2.5-flash-preview-tts', instructions: 'Speak in a friendly, upbeat tone.' }); audio.play(); }); </script> </body> </html>

值得注意:txt2speech()provider 列表比 listVoices 多出'speechify',因此使用 Speechify 音色前不妨先listVoices({ provider: 'speechify' })确认最新 voice id。另外合成文本长度须小于 3000 字符;test_mode/testMode置为true时接口返回示例音频而不消耗配额,适合先试听某个voice.id再决定正式使用。

与相关对象的联系

  • TTSEngine:与 TTSVoice 并列的另一个对象类型,描述"可用引擎/模型"及可选价格元数据pricing_per_million_chars,由puter.ai.txt2speech.listEngines()返回。后端 types.ts 中ITTSEngineITTSVoice同为puter-ttsdriver 的公共结构。TTSVoice 的supported_engines/supported_models字段正是"该音色 ↔ 引擎/模型"的关联线索。
  • 同一对象族:语音合成链路中还涉及Speech2TxtResult(语音转文字结果对象,见 Objects 目录 下的 speech2txtresult.md),以及配套的 speech2txt()、speech2speech() 接口。

最佳实践小结

  1. id为准、name为辅:展示层用name,请求层回传id,不要把两者混用。
  2. 可选字段一律判空languagedescriptioncategorylabelssupported_modelssupported_engines都可能缺失,跨 provider 迭代时务必先判断再访问(如voice.language ? voice.language.code : null)。
  3. 多供应商场景用provider分组provider: 'all'返回混合数组,按voice.provider归组可避免同名音色混淆。
  4. supported_engines做联动过滤:展示 Polly 音色时,仅当数组含"neural"才允许用户选 neural 引擎,减少运行时bad_request
  5. 先试听再合成:用test_mode获取样本音频验证 voice/engine 组合,正式调用时不带该参数。
  6. 供应商别名统一由后端解析:即使 SDK 版本较旧,'eleven''google''grok'等别名也能在后端被正确归一化(见 providerAliases.ts 的normalizeTTSProvider()),因此客户端不必重复维护别名映射。

通过本文介绍的对象字段与调用链路,你已经可以把"枚举音色 → 展示选择 → 语音合成 → 播放"整条 TTS 流程接入 Puter 应用;如需在自托管环境中进一步调试,可从 src/backend/drivers/ai-tts 的驱动与 provider 实现入手追踪完整数据流。

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:18:10

Buzz 离线语音转写怎么快速配通?Faster-Whisper 三步跑起来

Buzz 离线语音转写怎么快速配通&#xff1f;Faster-Whisper 三步跑起来 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz Buzz …

作者头像 李华
网站建设 2026/9/10 15:15:31

论文大纲用60秒生成还是逐级推敲?按时间预算对比

写论文时&#xff0c;大纲这一步常把人卡在两难里&#xff1a;时间本就不宽裕&#xff0c;要不要再花大块时间逐级推敲大纲&#xff1f;本文把「60 秒快速生成」与「逐级推敲」两种路径放进同一张时间预算表&#xff0c;按可用天数给出分档选择规则。结论先行&#xff1a;对多数…

作者头像 李华
网站建设 2026/9/10 15:14:52

ZeroTierOne Windows 服务:从注册到入网的完整实战指南

ZeroTierOne Windows 服务&#xff1a;从注册到入网的完整实战指南 【免费下载链接】ZeroTierOne A Smart Ethernet Switch for Earth 项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTierOne ZeroTierOne 是一个把不同网络的机器组成同一个二层局域网的开源虚拟…

作者头像 李华
网站建设 2026/9/10 15:14:51

中医舌象AI诊断系统:多模型协同Web应用实战

简介&#xff1a;这是一套面向计算机、电子信息及中医药信息化方向学习者的中医舌象智能分析Web应用完整开发方案&#xff0c;聚焦舌色、苔色、薄厚、腻否四维分类诊断&#xff0c;适用于课程设计、期末大作业与毕业设计参考。资源包含85个文件&#xff0c;以22个Python后端核心…

作者头像 李华