前言说明
在数字化浪潮席卷全球的时代,语音交互正以前所未有的速度融入我们的生活与工作场景,从智能客服到有声内容创作,从导航语音播报再到教育场景的语言学习,优质、高效的语音合成技术成为了推动行业创新发展的关键力量。云音工坊深度洞察市场需求,依托 Fish Speech 先进的语音合成技术,致力于为用户提供专业、精准且极具表现力的语音合成功能。我们凭借强大的技术研发实力,基于 Fish Speech 技术开发了专属 API 接口,不仅能满足用户多样化的语音合成需求,还为开发者提供了便捷接入的渠道,助力各行业轻松实现语音交互升级,解锁智能语音应用的无限可能。
使用说明
语音合成
接口地址
https://www.yuntts.com/api/v1/cloning
请求头
// JSON 格式
Content-Type: application/json
Authorization: Bearer API-KEY // API密钥
注意:秘钥请登录后前往 https://www.yuntts.com/user/api/ 生成,接口秘钥支持访问本站所有接口服务!
请求参数
{
"model_id": string, // 必填,模型ID
"text": string, // 必填,要转换的文本
"speed": number, // 可选,语速,范围:0.5-2.0,默认:1
"volume": number, // 可选,音量,范围:-20-20,默认:0
"version": string, // 可选,TTS版本,可选值:"v1"或"v2",默认:"v1"
"cache": boolean // 可选,是否缓存音频并返回URL,默认:false
}
示例
{
"reference_id": "25129630-581c-4cd8-9fa1-12199fcc9f0b",
"text": "云音工坊测试文本",
"speed": 1,
"volume": 0,
"version": "v1",
"cache": true
}
请求参数说明
参数名称 | 是否必填 | 参数类型 | 参数说明 | 默认值 | 取值范围/可选值 |
---|---|---|---|---|---|
model_id | 必填 | string | 模型ID | - | - |
text | 必填 | string | 要转换的文本 | - | - |
speed | 可选 | number | 语速 | 1 | 0.5 - 2.0 |
volume | 可选 | number | 音量 | 0 | -20 - 20 |
version | 可选 | string | TTS版本 | "v1" | "v1" 或 "v2" |
cache | 可选 | boolean | 是否缓存音频并返回URL | false | true 或 false |
返回数据
如过开启缓存返回
{
"code": 200,
"msg": "合成成功",
"audio_url": "https://www.yuntts.com/wp-content/uploads/2025/05/682724acaaf55_1747395756.mp3",
"format": "mp3",
"characters_used": 8,
"price": 0.01,
"quota_remaining": 184.7715
}
返回参数说明
参数名称 | 参数类型 | 参数说明 | 示例值 |
---|---|---|---|
code | number | 状态码 | 200 |
success | boolean | 请求是否成功 | true |
audio_url | string | 生成的音频文件URL | https://www.yuntts.com/wp-content/uploads/2025/05/6827182c06ce0_1747392556.mp3 |
format | string | 音频格式 | mp3 |
characters_used | number | 本次请求消耗的字符数 | 40 |
price | number | 本次请求的费用 | 0.05 |
quota_remaining | number | 剩余可用额度 | 184.7815 |
如过关闭缓存返回
Content-Type: audio/mpeg
<二进制音频数据>
注意:返回二进制音频数据需要自己在客户端处理!
错误处理
HTTP状态码 | 触发条件 | 错误代码 | 响应示例 |
---|---|---|---|
400 | 缺少必要参数或参数格式错误 | invalid_parameters | { "error": "invalid_parameters", "msg": "缺少必要参数" } |
400 | 音量值超出-20~20范围 | invalid_volume | { "error": "invalid_volume", "msg": "音量值超出范围" } |
401 | API密钥无效或过期 | invalid_key | { "code": 401, "msg": "API密钥无效或已过期" } |
403 | 用户权限不足 | forbidden | { "code": 403, "msg": "操作未授权" } |
429 | 用户余额不足 | insufficient_balance | { "code": 429, "error": "insufficient_balance", "msg": "用户余额不足" } |
500 | 服务器配置异常 | server_config_error | { "code": 500, "error": "server_config_error", "msg": "服务端配置异常" } |
模型克隆
接口地址
http://www.yuntts.com/wp-json/api/v1/cloning-model
请求头
Content-Type: multipart/form-data
Authorization: Bearer YOUR_API_TOKEN // API密钥
注意:秘钥请登录后前往 https://www.yuntts.com/user/api/ 生成,接口秘钥支持访问本站所有接口服务!
请求参数
{
"name": "解说大神",
"description": "云音工坊测试",
"audioFile": "default.mp3"
}
请求参数说明
字段名 | 类型 | 必填性 | 说明 |
---|---|---|---|
name |
string | 必填 | 模型名称 |
description |
string | 可选 | 模型描述(非必填,可留空或填写简要说明) |
audioFiles |
File | 必填 | 音频文件,支持格式:wav/mp3(需上传文件,文件名为具体路径或文件名) |
返回参数
{
"code": 200,
"msg": "模型创建成功",
"modelId": "7ef46f62-fe18-4c47-9948-d8861134e649",
"title": "解说大神",
"createdAt": "2025-05-17 04:43:50",
"quota_remaining": 184.6015
}
参考代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>语音模型创建</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
.file-upload {
border: 2px dashed #dee2e6;
border-radius: 0.375rem;
padding: 2rem;
text-align: center;
}
.progress {
height: 1.5rem;
margin-top: 1rem;
}
</style>
</head>
<body>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<h2 class="mb-4">创建语音克隆模型</h2>
<!-- 错误提示 -->
<div class="alert alert-danger d-none" id="errorAlert"></div>
<form id="modelForm">
<!-- 模型名称 -->
<div class="mb-3">
<label class="form-label">模型名称 *</label>
<input type="text" class="form-control" name="name" required>
</div>
<!-- 模型描述 -->
<div class="mb-3">
<label class="form-label">模型描述</label>
<textarea class="form-control" name="description" rows="3"></textarea>
</div>
<!-- 文件上传 -->
<div class="mb-3">
<label class="form-label">音频文件 *</label>
<div class="file-upload">
<input type="file" class="form-control" name="audioFiles" accept=".wav,.mp3" required>
<small class="text-muted d-block mt-2">支持格式:WAV/MP3,最大4MB</small>
<div class="invalid-feedback" id="fileError"></div>
</div>
</div>
<button type="submit" class="btn btn-primary w-100">
<span class="spinner-border spinner-border-sm d-none" role="status"></span>
提交创建
</button>
</form>
<!-- 结果展示 -->
<div class="mt-4 card d-none" id="resultCard">
<div class="card-body">
<h5 class="card-title">创建成功</h5>
<ul class="list-unstyled">
<li>模型ID: <span id="modelId"></span></li>
<li>创建时间: <span id="createdAt"></span></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
document.getElementById('modelForm').addEventListener('submit', async (e) => {
e.preventDefault();
const form = e.target;
const submitBtn = form.querySelector('button[type="submit"]');
const spinner = submitBtn.querySelector('.spinner-border');
const fileInput = form.querySelector('input[type="file"]');
// 重置状态
document.getElementById('errorAlert').classList.add('d-none');
spinner.classList.remove('d-none');
submitBtn.disabled = true;
try {
// 前端验证
if (!fileInput.files[0]) {
throw new Error('请选择音频文件');
}
const file = fileInput.files[0];
if (!['audio/wav', 'audio/mpeg', 'audio/mp3'].includes(file.type)) {
throw new Error('仅支持WAV/MP3格式');
}
if (file.size > 4 * 1024 * 1024) {
throw new Error('文件大小超过4MB限制');
}
// 构建FormData
const formData = new FormData();
formData.append('name', form.name.value);
formData.append('description', form.description.value);
formData.append('audioFiles', file);
// 添加请求参数日志
console.log('提交表单参数:', {
name: form.name.value,
description: form.description.value,
audioFile: file.name
});
// 发送请求
const response = await fetch('/wp-json/api/v1/cloning-model', {
method: 'POST',
headers: {
'Authorization': `Bearer 68985a242e655fb2d0194dfb478f1f76`,
// 移除手动设置的Content-Type头,浏览器会自动生成正确的boundary
},
body: formData
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.msg || '请求失败');
}
// 显示结果
document.getElementById('resultCard').classList.remove('d-none');
document.getElementById('modelId').textContent = result.modelId;
document.getElementById('createdAt').textContent = result.createdAt;
form.reset();
} catch (error) {
const errorAlert = document.getElementById('errorAlert');
errorAlert.textContent = error.message;
errorAlert.classList.remove('d-none');
} finally {
spinner.classList.add('d-none');
submitBtn.disabled = false;
}
});
</script>
</body>
</html>
curl -X POST "http://yourdomain.com/wp-json/api/v1/cloning-model" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "name=示例模型" \
-F "description=模型描述信息" \
-F "audioFiles=@/path/to/audio.wav"
import requests
url = "http://yourdomain.com/wp-json/api/v1/cloning-model"
headers = {
"Authorization": "Bearer YOUR_API_KEY"
}
files = {
"audioFiles": open("/path/to/audio.wav", "rb")
}
data = {
"name": "示例模型",
"description": "模型描述信息"
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
获取模型
接口地址
https://www.yuntts.com/api/v1/fetch-model
请求头
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN // API密钥
请求参数
{
"page": 1,//页面
"page_size": 20,//每页条数
"includePersonal": false//是否包含个人模型
}
返回参数
{
"total": 65,
"page": 1,
"pageSize": 70,
"totalPages": 1,
"data": [
{
"modelId": "fb215435-9cf1-4141-a938-d05e85c064ee",
"modelName": "奶龙",
"description": "小朋友们,准备好迎接奶龙的魔法了吗?",
"gender": "male",
"scene_type": "general",
"demoAudioUrl": "https://www.yuntts.com/audio/nailong.mp3",
"avatarUrl": "/wp-content/themes/360mb-v5/assets/tts/avatar/nailong.webp",
"createdAt": "2024-10-09 02:44:08",
"updatedAt": "2025-05-09 22:25:53",
"isPersonal": false
},
{
"modelId": "ff66d8d5-818f-43a8-9b6b-7936b6e75900",
"modelName": "女主播大白兔",
"description": "大家好,我是大白兔,欢迎进入我的直播间!",
"gender": "male",
"scene_type": "general",
"demoAudioUrl": "https://www.yuntts.com/audio/nvzhubodabaitu.mp3",
"avatarUrl": "/wp-content/themes/360mb-v5/assets/tts/avatar/dabaitu.webp",
"createdAt": "2025-01-16 12:28:39",
"updatedAt": "2025-05-09 22:24:57",
"isPersonal": true
}
]
}
返回参数说明
字段名 | 类型 | 描述 | 示例值 |
---|---|---|---|
total | int | 总记录数 | 65 |
page | int | 当前页码 | 1 |
pageSize | int | 每页记录数 | 70 |
totalPages | int | 总页数 | 1 |
data[].modelId | string | 模型唯一标识(UUID格式) | fb215435-9cf1-4141-a938-d05e85c064ee |
data[].modelName | string | 模型显示名称 | 奶龙 |
data[].description | string | 模型描述文本 | 小朋友们,准备好迎接奶龙的魔法了吗? |
data[].gender | string | 语音性别类型(male/female) | male |
data[].demoAudioUrl | string | 演示音频URL地址 | mp3地址 |
data[].avatarUrl | string | 模型头像路径(相对/绝对) | 头像地址 |
data[].isPersonal | bool | 是否个人模型 | false |
参考代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>模型查询接口调试</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container py-4">
<h3 class="mb-4">克隆模型查询接口调试</h3>
<form id="queryForm" class="mb-4">
<div class="row g-3">
<div class="col-md-3">
<label class="form-label">页码</label>
<input type="number" class="form-control" id="page" name="page" min="1" value="1" required>
<div class="invalid-feedback">页码必须≥1</div>
</div>
<div class="col-md-3">
<label class="form-label">每页条数</label>
<input type="number" class="form-control" id="page_size" name="page_size" min="1" max="100" value="20" required>
<div class="invalid-feedback">1-100之间</div>
</div>
<div class="col-md-6">
<div class="form-check form-switch mt-4 pt-2">
<input class="form-check-input" type="checkbox" role="switch" id="includePersonal">
<label class="form-check-label" for="includePersonal">包含个人模型</label>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary mt-3">查询</button>
</form>
<div class="card">
<div class="card-header">响应结果</div>
<div class="card-body p-0">
<textarea id="responseArea" class="form-control" style="height:400px; font-family: monospace" readonly></textarea>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
document.getElementById('queryForm').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = {
page: parseInt(document.getElementById('page').value),
page_size: parseInt(document.getElementById('page_size').value),
includePersonal: document.getElementById('includePersonal').checked
};
console.log('请求参数:', JSON.stringify(formData, null, 2));
try {
const response = await fetch('https://www.yuntts.com/api/v1/fetch-model', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer 68985a242e655fb2d0194dfb478f1f76`,
},
body: JSON.stringify(formData)
});
const result = await response.json();
document.getElementById('responseArea').value = JSON.stringify(result, null, 4);
if (!response.ok) {
alert(`请求失败: ${result.error || result.msg}`);
}
} catch (error) {
console.error('请求失败:', error);
document.getElementById('responseArea').value = `网络错误: ${error.message}`;
}
});
</script>
</body>
</html>
curl -X POST "https://www.yuntts.com/api/v1/fetch-model" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key_here" \
-d '{
"page": 2,
"pageSize": 30,
"includePersonal": true
}'
删除模型
接口地址
http://www.yuntts.com/wp-json/api/v1/cloning-delete
请求头
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN // API密钥
请求参数
{
"modelId": string // 必填,要删除的模型ID
}
返回数据
{
"code": 200,
"msg": "模型删除成功",
"modelId": "7ef46f62-fe18-4c47-9948-d8861134e649",
"quota_remaining": 184.6015
}
参考代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>删除语音模型</title>
<link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body class="bg-light">
<div class="container py-5">
<div class="card shadow-sm">
<div class="card-header bg-danger text-white">
<h3 class="mb-0">删除语音模型</h3>
</div>
<div class="card-body">
<form id="deleteForm">
<div class="mb-3">
<label for="modelId" class="form-label">模型ID</label>
<input type="text" class="form-control" id="modelId" required>
<div class="form-text text-muted">请输入要删除的模型ID</div>
</div>
<button type="submit" class="btn btn-danger">删除模型</button>
</form>
<div id="resultAlert" class="mt-4 d-none">
<div class="alert alert-dismissible fade show">
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<span class="alert-message"></span>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('#deleteForm').submit(function(e) {
e.preventDefault();
const modelId = $('#modelId').val().trim();
if (!modelId) {
showAlert('请输入有效的模型ID', 'danger');
return;
}
$.ajax({
url: '/wp-json/api/v1/cloning-delete',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer 68985a242e655fb2d0194dfb478f1f76`,
},
data: JSON.stringify({ modelId: modelId }),
success: function(response) {
if (response.code === 200) {
showAlert(`${response.message} 剩余额度:${response.quota_remaining}`, 'success');
} else {
showAlert(response.msg || '操作失败', 'warning');
}
},
error: function(xhr) {
const error = xhr.responseJSON || {};
showAlert(error.msg || '服务器错误,请稍后再试', 'danger');
}
});
});
function showAlert(message, type) {
const $alert = $('#resultAlert').removeClass('d-none').find('.alert');
$alert.removeClass('alert-success alert-danger alert-warning')
.addClass(`alert-${type}`)
.find('.alert-message').text(message);
}
});
</script>
</body>
</html>
curl -X POST https://fishspeech.net/api/open/delete-model \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"modelId": "your_model_id"
}
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)