在开发交互式音乐应用、游戏 NPC 实时演唱或虚拟主播(VTuber)音频生成系统时,许多工程师和创意技术人员常受限于网页端的手动操作界面:基于浏览器的生成模式无法嵌入自动化流水线,也无法承受高并发与自动化批处理。Uberduck 提供了官方 REST API,使开发者能够直接在代码中程序化合成具有节奏感和旋律感的声音资产。
要在后端成功集成 Uberduck API 来生成唱歌与说唱人声,主要涵盖三个关键架构层:HTTP Basic 鉴权、选择适配的合成模式(基于节奏对齐的 /tts/freestyle 端点、参数化音高时间轴 /speak 或声音转换 /tts/convert),以及基于 /speak-status 的高并发异步任务轮询机制。
1. 鉴权机制与请求架构
Uberduck 官方 REST API 采用标准的 HTTP Basic Authentication 协议。开发者需要将控制台获取的 API Key(作为用户名)与 API Secret(作为密码)合并并进行 Base64 编码,放入 HTTP 请求头中。
鉴权请求头构建
- 在 Uberduck 账号设置中生成
API Key与API Secret。 - 构造 HTTP
Authorization请求头:Authorization: Basic base64(API_KEY:API_SECRET) - API 基础端点地址为
https://api.uberduck.ai。
import base64
import os
API_KEY = os.getenv("UBERDUCK_API_KEY", "your_api_key")
API_SECRET = os.getenv("UBERDUCK_API_SECRET", "your_api_secret")
def get_auth_headers():
token = base64.b64encode(f"{API_KEY}:{API_SECRET}".encode("utf-8")).decode("utf-8")
return {
"Authorization": f"Basic {token}",
"Content-Type": "application/json"
}
2. 三种核心人声合成模式对比
针对说唱歌词与旋律歌唱的不同场景,Uberduck 提供了三种实现路径:
| 合成模式 | 核心端点 | 关键参数 | 适用场景 |
|---|---|---|---|
| 文本到说唱(Freestyle) | POST /tts/freestyle | lyrics, bpm, backing_track, voice 或 voicemodel_uuid | 生成具有节拍卡点的说唱音频;互动式即兴饶舌;动态定制歌词管线 |
| 参数化音高与时长合成 | POST /speak | speech, voicemodel_uuid, pitch, duration, pace | 依照 MIDI 或旋律简谱精确驱动音高曲线与音素长度的乐曲合成 |
| 声音转换(Voice-to-Voice) | POST /tts/convert | voicemodel_uuid, input(音频 URL), pitch_shift | 富有自然颤音与滑音的旋律歌唱;以导唱音频或合成器音轨为基准转换音色 |
3. 构建端到端程序化说唱合成管线
/tts/freestyle 是专门为说唱设计的端点,其底层模型能根据节拍速度(BPM)和伴奏音轨结构自动吸附押韵节拍。
步骤 1:查询官方伴奏库
如果希望人声与官方伴奏精准匹配,可先获取预置伴奏列表:
import requests
def list_backing_tracks():
url = "https://api.uberduck.ai/reference-audio/backing-tracks?detailed=true"
response = requests.get(url, headers=get_auth_headers())
response.raise_for_status()
return response.json() # 返回包含伴奏 UUID、BPM 与风格元数据的列表
步骤 2:(可选)自动生成押韵歌词
若应用包含“根据主题生成即兴说唱”的逻辑,可通过 /tts/lyrics 调用歌词生成接口(或自建大模型生成二维字符串数组格式):
def generate_lyrics(subject, lines=4):
url = "https://api.uberduck.ai/tts/lyrics"
payload = {
"subject": subject,
"lines": lines
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json() # 返回结构化歌词行
步骤 3:发起 Freestyle 异步生成请求
将结构化歌词矩阵(以二维数组划分段落与单句)、目标 BPM、伴奏 UUID 以及声音模型参数提交给 API:
def generate_rap_vocal(lyrics_matrix, bpm=90, backing_track_uuid=None, voice="zwf"):
url = "https://api.uberduck.ai/tts/freestyle"
payload = {
"lyrics": lyrics_matrix, # 例如:[["代码在终端翻滚节拍永不停歇", "函数调用人声在音轨穿梭"]]
"bpm": bpm,
"voice": voice,
"format": "json"
}
if backing_track_uuid:
payload["backing_track"] = backing_track_uuid
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
data = response.json()
return data["uuid"] # 返回异步任务 UUID
4. 配置音高时间轴与旋律歌唱人声
与注重节奏卡点的说唱不同,旋律性歌唱对连续音高和音素持续时长有极高要求。Uberduck 提供了两种实现思路:
方案 A:通过 /speak 控制音高曲线与音素长度
在支持细粒度控制的声音模型中(可通过 GET /voices/{voicemodel_uuid}/detail 检查响应中的 controls: true),/speak 允许传入 pitch(音高数组)和 duration(时长数组):
def generate_singing_notes(speech_text, voicemodel_uuid, pitch_curve, duration_curve):
"""
pitch_curve: 对应每个音素的目标基频或半音值的数值数组
duration_curve: 对应每个音素持续时间的数值数组
"""
url = "https://api.uberduck.ai/speak"
payload = {
"speech": speech_text,
"voicemodel_uuid": voicemodel_uuid,
"pitch": pitch_curve,
"duration": duration_curve,
"pace": 1.0
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json()["uuid"]
方案 B:利用声音转换(V2V)生成工业级自然歌声
直接计算音素级别的音高和时长曲线难度较高,且容易产生机械感。工业级音乐产品中更通用的做法是采用 Voice-to-Voice(声音转换):
先用轻量级 MIDI 歌唱合成器(如纯净导唱音)或真人录制一条基础导唱,然后通过 POST /tts/convert 接口替换为人气音色,并通过 pitch_shift 进行半音移调:
def convert_guide_vocal_to_singer(guide_audio_url, target_voice_uuid, semitone_shift=0):
url = "https://api.uberduck.ai/tts/convert"
payload = {
"input": guide_audio_url,
"voicemodel_uuid": target_voice_uuid,
"pitch_shift": semitone_shift
}
response = requests.post(url, json=payload, headers=get_auth_headers())
response.raise_for_status()
return response.json()["uuid"]
5. 异步生命周期与高并发轮询机制
音频神经网络推理消耗大量算力,无法在单一 HTTP 短连接内即时返回。每次提交任务后,API 会返回一个异步任务 ID(uuid)。后台需要建立具备超时与指数退避机制的轮询器:
import time
def poll_render_completion(job_uuid, max_attempts=30, delay_seconds=2):
status_url = f"https://api.uberduck.ai/speak-status?uuid={job_uuid}"
headers = get_auth_headers()
for attempt in range(max_attempts):
response = requests.get(status_url, headers=headers)
response.raise_for_status()
data = response.json()
# 异常失败检测
if data.get("failed_at"):
raise RuntimeError(f"音频合成任务失败:{data}")
# 成功完成检测
if data.get("finished_at"):
audio_url = data.get("path")
return audio_url # 渲染完毕的 CDN 存储地址
time.sleep(delay_seconds)
raise TimeoutError("合成任务超时未完成。")
6. 端到端可执行脚本示例
以下是一份完整的端到端 Python 脚本,涵盖了请求鉴权、任务提交、状态轮询与音频落盘全流程:
import requests
import base64
import time
import os
UBERDUCK_API_KEY = os.getenv("UBERDUCK_API_KEY")
UBERDUCK_API_SECRET = os.getenv("UBERDUCK_API_SECRET")
HEADERS = {
"Authorization": f"Basic {base64.b64encode(f'{UBERDUCK_API_KEY}:{UBERDUCK_API_SECRET}'.encode()).decode()}",
"Content-Type": "application/json"
}
def create_rap_track(lyrics, bpm=95, voice="zwf", output_file="vocal_output.wav"):
# 1. 提交说唱生成任务
print("正在提交人声合成请求...")
freestyle_url = "https://api.uberduck.ai/tts/freestyle"
payload = {
"lyrics": lyrics,
"bpm": bpm,
"voice": voice,
"format": "json"
}
resp = requests.post(freestyle_url, json=payload, headers=HEADERS)
resp.raise_for_status()
task_id = resp.json()["uuid"]
print(f"任务已创建,UUID: {task_id}")
# 2. 轮询任务状态
status_url = f"https://api.uberduck.ai/speak-status?uuid={task_id}"
audio_url = None
for _ in range(40):
time.sleep(2)
status_resp = requests.get(status_url, headers=HEADERS)
status_resp.raise_for_status()
status_data = status_resp.json()
if status_data.get("failed_at"):
raise RuntimeError("服务端处理任务失败。")
if status_data.get("finished_at"):
audio_url = status_data.get("path")
print(f"音频生成完成,下载地址: {audio_url}")
break
if not audio_url:
raise TimeoutError("渲染耗时超过 80 秒,已中止。")
# 3. 下载并持久化音频
audio_data = requests.get(audio_url).content
with open(output_file, "wb") as f:
f.write(audio_data)
print(f"音频已保存至: {output_file}")
return output_file
if __name__ == "__main__":
bars = [
["启动生成管线代码注入旋律节奏", "全自动化处理告别人工剪辑操作"],
["节拍咬字分毫不差端点持续响应", "Uberduck API 驱动音乐应用全新进化"]
]
create_rap_track(lyrics=bars, bpm=95)
7. 生产环境工程建议与权衡
在将 Uberduck API 部署至商业化生产环境时,应注意以下工程细节:
- 音节密度与 BPM 匹配:歌词单句的音节数量应与设定速度协调。如果 BPM 超过 110 且歌词过于密集,语音合成模型容易出现吞字、发音破损或爆音现象。
- 任务队列解耦:从提交到返回音频通常需要 4 到 15 秒。在对外提供 Web 接口时,切勿在 HTTP 请求主线程中同步阻塞等待,应结合 Celery、BullMQ 或 Kafka 等异步任务队列处理。
- 商用授权与套餐门槛:API 调用通常需要订阅 Pro 或 Enterprise 等商业级别方案。免费版不仅调用量受限,通常也不包含合法的商业发表授权。
- 音频后处理增强:API 输出的通常是干燥人声(Dry Stem)。在最终混音时,建议使用 FFmpeg 或专业音频处理微服务叠加混响(Reverb)、均衡(EQ)和动态压缩,以实现商业级发布听感。
参考资料
- Uberduck API Documentation
- Generate Freestyle - Uberduck Text To Speech API
- Generate Lyrics - Uberduck Text To Speech API
- Generate Speech - Uberduck Text To Speech API
- Voice To Voice Conversion - Uberduck Text To Speech API
- Get text-to-speech request status - Uberduck Text To Speech API
- List Backing Tracks - Uberduck Text To Speech API
- Uberduck AI Pricing and Plans