{"id":49643449,"url":"https://github.com/duolabmeng6/voice_hub","last_synced_at":"2026-05-09T00:02:02.666Z","repository":{"id":355253767,"uuid":"1227380817","full_name":"duolabmeng6/voice_hub","owner":"duolabmeng6","description":"多厂商 TTS 的 speaker 路由器。把 MiniMax、MiMo、智谱 GLM、阿里云百炼这些服务收进一个 Client，像管理配音演员一样管理 AI 声音。  业务代码只关心三件事：让谁说、说什么、存到哪。系统音色、克隆音色、文本设计音色、不同厂商的 payload 和音频返回格式，都交给 voice_hub 处理。","archived":false,"fork":false,"pushed_at":"2026-05-02T21:53:36.000Z","size":147,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T21:40:01.325Z","etag":null,"topics":["asr","tts","tts-api","voice"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duolabmeng6.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-02T15:51:36.000Z","updated_at":"2026-05-04T17:42:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/duolabmeng6/voice_hub","commit_stats":null,"previous_names":["duolabmeng6/voice_hub"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/duolabmeng6/voice_hub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duolabmeng6%2Fvoice_hub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duolabmeng6%2Fvoice_hub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duolabmeng6%2Fvoice_hub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duolabmeng6%2Fvoice_hub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duolabmeng6","download_url":"https://codeload.github.com/duolabmeng6/voice_hub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duolabmeng6%2Fvoice_hub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32713820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asr","tts","tts-api","voice"],"created_at":"2026-05-05T21:39:50.823Z","updated_at":"2026-05-09T00:02:02.660Z","avatar_url":"https://github.com/duolabmeng6.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# voice_hub\n\n[![PyPI version](https://img.shields.io/pypi/v/duolabmeng6-voice-hub.svg)](https://pypi.org/project/duolabmeng6-voice-hub/)\n[![Python versions](https://img.shields.io/pypi/pyversions/duolabmeng6-voice-hub.svg)](https://pypi.org/project/duolabmeng6-voice-hub/)\n[![Downloads](https://img.shields.io/pepy/dt/duolabmeng6-voice-hub.svg)](https://pepy.tech/project/duolabmeng6-voice-hub)\n\n多厂商 TTS 的 speaker 路由器。把 MiniMax、MiMo、智谱 GLM、阿里云百炼这些服务收进一个 `Client`，像管理配音演员一样管理 AI 声音。\n\n业务代码只关心三件事：让谁说、说什么、存到哪。系统音色、克隆音色、文本设计音色、不同厂商的 payload 和音频返回格式，都交给 `voice_hub` 处理。\n\n```python\nclient.speaker(\"旁白\").speak(\"欢迎回来。\").save(\"narrator.mp3\")\nclient.speaker(\"女主\").speak(\"我已经准备好了。\").save(\"heroine.wav\")\nclient.speaker(\"广告音\").speak(\"限时优惠，现在开始。\").save(\"ad.mp3\")\n```\n\n适合这些场景：\n\n- 短视频、直播切片、广告素材批量生成\n- 同一个项目里混用多个 TTS 厂商\n- 给不同角色绑定不同声音，随时切换 speaker\n- 复用克隆音色，避免业务代码到处写 provider 细节\n- 先用一个厂商上线，后面平滑替换或增加新声音\n\n核心优势：\n\n- **角色化**：把声音注册成 `旁白`、`女主`、`广告音` 这样的业务名字。\n- **多厂商统一**：MiniMax、MiMo、GLM、阿里云都走同一套调用方式。\n- **少改业务代码**：换声音、换模型、换 provider，不需要到处改生成逻辑。\n- **音频结果一致**：统一拿 bytes、保存文件、读取 metadata。\n\n## 安装\n\n```bash\npip install duolabmeng6-voice-hub\n```\n\nPython 版本要求：`\u003e=3.10`。\n\n## 为什么用它\n\n直接接 TTS 服务时，业务代码很快会被这些问题拖住：\n\n- 每家 provider 的认证、payload、返回音频格式都不一样。\n- 系统音色、克隆音色、设计音色的创建方式不一样。\n- 切换声音时容易把业务逻辑和厂商参数混在一起。\n- 批量生成时，需要稳定地保存音频、拿字节、记录元数据。\n\n`voice_hub` 把这些差异压到 provider 层。业务层只和 speaker 打交道：\n\n```python\nclient.add_speaker(\"旁白\", minimax_tts, default=True)\nclient.add_speaker(\"女主\", mimo_clone_tts)\nclient.add_speaker(\"广告音\", aliyun_tts)\n\nclient.speak(\"默认 speaker 会说这句话。\").save(\"default.mp3\")\nclient.speaker(\"女主\").speak(\"这句换女主说。\").save(\"heroine.wav\")\n```\n\n## 支持的声音来源\n\n| Provider | 入口 | 默认环境变量 | 说明 |\n| --- | --- | --- | --- |\n| MiniMax | `voice_hub.MinimaxTTS` | `MINIMAX_KEY` | 同步/流式 T2A、系统音色、快速复刻试听 |\n| MiMo | `voice_hub.MimoTTS` | 手动传入 `api_key` | 内置音色、文本设计音色、参考音频克隆 |\n| 智谱 GLM | `voice_hub.GLMTTS` | `ZHIPUAI_API_KEY` | 系统音色和克隆后的 `voice_id` |\n| 阿里云百炼 Qwen TTS | `voice_hub.AliyunTTS` | `DASHSCOPE_API_KEY` | Qwen TTS 系统音色、指令控制 |\n| 阿里云百炼 CosyVoice | `voice_hub.AliyunCosyVoiceTTS` | `DASHSCOPE_API_KEY` | 系统音色、本地文件复刻、公网 URL 复刻 |\n| OpenAI / Azure | `voice_hub.OpenAITTS` / `voice_hub.AzureTTS` | 按实例配置 | 占位/扩展入口 |\n\n更完整的接入流程见：\n\n- [阿里云百炼语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/aliyun-tts.md)\n- [智谱 GLM TTS 接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/glm-tts.md)\n- [MiniMax 语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/minimax-tts.md)\n- [MiMo 语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/mimo-tts.md)\n\n## 快速开始\n\n用 MiniMax 创建一个 speaker：\n\n```python\nimport os\nimport voice_hub\n\nclient = voice_hub.Client()\n\nclient.add_speaker(\n    \"旁白\",\n    voice_hub.MinimaxTTS(\n        api_key=os.environ[\"MINIMAX_KEY\"],\n        voice=voice_hub.MinimaxVoice.MALE_QN_QINGSE,\n        emotion=\"happy\",\n        format=\"mp3\",\n    ),\n    default=True,\n)\n\nclient.speak(\"夜深了，城市还没有睡。\").save(\"./tmp/narrator.mp3\")\n```\n\n再加一个 MiMo 克隆音色：\n\n```python\nclient.add_speaker(\n    \"龙儿\",\n    voice_hub.MimoTTS.cloned(\n        api_key=os.environ[\"MIMO_TOKEN_KEY\"],\n        base_url=os.environ[\"MIMO_TOKEN_BASE_URL\"],\n        sample=voice_hub.VoiceSample(\"./tmp/voice-clones/vc30.wav\"),\n        style=\"自然、快速讲话\",\n    ),\n)\n\nclient.speaker(\"龙儿\").speak(\"这句话换成克隆音色来说。\").save(\"./tmp/longer.wav\")\n```\n\n需要音频字节或元数据时，拿 `Speech` 对象：\n\n```python\nspeech = client.speaker(\"旁白\").speak(\"你好，欢迎使用 voice_hub。\")\n\naudio_bytes = speech.bytes()\nsaved_path = speech.save(\"./tmp/output.mp3\")\nmetadata = speech.metadata\n```\n\n也可以绕过 `Client`，直接调用单个 provider：\n\n```python\ntts = voice_hub.GLMTTS(\n    voice=voice_hub.GLMVoice.FEMALE,\n    response_format=\"wav\",\n    watermark_enabled=False,\n)\n\ntts.speak(\"夜深了，城市还没有睡。\").save(\"./tmp/glm.wav\")\n```\n\n## 多 speaker 管理\n\n```python\nimport os\nimport voice_hub\n\nclient = voice_hub.Client()\n\nclient.add_speaker(\n    \"冰糖\",\n    voice_hub.MimoTTS(\n        api_key=os.environ[\"MIMO_API_KEY\"],\n        base_url=os.environ.get(\"MIMO_BASE_URL\", \"https://api.xiaomimimo.com/v1\"),\n        voice=voice_hub.MimoVoice.BINGTANG,\n        style=\"自然、平稳\",\n    ),\n    default=True,\n)\n\nclient.add_speaker(\n    \"龙儿克隆\",\n    voice_hub.MimoTTS.cloned(\n        api_key=os.environ[\"MIMO_TOKEN_KEY\"],\n        base_url=os.environ[\"MIMO_TOKEN_BASE_URL\"],\n        sample=voice_hub.VoiceSample(\"./tmp/voice-clones/vc30.wav\"),\n        style=\"自然、快速讲话\",\n    ),\n)\n\nclient.add_speaker(\n    \"龙儿女生\",\n    voice_hub.MimoTTS.designed(\n        api_key=os.environ[\"MIMO_TOKEN_KEY\"],\n        base_url=os.environ[\"MIMO_TOKEN_BASE_URL\"],\n        prompt=\"年轻女性，温柔、松弛、有轻微气声\",\n        style=\"自然、平稳\",\n    ),\n)\n\nclient.speaker(\"冰糖\").speak(\"夜深了，城市还没有睡。\").save(\"./tmp/冰糖.wav\")\nclient.speaker(\"龙儿女生\").speak(\"夜深了，城市还没有睡。\").save(\"./tmp/龙儿女生.wav\")\nclient.speaker(\"龙儿克隆\").speak(\"夜深了，城市还没有睡。\").save(\"./tmp/龙儿克隆.wav\")\n```\n\n## MiniMax\n\n```python\nimport os\nimport voice_hub\n\ntts = voice_hub.MinimaxTTS(\n    api_key=os.environ[\"MINIMAX_KEY\"],\n    voice=voice_hub.MinimaxVoice.MALE_QN_QINGSE,\n    model=voice_hub.MINIMAX_T2A_MODEL,\n    emotion=\"happy\",\n    format=\"mp3\",\n)\n\ntts.speak(\"今天是不是很开心呀(laughs)，当然了！\").save(\"./tmp/minimax.mp3\")\n```\n\n查看官方系统音色备注：\n\n```python\nvoice_hub.MINIMAX_SYSTEM_VOICE_BY_ID[\"male-qn-qingse\"].note\n# \"中文 (普通话) / 青涩青年音色\"\n\nvoice_hub.MINIMAX_SYSTEM_VOICES_BY_LANGUAGE[\"中文 (粤语)\"]\n# 返回全部粤语系统音色说明\n```\n\n## MiMo\n\n```python\nimport os\nimport voice_hub\n\napi_key = os.environ[\"MIMO_API_KEY\"]\nbase_url = os.environ.get(\"MIMO_BASE_URL\", \"https://api.xiaomimimo.com/v1\")\n\nsystem_tts = voice_hub.MimoTTS(\n    api_key=api_key,\n    base_url=base_url,\n    voice=voice_hub.MimoVoice.BINGTANG,\n    style=\"轻快\",\n    format=\"wav\",\n)\n\ndesigned_tts = voice_hub.MimoTTS.designed(\n    api_key=api_key,\n    base_url=base_url,\n    prompt=\"年轻女性，温柔、松弛、有轻微气声\",\n    style=\"自然、平稳\",\n)\n\ncloned_tts = voice_hub.MimoTTS.cloned(\n    api_key=api_key,\n    base_url=base_url,\n    sample=voice_hub.VoiceSample(\"voice.mp3\"),\n    style=\"自然、平稳\",\n)\n```\n\n预置音色常量：\n\n```python\nvoice_hub.MimoVoice.DEFAULT   # \"mimo_default\"\nvoice_hub.MimoVoice.BINGTANG  # \"冰糖\"\nvoice_hub.MimoVoice.MOLI      # \"茉莉\"\nvoice_hub.MimoVoice.SUDA      # \"苏打\"\nvoice_hub.MimoVoice.BAIHUA    # \"白桦\"\nvoice_hub.MimoVoice.MIA       # \"Mia\"\nvoice_hub.MimoVoice.CHLOE     # \"Chloe\"\nvoice_hub.MimoVoice.MILO      # \"Milo\"\nvoice_hub.MimoVoice.DEAN      # \"Dean\"\n```\n\n## 智谱 GLM TTS\n\n默认读取 `ZHIPUAI_API_KEY`，直接调用智谱 HTTP API。完整说明见 [智谱 GLM TTS 接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/glm-tts.md)。\n\n```python\nimport voice_hub\n\ntts = voice_hub.GLMTTS(\n    voice=voice_hub.GLMVoice.FEMALE,\n    response_format=\"wav\",\n    watermark_enabled=False,\n)\n\ntts.speak(\"夜深了，城市还没有睡。\").save(\"./tmp/glm.wav\")\n```\n\n`watermark_enabled=False` 只对已经在智谱控制台完成去水印开通的账号生效；否则服务端可能仍会返回带显式水印的音频。\n\n当前内置官方系统音色：\n\n```python\nvoice_hub.GLM_SYSTEM_VOICE_IDS\n# (\"female\", \"male\", \"tongtong\", \"chuichui\", \"xiaochen\", \"jam\", \"kazi\", \"douji\", \"luodo\")\n```\n\n也可以使用克隆后的 `voice_id`：\n\n```python\ntts = voice_hub.GLMTTS(voice=\"your_voice_id\", response_format=\"wav\")\ntts.speak(\"你好，这是使用克隆音色合成的语音。\").save(\"./tmp/glm-clone.wav\")\n```\n\n## 阿里云百炼 Qwen TTS\n\n系统音色合成，默认读取 `DASHSCOPE_API_KEY`：\n\n```python\nimport voice_hub\n\ntts = voice_hub.AliyunTTS(\n    voice=voice_hub.AliyunVoice.CHERRY,\n    instructions=\"语速较快，带有明显的上扬语调，适合介绍时尚产品\",\n)\n\ntts.speak(\"那我来给大家推荐一款T恤，这款呢真的是超级好看。\").save(\"./tmp/aliyun.wav\")\n```\n\n默认模型是 `qwen3-tts-instruct-flash`。如需使用普通 Flash 模型：\n\n```python\nvoice_hub.AliyunTTS(model=voice_hub.ALIYUN_QWEN_TTS_FLASH_MODEL)\n```\n\n新加坡地域可把 `base_url` 改为 `voice_hub.ALIYUN_INTL_BASE_URL`。北京和新加坡 API Key 不通用。\n\n## 阿里云百炼 CosyVoice\n\n默认读取 `DASHSCOPE_API_KEY`，需要环境里已安装 DashScope SDK。\n\n常用入口：\n\n- 系统音色：直接实例化 `AliyunCosyVoiceTTS(...)`\n- 本地文件复刻：`AliyunCosyVoiceTTS.cloned(sample=...)`\n- 公网 URL 复刻：`AliyunCosyVoiceTTS.cloned(audio_url=...)`\n\n系统音色合成：\n\n```python\nimport voice_hub\n\ntts = voice_hub.AliyunCosyVoiceTTS(\n    voice=voice_hub.AliyunCosyVoice.LONGANYANG,\n)\n\ntts.speak(\"那我来给大家推荐一款T恤，这款颜色很显气质。\").save(\"./tmp/cosyvoice.mp3\")\n```\n\n本地文件复刻音色：\n\n```python\ntts = voice_hub.AliyunCosyVoiceTTS.cloned(\n    sample=\"./tmp/voice-clones/vc30.wav\",\n    language_hints=[\"zh\"],\n)\n\ntts.speak(\n    \"恭喜，已成功复刻并合成了属于自己的声音。\",\n).save(\"./tmp/cosyvoice-clone-from-file.mp3\")\n\nprint(tts.voice_result.voice_id)\nprint(tts.voice_result.reused)\n```\n\n公网 URL 复刻音色：\n\n```python\ntts = voice_hub.AliyunCosyVoiceTTS.cloned(\n    audio_url=\"https://example.com/reference.wav\",\n    language_hints=[\"zh\"],\n    max_prompt_audio_length=20.0,\n    enable_preprocess=False,\n)\n\ntts.speak(\"How is the weather today?\").save(\"./tmp/cosyvoice-clone.mp3\")\n```\n\n复刻时默认会先复用已有音色，避免每次调用都创建新音色：\n\n- `sample=...`：使用 `target_model + 文件内容` 的 MD5 派生 10 位以内前缀。\n- `audio_url=...`：使用 `target_model + audio_url` 的 MD5 派生 10 位以内前缀。\n- 创建前会先按前缀 `list_voices`，已有 `OK` 或 `DEPLOYING` 音色时直接复用。\n- 也可以显式传入 `prefix`，例如 `prefix=\"myvoice\"`。\n\n## 详细教程\n\n- [阿里云百炼语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/aliyun-tts.md)\n- [智谱 GLM TTS 接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/glm-tts.md)\n- [MiniMax 语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/minimax-tts.md)\n- [MiMo 语音合成接入流程](https://github.com/duolabmeng6/voice_hub/blob/main/docs/mimo-tts.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduolabmeng6%2Fvoice_hub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduolabmeng6%2Fvoice_hub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduolabmeng6%2Fvoice_hub/lists"}