Files
xiaoxia-saas/packages/domain/preset_voices.py
T
灵应 44dc89360a
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 170h24m47s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 170h24m52s
Deploy / Deploy Staging (push) Failing after 170h27m34s
CI/CD Pipeline / Frontend Lint (push) Failing after 170h28m8s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 170h28m14s
feat: 配音列表 API 增强 — 预置音色 + 克隆音色统一接口
- 新增预置音色配置(8 个 CosyVoice 真实音色)
- 增强 GET /api/v1/voices 接口,支持 type 查询参数(preset/clone/all)
- 新增 GET /api/v1/voices/presets 端点
- 统一响应格式,包含 preset_count 和 clone_count
- 保留原有 CRUD 端点向后兼容
- 添加 18 个预置音色单元测试(全部通过)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 10:26:14 +08:00

134 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""预置音色配置 — Phase 3 CosyVoice 集成.
定义系统预置的 CosyVoice 音色列表,不存数据库,以配置方式提供。
音色 ID 对应阿里云 CosyVoice 模型中的真实音色名。
参考: https://help.aliyun.com/zh/model-studio/cosyvoice-voice-list
"""
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class PresetVoice:
"""预置音色定义。
Attributes:
voice_id: CosyVoice 模型音色名(如 longxiaochun
name: 中文展示名
description: 音色描述
gender: 性别(male/female
language: 语言代码(如 zh-CN
preview_url: 预览音频 URL(可选)
tags: 标签列表
"""
voice_id: str
name: str
description: str
gender: str
language: str = "zh-CN"
preview_url: str = ""
tags: list[str] | None = None
def to_dict(self) -> dict:
"""序列化为字典。"""
return {
"voice_id": self.voice_id,
"name": self.name,
"description": self.description,
"gender": self.gender,
"language": self.language,
"preview_url": self.preview_url,
"tags": self.tags or [],
}
# 预置音色列表(阿里云 CosyVoice 真实可用音色)
PRESET_VOICES: list[PresetVoice] = [
PresetVoice(
voice_id="longxiaochun",
name="龙小淳",
description="温柔女声,适合情感类内容",
gender="female",
language="zh-CN",
tags=["温柔", "女声", "情感"],
),
PresetVoice(
voice_id="longxiaoxia",
name="龙小夏",
description="知性女声,适合新闻播报",
gender="female",
language="zh-CN",
tags=["知性", "女声", "播报"],
),
PresetVoice(
voice_id="longxiaochen",
name="龙小晨",
description="磁性男声,适合有声书",
gender="male",
language="zh-CN",
tags=["磁性", "男声", "有声书"],
),
PresetVoice(
voice_id="longyue",
name="龙悦",
description="甜美女声,适合广告配音",
gender="female",
language="zh-CN",
tags=["甜美", "女声", "广告"],
),
PresetVoice(
voice_id="longshu",
name="龙书",
description="沉稳男声,适合教育讲解",
gender="male",
language="zh-CN",
tags=["沉稳", "男声", "教育"],
),
PresetVoice(
voice_id="longjing",
name="龙静",
description="优雅女声,适合纪录片解说",
gender="female",
language="zh-CN",
tags=["优雅", "女声", "纪录片"],
),
PresetVoice(
voice_id="longbo",
name="龙博",
description="浑厚男声,适合科技类内容",
gender="male",
language="zh-CN",
tags=["浑厚", "男声", "科技"],
),
PresetVoice(
voice_id="longtian",
name="龙甜",
description="活泼女声,适合短视频配音",
gender="female",
language="zh-CN",
tags=["活泼", "女声", "短视频"],
),
]
def get_preset_voices() -> list[PresetVoice]:
"""获取所有预置音色。"""
return PRESET_VOICES
def get_preset_voice_by_id(voice_id: str) -> PresetVoice | None:
"""根据 voice_id 获取预置音色。"""
for voice in PRESET_VOICES:
if voice.voice_id == voice_id:
return voice
return None
def is_preset_voice(voice_id: str) -> bool:
"""判断是否为预置音色。"""
return get_preset_voice_by_id(voice_id) is not None