You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

4.7 KiB

Changelog: 添加 ElevenLabs 音色列表 API

日期: 2026-02-10
类型: Feature
影响范围: AI Service, API

变更概述

添加 /api/v1/ai/voices 接口,支持获取 ElevenLabs 可用音色列表,方便前端展示音色选择器。

变更详情

1. AIService 新增方法

文件: server/app/services/ai_service.py

async def list_voices(self, model: Optional[str] = None) -> Dict[str, Any]:
    """获取可用音色列表
    
    Args:
        model: 模型名称(可选,默认使用 ElevenLabs)
        
    Returns:
        {
            'voices': [
                {
                    'voice_id': str,
                    'name': str,
                    'category': str,
                    'description': str,
                    'preview_url': str,
                    'labels': dict
                }
            ]
        }
    """

功能

  • 调用 ElevenLabs Provider 的 list_voices() 方法
  • 返回所有可用音色及其元数据

2. API 路由新增端点

文件: server/app/api/v1/ai.py

@router.get("/voices", response_model=ApiResponse[dict])
async def list_voices(
    model: Optional[str] = Query(None, description="模型名称(可选,默认 ElevenLabs)"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_session)
):
    """获取可用音色列表"""

端点: GET /api/v1/ai/voices

查询参数:

  • model (可选): 模型名称,默认使用 ElevenLabs

响应示例:

{
  "success": true,
  "code": 200,
  "message": "Success",
  "data": {
    "voices": [
      {
        "voice_id": "CwhRBWXzGAHq8TQ4Fs17",
        "name": "Roger - Laid-Back, Casual, Resonant",
        "category": "premade",
        "description": "Easy going and perfect for casual conversations.",
        "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/CwhRBWXzGAHq8TQ4Fs17/58ee3ff5-f6f2-4628-93b8-e38eb31806b0.mp3",
        "labels": {
          "accent": "american",
          "gender": "male",
          "age": "middle_aged",
          "language": "en",
          "use_case": "conversational"
        }
      }
    ]
  }
}

使用场景

前端集成示例

// 1. 获取音色列表
const { data } = await fetch('/api/v1/ai/voices', {
  headers: { Authorization: `Bearer ${token}` }
});

// 2. 展示音色选择器(带试听功能)
<Select>
  {data.voices.map(voice => (
    <Option key={voice.voice_id} value={voice.voice_id}>
      <div>
        <span>{voice.name}</span>
        {voice.preview_url && (
          <audio controls src={voice.preview_url} preload="none">
            Your browser does not support the audio element.
          </audio>
        )}
      </div>
    </Option>
  ))}
</Select>

// 3. 使用选中的音色生成语音
await fetch('/api/v1/ai/generate-voice', {
  method: 'POST',
  body: JSON.stringify({
    text: "Hello world",
    voice_type: selectedVoiceId  // 使用 voice_id
  })
});

注意事项

API Key 权限要求

ElevenLabs API Key 需要包含 voices_read 权限才能调用此接口。

错误示例:

{
  "success": false,
  "code": 400,
  "message": "获取音色列表失败: missing_permissions - voices_read"
}

解决方案:

  1. 登录 ElevenLabs Dashboard
  2. 重新生成 API Key 并勾选 voices_read 权限
  3. 更新 .env 中的 ELEVENLABS_API_KEY

音色分类

  • premade: 预制音色(官方提供)
  • cloned: 克隆音色(用户克隆)
  • professional: 专业音色(付费)

筛选建议

前端可以根据 labels 字段筛选音色:

  • language: 语言(en, zh, es, fr 等)
  • gender: 性别(male, female)
  • age: 年龄(young, middle_aged, old)
  • accent: 口音(american, british, australian 等)
  • use_case: 用途(conversational, narration, characters 等)

相关文档

测试验证

# 获取音色列表
curl -X GET "http://localhost:6160/api/v1/ai/voices" \
  -H "Authorization: Bearer $TOKEN"

# 使用音色生成语音
curl -X POST "http://localhost:6160/api/v1/ai/generate-voice" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello, this is a test.",
    "voice_type": "CwhRBWXzGAHq8TQ4Fs17"
  }'

后续优化

  1. 缓存音色列表: 音色列表变化不频繁,可以缓存 1 小时减少 API 调用 已实现
  2. 音色预览: 前端支持播放 preview_url 试听音色 API 已返回 preview_url
  3. 音色收藏: 用户可以收藏常用音色
  4. 音色搜索: 支持按名称、语言、性别等搜索音色