关于 venice-audio-music
venice-audio-music 是通过 Venice 异步音频 API 生成音乐、音效和较长语音内容的 Skill。它适合需要先估价、提交生成任务、获取结果并清理存储媒体的开发者。
主要功能
- 01提交前查询生成价格
- 02排队处理异步音频任务
- 03生成音乐、音效和语音
- 04轮询任务并获取音频数据
- 05获取后删除存储媒体
适用场景
- 01制作歌曲或短曲
- 02生成音效和声景
- 03制作长篇旁白
- 04音频生成前核算费用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ veniceai/ skills --skill venice-audio-music安装后在 Claude Code 中输入/venice-audio-music确认已加载。
详细介绍
Venice 音乐 / 异步音频
音乐、音效和按字符计价的语音生成均为异步:
| 方法 | 路径 | 身份验证 | 说明 |
|---|---|---|---|
POST | /api/v1/audio/quote | 无需身份验证(密钥可选) | 价格以 USD 计。 |
POST | /api/v1/audio/queue | Bearer 密钥或 x402 (SIWX) | 扣费并加入队列 → queue_id。每位用户每分钟 40 次请求。 |
POST | /api/v1/audio/retrieve | Bearer 密钥或 x402 (SIWX) | 状态 JSON 或音频字节。每位用户每分钟 120 次请求。 |
POST | /api/v1/audio/complete | Bearer 密钥或 x402 (SIWX) | 删除已存储的媒体。 |
对于较短的同步文本转语音,请使用 venice-audio-speech。这些端点会拒绝语音转换(语音转语音)模型,并返回指向 /audio/voice-changer/* 的 400(无法查看该模型的调用方会收到 404)——参见 venice-audio-voice-changer。
适用场景
- 你需要歌曲、短曲、配乐、音景、音效或长篇旁白。
- 模型按时长、每秒、每项任务或字符计价,而且你希望在提交前先了解价格。
- 生成耗时较长,同步调用可能会超时。
模型
查询 GET /models?type=music,获取当前列表以及每个模型的 model_spec。以下是代表性 ID(均在实时列表中):
| 类型 | 示例 |
|---|---|
| 纯音乐 / 歌曲 | elevenlabs-music、elevenlabs-music-v2-5、lyria-3-pro、sonilo-v1-1-music、stable-audio-25 |
| 带歌词的歌曲 | minimax-music-v25、minimax-music-v26、minimax-music-v2(必须提供歌词)、ace-step-15(可选歌词) |
| 音效 | elevenlabs-sound-effects-v2(支持 loop)、sonilo-v1-1-sound-effects、mmaudio-v2-text-to-audio |
语音(文本放在 prompt 中) | elevenlabs-tts-v4、elevenlabs-tts-v4-turbo、elevenlabs-tts-v3、elevenlabs-tts-multilingual-v2、seed-audio-1-0 |
生命周期
1. POST /audio/quote — 先查询价格
curl https://api.venice.ai/api/v1/audio/quote \
-H "Content-Type: application/json" \
-d '{ "model": "elevenlabs-music", "duration_seconds": 60 }'
响应:{"quote": 0.69}(USD)。无需 API 密钥;提供密钥后,才能查询仅你的账户可见的模型价格。
| 字段 | 说明 |
|---|---|
model | 必填。 |
duration_seconds | 整数或数字字符串。仅适用于公开时长元数据(min_duration / max_duration / duration_options)的模型——否则会被拒绝。省略时,按模型的 default_duration 计价。 |
character_count | 小于或等于 prompt_character_limit 的整数。按 per_thousand_characters 计价的模型必须提供。 |
未知字段 → 400。
2. POST /audio/queue — 入队
curl https://api.venice.ai/api/v1/audio/queue \
-H "Authorization: Bearer $VENICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "elevenlabs-music",
"prompt": "Uplifting indie-folk acoustic track, 120 BPM, major key.",
"duration_seconds": 60,
"force_instrumental": true
}'
带歌词的歌曲(minimax-music-v25 支持歌词、歌词优化器和纯音乐模式,但不支持 duration_seconds):
{
"model": "minimax-music-v25",
"prompt": "Warm indie-pop ballad, female vocals, acoustic guitar.",
"lyrics_prompt": "[Verse]\nWalking through the city lights...\n[Chorus]\nWe are the dreamers..."
}
响应:{ "model": "...", "queue_id": "...", "status": "QUEUED" }。
请求体采用严格校验:当模型的 model_spec 表明不支持以下可选字段时,传入这些字段都会被拒绝并返回 400。
| 字段 | 说明 |
|---|---|
model | 必填。 |
prompt | 必填。长度介于 min_prompt_length(默认值为 10)和 prompt_character_limit 之间;会先去除首尾空白。对于语音模型,这是要朗读的文本。 |
lyrics_prompt | 最多为 lyrics_character_limit(默认值为 4096)个字符。lyrics_required=true 时必填;supports_lyrics=false 时会被拒绝。 |
duration_seconds | 整数或数字字符串。传入时必须是 duration_options 中的值,否则必须在 min_duration–max_duration 范围内。默认为 default_duration。 |
force_instrumental | 仅当 supports_force_instrumental=true 时支持。 |
lyrics_optimizer | 根据 prompt 自动撰写歌词。仅当 supports_lyrics_optimizer=true 时支持;此时 lyrics_prompt 必须为空。 |
loop | 渲染无缝循环音频(结尾衔接开头)。仅当 supports_loop=true 时支持——目前仅适用于 elevenlabs-sound-effects-v2。 |
voice | 仅适用于支持语音的模型。必须是 voices 中的值;默认为 default_voice。支持 supports_custom_voice_id=true 的模型(ElevenLabs TTS 模型)也接受原始 ElevenLabs Voice ID。 |
language_code | ISO 639-1。仅当 supports_language_code=true 时支持——当前列表中的模型均未设置此项。 |
speed | 仅当 supports_speed=true 时支持,且必须在 min_speed–max_speed 范围内。 |
此外还适用特定于模型的规则:minimax-music-v25 要求 lyrics_prompt 至少包含 10 个字符,除非 force_instrumental 或 lyrics_optimizer 为 true;minimax-music-v26 也有相同要求,但仅在 force_instrumental 为 true 时例外;minimax-music-v2 要求 lyrics_prompt 非空白。
3. POST /audio/retrieve — 轮询 / 下载
curl https://api.venice.ai/api/v1/audio/retrieve \
-H "Authorization: Bearer $VENICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"elevenlabs-music","queue_id":"..."}' \
--output track.mp3
- 仍在运行:返回
200JSON{"status":"PROCESSING","average_execution_time":<ms, P80 estimate>,"execution_duration":<ms since queued>}。 - 已完成:返回
200和音频字节。Content-Type为音频类型;响应头包括x-venice-audio-format、x-venice-inference-time(秒)、x-venice-model-id、x-venice-model-name;对于 Seed Audio,还包括x-venice-audio-duration和x-venice-audio-subtitle。 delete_media_on_completion: true会在下载后删除媒体,因此可以跳过步骤 4。
如果生成失败(内容政策、容量或提供商验证问题),费用会退还(之前 epoch 产生的 DIEM 费用除外),错误将在此处返回。
4. POST /audio/complete — 清理
curl https://api.venice.ai/api/v1/audio/complete \
-H "Authorization: Bearer $VENICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"elevenlabs-music","queue_id":"..."}'
存储的媒体删除后返回 {"success": true}(删除未成功时返回 false)。保存音频字节后调用此接口;如果检索时使用了 delete_media_on_completion: true,则无需调用。
完整流程(TypeScript)
import fs from 'node:fs/promises'
const base = 'https://api.venice.ai/api/v1'
const headers = {
Authorization: `Bearer ${process.env.VENICE_API_KEY}`,
'Content-Type': 'application/json',
}
async function generateTrack() {
// 1. Quote
const quote = await fetch(`${base}/audio/quote`, {
method: 'POST', headers,
body: JSON.stringify({ model: 'elevenlabs-music', duration_seconds: 60 }),
}).then(r => r.json())
console.log('price:', quote.quote)
// 2. Queue
const { queue_id, model } = await fetch(`${base}/audio/queue`, {
method: 'POST', headers,
body: JSON.stringify({
model: 'elevenlabs-music',
prompt: 'Uplifting indie-folk acoustic track, 120 BPM.',
duration_seconds: 60,
force_instrumental: true,
}),
}).then(r => r.json())
// 3. Poll
while (true) {
const res = await fetch(`${base}/audio/retrieve`, {
method: 'POST', headers,
body: JSON.stringify({ model, queue_id, delete_media_on_completion: true }),
})
if (!res.ok) throw new Error(`retrieve failed: ${res.status} ${await res.text()}`)
const ct = res.headers.get('content-type') ?? ''
if (!ct.startsWith('application/json')) {
await fs.writeFile('track.mp3', Buffer.from(await res.arrayBuffer()))
break
}
const { status } = await res.json()
if (status !== 'PROCESSING') throw new Error(`unexpected ${status}`)
await new Promise(r => setTimeout(r, 3000))
}
// delete_media_on_completion: true made /audio/complete unnecessary
}
能力探测
每个 GET /models?type=music 条目的 model_spec 会公开:
supports_lyrics、lyrics_required、lyrics_character_limit、supports_lyrics_optimizersupports_force_instrumental、supports_loop、supports_language_codesupports_speed、default_speed、min_speed、max_speedvoices[]、default_voice、supports_custom_voice_idduration_options[]、min_duration、max_duration、default_durationmin_prompt_length、prompt_character_limitsupported_formats、default_format(输出容器,仅供参考,不是请求字段)voice_changer: true表示这是语音到语音模型,应使用/audio/voice-changer/*pricing,取值如下:durations—{ "<tier>": { usd, diem, min_seconds, max_seconds } }(例如elevenlabs-music、ace-step-15)generation— 每个任务固定收费(例如minimax-music-v25、lyria-3-pro、stable-audio-25)per_second— 按生成秒数收费(例如elevenlabs-sound-effects-v2、sonilo-v1-1-music、seed-audio-1-0)per_thousand_characters— 按prompt长度收费(ElevenLabs TTS 模型)
错误
| 代码 | 含义 |
|---|---|
400 | 架构错误(请求体严格校验)、模型不支持该选项、duration_seconds 无效、lyrics_optimizer 与 lyrics_prompt 冲突、在这些端点上使用了语音转换模型、检索时报告了提供商端验证失败(已退款),或在检索/完成时使用了未知或外部的 queue_id("Request ID is invalid.")。语音错误会包含 details.supported_voices。 |
401 | 身份验证失败。 |
402 | 余额不足。Bearer → {"error":"Insufficient USD or Diem balance…"};如果超出密钥自身的消费限额,则返回 `"API key USD |
403 | PRIVATE_ONLY 密钥调用 anonymized 模型,或受到区域限制。 |
404 | 未知 model;或检索时媒体不存在、已过期或已删除。 |
422 | 内容违反政策(排队或检索时)。可能包含 suggested_prompt。费用已退还(上一纪元产生的 DIEM 费用除外)。 |
429 | 请求频率受限(每位用户排队每分钟 40 次,检索每分钟 120 次)。 |
500 | 推理失败。 |
503 | 模型已达容量上限——请稍后重试。 |
响应体格式请参阅 venice-errors。
注意事项
- 排队前先获取报价。 排队时会预先扣费(积分),或根据报价检查 x402 余额。使用 API 密钥时,请将报价与
GET /api_keys/rate_limits返回的data.balances比较;该接口可使用 INFERENCE 密钥,且余额已受密钥消费限额约束。请求会从足以支付全部报价的第一种货币中扣费(DIEM、已赚取积分、捆绑积分、USD;balances不列出已赚取积分)。使用钱包时,请通过/x402/balance/...查询。 - 发送不受支持的选项(
lyrics_prompt、voice、speed、language_code、loop、duration_seconds等)会返回400,而不是静默忽略。请根据model_spec构建请求体。 - 保存
queue_id和model——之后的每次调用都需要这两项。 - 媒体是临时的。检索时请保存媒体数据;完成后(或设置
delete_media_on_completion后),音频就会消失。 seed-audio-1-0不接受duration_seconds:它会在排队时预留 120 秒的输出上限,并在完成后按实际时长结算。- 每 2–5 秒轮询一次;使用
average_execution_time来确定首次等待时间。更频繁地轮询不会加快任务处理速度,还会消耗每分钟 120 次的检索限额。