| 项目 | 值 |
|---|---|
| Base URL | https://api.kunxun.top/v2 |
| 鉴权方式 | 请求头 Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a 或 X-API-Key: 你的密钥 |
| 密钥获取 | 注册 zhenxun.kunxun.top 后,在「个人中心」复制(密钥以 kx_ 开头,长度 35 位) |
| 任务模式 | 异步:提交 → 返回 job_id → 轮询 GET /v2/jobs/{job_id} → 完成后拿下载 URL |
| 响应格式 | 成功 {"code": 0, ...};失败 {"status":"error","message":"..."} + HTTP 状态码 |
job_id、queue_position 排队位置),之后每秒或每 3 秒轮询一次 /v2/jobs/{job_id},等 status 变成 succeeded 后,用返回的 result.audio_url(或顶层 audio_url)直接下载即可。任务处理需要时间(CPU 推理),大文件人声分离可能要等几分钟,属正常排队。三种模式中,文本配音和音频变声需要指定模型,人声分离不需要模型。模型列表用下面这个接口拿(全部可用模型都会返回):
curl -s https://api.kunxun.top/v2/models \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
响应示例(返回 id 就是提交任务时要填的 model_id):
{
"code": 0,
"device": "cpu",
"models": [
{"id": "onimai_mahiro", "label": "绪山真寻", "backend": "rvc", "sampling_rate": 40000, "available": true},
{"id": "onimai_asahi", "label": "旭", "backend": "svc", "sampling_rate": 40000, "available": true},
{"id": "onimai_kaede", "label": "枫", "backend": "svc", "sampling_rate": 40000, "available": true},
{"id": "onimai_meiboli", "label": "美波里", "backend": "svc", "sampling_rate": 40000, "available": true},
{"id": "onimai_miyo", "label": "美夜", "backend": "svc", "sampling_rate": 40000, "available": true},
{"id": "onimai_momiji", "label": "椛", "backend": "svc", "sampling_rate": 40000, "available": true},
{"id": "onimai_zhenxun", "label": "真寻(SVC)", "backend": "svc", "sampling_rate": 40000, "available": true}
]
}
onimai_mahiro(RVC 声线);其余为 SVC 声线。别用模型文件名当 id(如 onimai_mahiro_gpu_e500_s41500 是文件不是 id),填错会返回「模型不存在」。POST /v2/tts异步 输入文字 + 模型 + 高级参数,输出目标角色朗读的语音。
请求体支持 JSON 和 multipart/form-data 两种格式(客户端按自己习惯选一种)。
| 参数 | 必填 | 默认 | 说明 / 可选值 |
|---|---|---|---|
| text | 是 | — | 要合成的文字,≤ 5000 字 |
| model_id | 是 | — | 角色模型 id,取自 GET /v2/models,如 onimai_mahiro |
| edge_voice | 否 | zh-CN-XiaoxiaoNeural | 朗读语音:zh-CN-XiaoxiaoNeural 晓晓(女) / zh-CN-YunxiNeural 云希(男) / zh-CN-XiaoyiNeural 晓伊(女) / zh-CN-YunjianNeural 云健(男) / ja-JP-NanamiNeural Nanami(日) |
| rate | 否 | +0% | 语速:-20% 慢20% / -10% 慢10% / +0% 正常 / +10% 快10% / +20% 快20% |
| pitch | 否 | +0Hz | 音调:-10Hz 低 / +0Hz 正常 / +10Hz 高 |
| transpose | 否 | 0 | 升降调(半音),整数,范围 -24 ~ 24。正数变高、负数变低 |
| f0_method | 否 | rmvpe | F0 基频算法:pm / rmvpe(推荐)/ dio / harvest / crepe / crepe-tiny / parselmouth |
curl -s -X POST https://api.kunxun.top/v2/tts \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
-H "Content-Type: application/json" \
-d '{
"text": "你好呀,我是真寻!今天也要加油哦。",
"model_id": "onimai_mahiro",
"edge_voice": "zh-CN-XiaoxiaoNeural",
"rate": "+0%",
"pitch": "+0Hz",
"transpose": 0,
"f0_method": "rmvpe"
}'
curl -s -X POST https://api.kunxun.top/v2/tts \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
-F "text=你好呀,我是真寻!今天也要加油哦。" \
-F "model_id=onimai_mahiro" \
-F "edge_voice=zh-CN-XiaoxiaoNeural" \
-F "rate=+0%" \
-F "pitch=+0Hz" \
-F "transpose=0" \
-F "f0_method=rmvpe"
{
"job_id": "61b05bbc69364cddad1d0daf9069ea4f",
"kind": "tts",
"status": "queued",
"stage": "等待中",
"progress": 0,
"queue_position": 1,
"queue_waiting": 1,
"model_id": "onimai_mahiro",
"model_name": "绪山真寻",
"message": "任务已加入队列",
"result": {}
}
POST /v2/convert异步 上传一段音频/视频,把里面的人声转换成目标角色声线。
注意:音频变声是文件上传,请求体必须是 multipart/form-data,不能是 JSON。
| 参数 | 必填 | 默认 | 说明 / 可选值 |
|---|---|---|---|
| audio | 是 | — | 音频文件(表单字段名 audio)。支持 wav/mp3/flac/m4a/ogg/aac/opus/aiff/wma/amr/ac3/ape;也支持视频 mp4/mov/avi/mkv/flv 等(自动提取音轨) |
| model_id | 是 | — | 角色模型 id,如 onimai_mahiro |
| transpose | 否 | 0 | 升降调(半音),整数,范围 -24 ~ 24 |
| f0_method | 否 | rmvpe | F0 算法:pm / rmvpe(推荐)/ dio / harvest / crepe / crepe-tiny / parselmouth |
curl -s -X POST https://api.kunxun.top/v2/convert \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
-F "audio=@/path/to/input.mp3" \
-F "model_id=onimai_mahiro" \
-F "transpose=0" \
-F "f0_method=rmvpe"
{
"job_id": "9c2e4f1a8b3d4c5e9f0a1b2c3d4e5f60",
"kind": "convert",
"status": "queued",
"stage": "等待中",
"progress": 0,
"queue_position": 1,
"queue_waiting": 0,
"model_id": "onimai_mahiro",
"model_name": "绪山真寻",
"message": "任务已加入队列",
"result": {}
}
POST /v2/separate异步 上传一段混合音频,分离出人声轨和伴奏轨。
特殊:人声分离不需要选模型!它跟角色声线无关,只做「人声 / 伴奏」拆分,所以参数里没有 model_id。
| 参数 | 必填 | 默认 | 说明 / 可选值 |
|---|---|---|---|
| audio | 是 | — | 音频/视频文件(表单字段名 audio),支持格式同上 |
| strength | 否 | 0.85 | 分离强度,小数,范围 0.15 ~ 1.0。越大分离越干净,但可能损失细节;一般 0.85 即可 |
curl -s -X POST https://api.kunxun.top/v2/separate \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
-F "audio=@/path/to/song.mp3" \
-F "strength=0.85"
{
"job_id": "7d8e9f0a1b2c3d4e5f60718293a4b5c6d",
"kind": "separate",
"status": "queued",
"stage": "等待中",
"progress": 0,
"queue_position": 1,
"queue_waiting": 0,
"model_id": "onimai_mahiro",
"model_name": "绪山真寻",
"message": "任务已加入队列",
"result": {}
}
result.vocals_url 是人声轨、result.background_url 是伴奏轨,两个都可以下载。人声分离是最重的任务(大文件几分钟),务必控制上传体积。GET /v2/jobs/{job_id}需密钥 用提交时返回的 job_id 轮询。建议每 2~3 秒查一次,直到 status 变为 succeeded 或 failed。
状态含义:queued 排队中 / running 处理中(progress 是百分比,stage 是当前阶段描述)/ succeeded 完成 / failed 失败(看 message)。
curl -s https://api.kunxun.top/v2/jobs/61b05bbc69364cddad1d0daf9069ea4f \
-H "Authorization: Bearer z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a" \
{
"job_id": "61b05bbc69364cddad1d0daf9069ea4f",
"kind": "tts",
"status": "succeeded",
"stage": "完成",
"progress": 100,
"elapsed_seconds": 16.85,
"model_id": "onimai_mahiro",
"model_name": "绪山真寻",
"message": "绪山真寻配音生成完成",
"result": {
"audio_url": "https://api.kunxun.top/outputs/61b05bbc69364cddad1d0daf9069ea4f.onimai_mahiro.tts.wav",
"vocals_url": null,
"background_url": null,
"duration_seconds": 1.88,
"model_id": "onimai_mahiro",
"model_name": "绪山真寻"
},
"audio_url": "https://api.kunxun.top/outputs/61b05bbc69364cddad1d0daf9069ea4f.onimai_mahiro.tts.wav"
}
| 模式 | 成功后拿哪个字段 | 说明 |
|---|---|---|
| 文本配音 | result.audio_url 或 audio_url | 最终配音 WAV |
| 音频变声 | result.audio_url 或 audio_url | 转换后 WAV |
| 人声分离 | result.vocals_url(人声)+ result.background_url(伴奏) | 两条轨分开下载 |
import time
import urllib.request, json
KEY = "z7xQm2Lv8pR4tN6wB3cF9hJ1sD5gH0a"
BASE = "https://api.kunxun.top/v2"
def poll(job_id, timeout=600):
url = BASE + "/jobs/" + job_id
req = urllib.request.Request(url, headers={"Authorization": "Bearer " + KEY})
start = time.time()
while time.time() - start < timeout:
with urllib.request.urlopen(req, timeout=30) as resp:
data = json.loads(resp.read().decode())
if data["status"] in ("succeeded", "failed", "error"):
return data
time.sleep(3)
raise TimeoutError("任务超时")
| HTTP | 错误 message | 原因 / 处理 |
|---|---|---|
| 401 | Invalid or missing API key | 密钥没传、格式不对或已失效。检查 Authorization: Bearer 头 |
| 403 | 无权查看该任务 | job_id 不属于当前密钥对应的账号 |
| 404 | 任务不存在或已过期 | job_id 拼错,或任务已清理 |
| 404 | 模型不存在 | model_id 填错。用 GET /v2/models 拿真实 id |
| 400 | 文字太长 / 请输入要合成的文字 | text 为空或超过 5000 字 |
| 400 | 不支持的格式 | 上传文件扩展名不在支持列表 |
| 400 | 上传音频为空 | 上传了空文件 |
| 429 | 今日配额已用完 | 每天有配额上限(GET /v2/me 可查 used/limit),明天再试 |
| 422 | validation error | 参数类型不对(如 transpose 传了非数字) |
https://api.kunxun.top/v2(不是 /v2/)