fix(viral-video): 预设音色ID与后端对齐(longxiaochun_v3等v3后缀)+ 取消模糊匹配兜底 #2130

Merged
xiaoxia merged 1 commits from fix/2041-preset-voice-ids into develop 2026-10-01 22:42:17 +08:00
Owner

排查结论

1. 前端硬编码旧ID位置

只在 PresetVoicePickerModal.tsx 的 MOCK_VOICES 兜底列表里发现旧ID硬编码:

  • long-xiaochun(错误带短横线、无v3后缀)
  • long-xiaoxia / long-xiaoyan / long-xiaotong / long-sanshu / long-xiaogang / long-xiaocheng / long-xiaozhi / long-yue / long-xiaodong / long-xiaoling / long-xiaoxiao-neural(12个,多数是虚构ID,与后端真实音色列表不对应)
  • zh-CN-XiaoxiaoNeural 之前的 Azure TTS 兜底 ID 已在上一轮修复中清理。

ViralVideoPage.tsx 本身没有硬编码任何 preset voice_id;所有 preset 音色通过 onConfirm 回调以 Modal 返回对象的 id 为准透传。

2. 默认音色兜底

  • 前端无默认音色:emptyTask.refAudio = null,用户不主动选音色的话 voice_id 不会传给后端,由后端走默认(后端默认 longxiaochun_v3,见 packages/application/cosyvoice_service.py 注释与健康检查)。
  • 选了内置音色后,Modal 返回的 v.id 直接写进 refAudio.id,confirm-copy/generate-video payload 取 task.refAudio.id 作为 voice_id。

3. ID 覆盖风险

原代码 { ...v, ... } 已经是把 API 的 v 放在展开后,但模糊匹配会给 category/desc 补充信息,不覆盖 id,所以不覆盖后端 voice_id。不过匹配逻辑用 name 模糊命中(slice(1)/slice(0,2))很脆弱,可能误匹配。

4. MOCK_VOICES 与后端对齐

对照后端 packages/domain/preset_voices.py 的 PRESET_VOICES 列表(CosyVoice v3-flash 真实可用音色),重写 MOCK_VOICES:

  • 8 个音色(与后端完全一致):longxiaochun_v3(龙小淳)/longxiaoxia_v3(龙小夏)/longsanshu_v3(龙三叔)/longyue_v3(龙悦)/longshu_v3(龙书)/longyingjing_v3(龙应静)/longshuo_v3(龙硕)/longtian_v3(龙甜)
  • 删除虚构的 long-xiaoyan/long-xiaotong/long-xiaogang/long-xiaocheng/long-xiaozhi/long-xiaodong/long-xiaoling/晓晓 等 ID(后端没这些音色,提交会导致 TTS 失败)
  • 描述文案与后端 PRESET_VOICES.description 对齐

5. 匹配逻辑修复

realList 映射改为按 id 精确匹配(m.id === v.id),不用 name 模糊匹配。当 API 返回真实音色列表时,id/name/gender/category/desc 全部来自 API,不被 mock 覆盖;只有当字段缺失时才用 mock 的同 ID 条目补充。

后端 ID 规范确认

后端 packages/domain/preset_voices.py 明确:

  • voice_id 格式:long{pinyin}_v3,例如 longxiaochun_v3
  • tags:["知性","女声","助手"] 这类中文标签
  • 默认 voice_id = longxiaochun_v3(health check 与注释均确认)

验证

  • tsc ✅ / vite build ✅ / prettier ✅
  • 全局 grep 前端代码无 long-xiaochun/longxiaochun(旧)/zh-CN-XiaoxiaoNeural 残留
## 排查结论 ### 1. 前端硬编码旧ID位置 只在 `PresetVoicePickerModal.tsx` 的 MOCK_VOICES 兜底列表里发现旧ID硬编码: - `long-xiaochun`(错误带短横线、无v3后缀) - `long-xiaoxia` / `long-xiaoyan` / `long-xiaotong` / `long-sanshu` / `long-xiaogang` / `long-xiaocheng` / `long-xiaozhi` / `long-yue` / `long-xiaodong` / `long-xiaoling` / `long-xiaoxiao-neural`(12个,多数是虚构ID,与后端真实音色列表不对应) - `zh-CN-XiaoxiaoNeural` 之前的 Azure TTS 兜底 ID 已在上一轮修复中清理。 `ViralVideoPage.tsx` 本身没有硬编码任何 preset voice_id;所有 preset 音色通过 onConfirm 回调以 Modal 返回对象的 id 为准透传。 ### 2. 默认音色兜底 - **前端无默认音色**:`emptyTask.refAudio = null`,用户不主动选音色的话 `voice_id` 不会传给后端,由后端走默认(后端默认 `longxiaochun_v3`,见 `packages/application/cosyvoice_service.py` 注释与健康检查)。 - 选了内置音色后,Modal 返回的 `v.id` 直接写进 `refAudio.id`,confirm-copy/generate-video payload 取 `task.refAudio.id` 作为 `voice_id`。 ### 3. ID 覆盖风险 原代码 `{ ...v, ... }` 已经是把 API 的 v 放在展开后,但模糊匹配会给 category/desc 补充信息,**不覆盖 id**,所以不覆盖后端 voice_id。不过匹配逻辑用 name 模糊命中(slice(1)/slice(0,2))很脆弱,可能误匹配。 ### 4. MOCK_VOICES 与后端对齐 对照后端 `packages/domain/preset_voices.py` 的 PRESET_VOICES 列表(CosyVoice v3-flash 真实可用音色),重写 MOCK_VOICES: - 8 个音色(与后端完全一致):longxiaochun_v3(龙小淳)/longxiaoxia_v3(龙小夏)/longsanshu_v3(龙三叔)/longyue_v3(龙悦)/longshu_v3(龙书)/longyingjing_v3(龙应静)/longshuo_v3(龙硕)/longtian_v3(龙甜) - 删除虚构的 long-xiaoyan/long-xiaotong/long-xiaogang/long-xiaocheng/long-xiaozhi/long-xiaodong/long-xiaoling/晓晓 等 ID(后端没这些音色,提交会导致 TTS 失败) - 描述文案与后端 PRESET_VOICES.description 对齐 ### 5. 匹配逻辑修复 realList 映射改为**按 id 精确匹配**(`m.id === v.id`),不用 name 模糊匹配。当 API 返回真实音色列表时,id/name/gender/category/desc 全部来自 API,不被 mock 覆盖;只有当字段缺失时才用 mock 的同 ID 条目补充。 ## 后端 ID 规范确认 后端 packages/domain/preset_voices.py 明确: - voice_id 格式:`long{pinyin}_v3`,例如 longxiaochun_v3 - tags:["知性","女声","助手"] 这类中文标签 - 默认 voice_id = longxiaochun_v3(health check 与注释均确认) ## 验证 - tsc ✅ / vite build ✅ / prettier ✅ - 全局 grep 前端代码无 long-xiaochun/longxiaochun(旧)/zh-CN-XiaoxiaoNeural 残留
xiaoxia added 1 commit 2026-10-01 22:42:13 +08:00
fix(viral-video): 预设音色ID与后端对齐 longxiaochun_v3等v3后缀,去模糊匹配
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 54s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m44s
PR Automation / Auto Approve on CI Green (pull_request) Failing after 1m52s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m48s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 3m18s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 4m8s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 5m40s
AI Code Review / AI Code Review (pull_request) Successful in 7m24s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Successful in 22m35s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 27m20s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 58m19s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
880354e8de
xiaoxia merged commit 07069144c7 into develop 2026-10-01 22:42:17 +08:00
xiaoxia deleted branch fix/2041-preset-voice-ids 2026-10-01 22:42:23 +08:00
auto-approve-bot reviewed 2026-10-01 22:44:06 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。

🗑️ 预览环境已清理

PR #2130 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #2130 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。

🚀 预览环境已部署

项目 详情
PR号 #2130
预览链接 https://pr-2130.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #2130 | | 预览链接 | [https://pr-2130.preview.xiaoxiajianji.com](https://pr-2130.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Sign in to join this conversation.