feat: TTS文字转语音配音引擎 #295

Merged
xiaoxia merged 2 commits from feat/tts-voiceover into develop 2026-07-14 10:21:50 +08:00
Owner

TTS 配音引擎

在统一渲染管道中加入 AI 配音能力。

核心模块

  1. TTS 抽象层 (packages/ports/tts_service.py)

    • TtsService Port 接口
    • 支持多 provider 切换(mock + 预留阿里云/讯飞)
    • TtsError 异常类
  2. Mock TTS 实现 (packages/adapters/tts/mock_tts_service.py)

    • 基于 FFmpeg sine 波合成测试音频
    • 不同音色用不同基频模拟
    • 语速 atempo + 语调 asetrate
    • 颤音 + 淡入淡出让声音更自然
  3. 配音引擎 (apps/worker/video_processing/tts_engine.py)

    • 整段配音模式:一段文本生成一条完整配音
    • 字幕联动模式:按字幕片段分段合成,自动对齐时间轴
    • 失败降级:TTS 失败自动跳过,不阻断渲染
  4. 统一渲染集成

    • 在 audio 图层加入配音音轨
    • 复用现有 mix_audio 混音逻辑
    • 配置通过 plan.config.tts 传入
  5. 音色预设 (packages/domain/voice_presets.py)

    • 8 种音色:温暖女声/沉稳男声/活泼女声/可爱童声/客服女声/新闻男声/轻柔女声/磁性男声
    • 支持按性别/风格/关键词筛选
  6. 服务工厂 (apps/worker/services/tts_service_factory.py)

    • 按 provider 创建 TTS 服务实例
    • 环境变量 TTS_PROVIDER 配置
  7. API 接口

    • GET /api/v1/tts/presets — 音色列表(支持 gender/style/keyword 筛选)

配置示例

{
  "tts": {
    "enabled": true,
    "voice_id": "female_warm",
    "speed": 1.0,
    "pitch": 0.0,
    "volume": 0.8,
    "text": "大家好,欢迎收看本期视频",
    "align_mode": "full",
    "overlap_mode": "mix"
  }
}

测试

  • 40 个新增单测全绿
  • 134 个现有测试全绿,无回归

向后兼容

  • 默认关闭,不传 tts 配置不受影响
  • 失败自动降级,不影响主渲染流程
## TTS 配音引擎 在统一渲染管道中加入 AI 配音能力。 ### 核心模块 1. **TTS 抽象层** (packages/ports/tts_service.py) - TtsService Port 接口 - 支持多 provider 切换(mock + 预留阿里云/讯飞) - TtsError 异常类 2. **Mock TTS 实现** (packages/adapters/tts/mock_tts_service.py) - 基于 FFmpeg sine 波合成测试音频 - 不同音色用不同基频模拟 - 语速 atempo + 语调 asetrate - 颤音 + 淡入淡出让声音更自然 3. **配音引擎** (apps/worker/video_processing/tts_engine.py) - 整段配音模式:一段文本生成一条完整配音 - 字幕联动模式:按字幕片段分段合成,自动对齐时间轴 - 失败降级:TTS 失败自动跳过,不阻断渲染 4. **统一渲染集成** - 在 audio 图层加入配音音轨 - 复用现有 mix_audio 混音逻辑 - 配置通过 plan.config.tts 传入 5. **音色预设** (packages/domain/voice_presets.py) - 8 种音色:温暖女声/沉稳男声/活泼女声/可爱童声/客服女声/新闻男声/轻柔女声/磁性男声 - 支持按性别/风格/关键词筛选 6. **服务工厂** (apps/worker/services/tts_service_factory.py) - 按 provider 创建 TTS 服务实例 - 环境变量 TTS_PROVIDER 配置 7. **API 接口** - GET /api/v1/tts/presets — 音色列表(支持 gender/style/keyword 筛选) ### 配置示例 ```json { "tts": { "enabled": true, "voice_id": "female_warm", "speed": 1.0, "pitch": 0.0, "volume": 0.8, "text": "大家好,欢迎收看本期视频", "align_mode": "full", "overlap_mode": "mix" } } ``` ### 测试 - 40 个新增单测全绿 - 134 个现有测试全绿,无回归 ### 向后兼容 - 默认关闭,不传 tts 配置不受影响 - 失败自动降级,不影响主渲染流程
xiaoxia force-pushed feat/tts-voiceover from d32c452b75 to 64e35082fb 2026-07-14 09:35:56 +08:00 Compare
Author
Owner

【代码审计】PR #295 TTS配音引擎 审查结论:有条件通过

总览

  • 结论:有条件通过
  • 问题统计:P0 x0项,P1 x0项,P2 x2项,P3 x1项
  • 核心改动:新增TTS Port/Adapter架构、MockTTS实现、TtsEngine配音引擎、音色预设库,集成到UnifiedRenderService的audio图层

问题清单

P2 - MockTtsService未使用run_ffmpeg工具函数

  • 位置:packages/adapters/tts/mock_tts_service.py → _synthesize_with_ffmpeg
  • 问题描述:使用subprocess.run直接调用ffmpeg,未使用项目统一的run_ffmpeg工具函数。虽是Mock实现且参数均为内部生成,安全风险低,但不符合项目规范,缺少统一超时管理和错误处理。
  • 修复建议:改用 from video_processing.ffmpeg_utils import run_ffmpeg 调用。

P2 - 未使用变量和导入

  • 位置:
    • mock_tts_service.py:164 → filters变量赋值但从未使用
    • tts_config.py:5 → dataclasses.field导入但未使用
  • 问题描述:pyflakes静态检查发现未使用的变量和导入
  • 修复建议:清理未使用代码。

P3 - TTS预设列表接口无分页

  • 位置:apps/api/app/api/routes/tts.py → list_preset_voices
  • 问题描述:当前8个Mock音色没问题,后续接入真实TTS供应商后音色数量可能增多
  • 修复建议:后续扩展时考虑分页。

亮点

  • Port/Adapter架构清晰,易于扩展多供应商(mock/阿里云/讯飞)
  • 边界钳制完善(speed 0.5-2.0, pitch -12~12, volume 0-1)
  • 失败降级机制完善(TTS失败不阻断渲染,单片段失败跳过)
  • 单元测试覆盖全面(413行测试,覆盖配置解析、Mock服务、引擎核心、失败降级)
  • 支持整段配音和字幕联动两种模式

修复P2问题后可合并。

【代码审计】PR #295 TTS配音引擎 审查结论:有条件通过 ## 总览 - 结论:有条件通过 - 问题统计:P0 x0项,P1 x0项,P2 x2项,P3 x1项 - 核心改动:新增TTS Port/Adapter架构、MockTTS实现、TtsEngine配音引擎、音色预设库,集成到UnifiedRenderService的audio图层 ## 问题清单 ### P2 - MockTtsService未使用run_ffmpeg工具函数 - 位置:packages/adapters/tts/mock_tts_service.py → _synthesize_with_ffmpeg - 问题描述:使用subprocess.run直接调用ffmpeg,未使用项目统一的run_ffmpeg工具函数。虽是Mock实现且参数均为内部生成,安全风险低,但不符合项目规范,缺少统一超时管理和错误处理。 - 修复建议:改用 `from video_processing.ffmpeg_utils import run_ffmpeg` 调用。 ### P2 - 未使用变量和导入 - 位置: - mock_tts_service.py:164 → filters变量赋值但从未使用 - tts_config.py:5 → dataclasses.field导入但未使用 - 问题描述:pyflakes静态检查发现未使用的变量和导入 - 修复建议:清理未使用代码。 ### P3 - TTS预设列表接口无分页 - 位置:apps/api/app/api/routes/tts.py → list_preset_voices - 问题描述:当前8个Mock音色没问题,后续接入真实TTS供应商后音色数量可能增多 - 修复建议:后续扩展时考虑分页。 ## 亮点 - ✅ Port/Adapter架构清晰,易于扩展多供应商(mock/阿里云/讯飞) - ✅ 边界钳制完善(speed 0.5-2.0, pitch -12~12, volume 0-1) - ✅ 失败降级机制完善(TTS失败不阻断渲染,单片段失败跳过) - ✅ 单元测试覆盖全面(413行测试,覆盖配置解析、Mock服务、引擎核心、失败降级) - ✅ 支持整段配音和字幕联动两种模式 修复P2问题后可合并。
xiaoxia added 2 commits 2026-07-14 10:08:11 +08:00
- TTS服务抽象层 (TtsService Port),支持多provider切换
- Mock TTS实现:基于FFmpeg sine波合成,8种预设音色
- 配音核心引擎 (TtsEngine):整段配音+字幕联动配音
- 语速/语调调整:speed 0.5x~2.0x,pitch -12~12半音
- 8种预设音色:温暖女声/沉稳男声/活泼女声/可爱童声/客服女声/新闻男声/轻柔女声/磁性男声
- 字幕联动:按字幕片段分段合成,自动对齐时间轴
- 降级策略:TTS失败自动跳过,不阻断渲染
- 集成到UnifiedRenderService:配音作为独立音轨混入
- 音色列表API:GET /api/v1/tts/presets 支持按性别/风格/关键词筛选
- 40个新增单测全绿 + 134个现有测试全绿,无回归
chore: rebase到develop + 格式化代码
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 40s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m17s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 1m26s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 4m48s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
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 / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
c6bc8170d1
xiaoxia force-pushed feat/tts-voiceover from 64e35082fb to c6bc8170d1 2026-07-14 10:08:11 +08:00 Compare
xiaoxia merged commit c840f37a44 into develop 2026-07-14 10:21:50 +08:00
Sign in to join this conversation.