AB
AiBoss
Tutorials

Uberduck

Tutorials

用 Uberduck API 把文本转成语音并筛选音色

面向开发者的 Uberduck API 实操教程:从获取 API Key 开始,用 cURL、JavaScript 与 Python 调用文本转语音接口,按语言与性别筛选音色、列出可用模型,并通过 extended 参数调整语速与音高、指定输出格式,附错误排查与版本变更说明。

Uberduck API 把语音合成、声音克隆和音乐生成三类能力收在同一个接口层之下,用一套鉴权方式、一个基础地址对外提供服务。这篇教程聚焦其中最常用的一条路径:把一段文本交给指定的音色和模型,拿回一个可以直接播放或下载的音频地址。适合已经会写基本 HTTP 请求、想在自己的应用里批量生成旁白、播报或角色台词的开发者。如果你更想先在网页里试听效果再决定用哪个音色,可以配合站内的 Uberduck 工具页一起看;真正接入代码时,下面这些接口约定才是关键。

需要先说明一点:Uberduck 的接口不是「一个模型包打天下」,而是把能力(capability)、模型(model)、音色(voice)拆成三层。文本转语音是能力,Polly、WaveNet、Neural 这类是具体模型,Joanna 这类是挂在模型下面的音色。理解这三层关系,后面选参数时就不会把音色名和模型名混着填。

准备工作

账号与 API Key

调用任何接口之前,需要准备三样东西:一个 Uberduck 账号、一把从账号后台生成的 API Key,以及对 REST 接口的基本认知和你惯用的编程语言环境。获取 Key 的路径是固定的:

  1. 登录 uberduck.ai 的账号。
  2. 进入账号设置(account settings)。
  3. 找到 API 分区。
  4. 生成一把新的 API Key。
  5. 把 Key 复制下来,后续请求都要用到。

Key 只在生成时完整展示,务必当场保存到安全的位置。所有请求都通过 HTTP 头传递它,格式是 Authorization: Bearer YOUR_API_KEY,注意 Bearer 与 Key 之间有一个空格,这是最常见的格式错误来源之一。

基础地址与版本

所有请求都发往同一个基础地址:

https://api.uberduck.ai/v1

当前版本是 v1。接口变更遵循语义化版本原则:主版本(v1、v2 等)可能包含破坏性变更;次版本更新向后兼容,只增加新功能;修订更新同样是向后兼容的问题修复。主版本切换会提前至少 6 个月公告,之后旧版本才会被弃用。这意味着把版本号写死在代码里是安全的做法,但升级窗口要留足。

三层概念:能力、模型、音色

动手写请求前,先把这三个词的含义对齐,它们直接决定请求体里填什么。

  • 能力(capability):接口按能力组织,包括 text-to-speech(文本转语音)、voice-cloning(用音频样本创建声音模型)、music-generation(用文字描述生成音乐)。
  • 模型(model):能力的实现,通常来自某个具体供应商,例如 AWS、Google、Azure。供应商是来源,模型是具体实现,例如 Polly、WaveNet、Neural。
  • 音色(voice):与语音模型搭配使用,分三类——供应商音色(供应商预置的,例如 AWS Polly 的 Joanna)、零样本音色(用你自己的音频样本创建的自定义音色)、微调音色(经过大量训练的自定义声音模型)。

所以一次文本转语音请求至少要指定两样:用哪个音色、用哪个模型。音色名和模型名不匹配会直接失败,这一点在排查问题时经常被忽略。

可用端点一览

端点说明
GET /v1/models列出可用的文本转语音模型
GET /v1/voices列出可用音色,支持多种筛选条件
POST /v1/text-to-speech用指定音色和模型把文本合成为语音

三个端点就构成了最小可用闭环:先查模型和音色,再发起合成。

操作步骤

第一步:发出第一个合成请求

先用 cURL 验证 Key 是否可用,这是排除环境干扰最快的方式。请求体里三个字段:text 是要合成的文本,voice 是音色名,model 是模型名。

curl -X POST https://api.uberduck.ai/v1/text-to-speech \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello world! This is my first Uberduck API request.",
    "voice": "polly_joanna",
    "model": "polly_neural"
  }'

返回的 JSON 里有一个 audio_url 字段,指向生成的音频文件。把这个地址拿到浏览器里打开就能试听。注意 Content-Type 必须是 application/json,请求体必须是合法 JSON,否则服务端无法解析。

第二步:用 JavaScript 或 Node.js 调用

在 Node.js 环境里用内置的 fetch 即可,不需要额外依赖。下面这段把请求、解析、播放串在一起:

async function generateSpeech() {
  const response = await fetch('https://api.uberduck.ai/v1/text-to-speech', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      text: 'Hello world! This is my first Uberduck API request.',
      voice: 'polly_joanna',
      model: 'polly_neural'
    })
  });

  const data = await response.json();
  console.log(`Speech generated! Audio available at: ${data.audio_url}`);

  // 在浏览器环境中直接播放
  const audio = new Audio(data.audio_url);
  audio.play();
}

generateSpeech();

最后两行 new Audio(...) 只在浏览器环境有效。如果代码跑在 Node.js 里,把这两行去掉,改为把 audio_url 下载到本地或交给下游处理。

第三步:用 Python 调用

Python 侧用 requests 库,把请求头写成字典、请求体用 json= 参数传入,库会自动序列化并设置正确的 Content-Type:

import requests

url = "https://api.uberduck.ai/v1/text-to-speech"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}
payload = {
    "text": "Hello world! This is my first Uberduck API request.",
    "voice": "polly_joanna",
    "model": "polly_neural"
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()
print(f"Speech generated! Audio available at: {data['audio_url']}")

生产环境里不要像示例这样把 Key 硬编码在源码中,改为从环境变量读取,例如 os.environ["UBERDUCK_API_KEY"],再拼进请求头。

第四步:查询可用音色

音色有几百个,跨多个供应商,靠猜名字不现实。先拉一批看看返回结构:

curl -X GET "https://api.uberduck.ai/v1/voices?limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

这会返回前 10 个音色。返回体里带 total 字段表示符合条件的音色总数,示例代码里就是用它来打印「找到多少个音色」的。要缩小范围,可以叠加筛选参数,例如只要英语女性音色:

curl -X GET "https://api.uberduck.ai/v1/voices?language=english&gender=female&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

目前文档里明确给出的筛选参数是 language、gender 和 limit。实际接入时建议先按语言筛一遍,再按性别筛,最后用 limit 控制返回量,避免一次拉回几百条记录。

第五步:查询可用模型

模型列表同样要先查再填。请求很简单:

curl -X GET https://api.uberduck.ai/v1/models \
  -H "Authorization: Bearer YOUR_API_KEY"

返回体里的 models 是一个数组,每个元素有 id 字段,这个 id 就是合成请求里 model 参数该填的值。示例代码里用 data.models.map(m => m.id).join(', ') 把所有模型 id 拼成一行打印出来,方便直接复制。把音色列表和模型列表对照着看,就能确定哪些组合是可用的。

第六步:用扩展参数调整语速与音高

基础请求只能控制文本、音色、模型。要调整听感,需要加 extended 对象和 output_format 字段:

const response = await fetch('https://api.uberduck.ai/v1/text-to-speech', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    text: 'This is a customized text-to-speech request with adjusted speed and pitch.',
    voice: 'polly_joanna',
    model: 'polly_neural',
    extended: {
      speed: 1.2,
      pitch: 0.5
    },
    output_format: 'mp3'
  })
});

这里 speed 控制语速,pitch 控制音高,output_format 指定输出音频格式,示例里用的是 mp3。三个字段都是可选的,不加就按服务端默认行为处理。语速和音高的具体取值范围文档没有列出,建议从接近 1.0 的语速开始小幅调整,避免一次改太多导致听感失真。

一个完整示例

下面把前面几步串成一个可运行的脚本:先查模型确认可用,再查英语女性音色,最后用第一个可用音色合成一段带语速调整的语音。以 Python 为例:

import os
import requests

API_KEY = os.environ["UBERDUCK_API_KEY"]
BASE = "https://api.uberduck.ai/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# 1. 查模型
models_resp = requests.get(f"{BASE}/models", headers=HEADERS)
models = models_resp.json()["models"]
print("可用模型:", ", ".join(m["id"] for m in models))

# 2. 查英语女性音色
voices_resp = requests.get(
    f"{BASE}/voices",
    headers=HEADERS,
    params={"language": "english", "gender": "female", "limit": 10}
)
voices_data = voices_resp.json()
print(f"找到 {voices_data['total']} 个符合条件的音色")

# 3. 用第一个音色合成语音
payload = {
    "text": "This is a customized text-to-speech request with adjusted speed and pitch.",
    "voice": "polly_joanna",
    "model": "polly_neural",
    "extended": {"speed": 1.2, "pitch": 0.5},
    "output_format": "mp3"
}

speech_resp = requests.post(f"{BASE}/text-to-speech", json=payload, headers=HEADERS)
result = speech_resp.json()
print(f"音频地址: {result['audio_url']}")

这个脚本覆盖了完整链路:鉴权、列举资源、带扩展参数发起合成、取出音频地址。把 text 换成你自己的文案、把 voice 换成第 2 步查到的某个音色 id,就能直接用于实际项目。批量生成时,把第 3 步包进循环,每次替换 text 即可,注意控制并发节奏,避免触发限流。

注意事项

请求格式类问题

遇到报错时,按下面的顺序自查,基本能覆盖大部分情况:

  • 确认 API Key 有效,且在 Authorization 头里格式正确(Bearer 加空格加 Key)。
  • 确认请求体是合法 JSON,字段名拼写与文档一致。
  • 确认所用的音色和模型彼此兼容——音色是挂在模型下面的,跨模型混用会失败。
  • 如果收到限流错误,等待一段时间再重试,不要立即连续重发。

以上都排查过仍然不通,可以联系 support@uberduck.ai。

版本与兼容性

主版本升级会带来破坏性变更,但会提前至少 6 个月公告。如果你的服务对稳定性要求高,建议在代码里固定使用 /v1 路径,并在公告期内规划迁移,而不是等到旧版本被弃用才动手。次版本和修订更新向后兼容,通常不需要改代码,但新功能可能只在新版本里出现。

音色与模型的可用性

音色分供应商音色、零样本音色、微调音色三类,后两类依赖你自己上传的音频样本,创建流程与文本转语音不同。文档没有给出各类音色的数量上限、训练时长或配额数字,实际可用范围以账号后台和接口返回为准。价格、可用音色数量、限流阈值这类信息会随时间调整,接入前请以官网当前信息为准。

音频地址的处理

接口返回的是 audio_url,不是音频二进制本身。这意味着你的应用需要能访问这个地址,或者把它下载到自己的存储里再对外提供。如果音频地址有有效期,务必在生成后尽快转存,不要长期依赖原始链接。文档没有说明链接的保留时长,涉及长期存档的场景建议自行落盘。