# 语音合成坊数据表V2架构说明 ## 概述 为了统一语音合成坊的异步任务管理,创建了4个新表(V2版本),采用零影响迁移策略。 ## 设计原则 1. **统一异步模式** - 所有任务都是异步的,通过 task_id 追踪 2. **零影响迁移** - 创建新表,不修改旧表,现有服务不受影响 3. **统一状态管理** - 所有表使用相同的状态流转:PENDING → PROCESSING → SUCCEEDED / FAILED 4. **完整错误处理** - 所有表都有 error_message 字段记录失败原因 ## 新表结构 ### 1. asr_recognition_v2(语音识别) **用途**: 异步语音识别任务 **核心字段**: - `task_id`: DashScope返回的任务ID(唯一标识) - `model`: ASR模型名称 - `file_url`: 音频文件URL - `status`: 任务状态 - `result_text`: 识别结果文本 - `result_url`: 识别结果文件URL(长文本场景) - `duration`: 音频时长(秒) - `bill`: 费用(元) **状态流转**: ``` PENDING (提交任务) → PROCESSING (识别中) → SUCCEEDED (成功) / FAILED (失败) ``` **使用场景**: - 用户上传音频文件进行语音识别 - 支持长音频文件识别 - 异步轮询获取识别结果 --- ### 2. audio_synthesis_v2(语音合成) **用途**: 异步语音合成任务 **核心字段**: - `task_id`: DashScope返回的任务ID(唯一标识) - `model`: TTS模型名称 - `voice`: 音色ID - `text`: 合成文本内容 - `audio_url`: 生成的音频文件URL - `status`: 任务状态 - `duration`: 音频时长(秒) - `format`: 音频格式(mp3/wav/pcm) - `characters`: 文本字符数 - `bill`: 费用(元) - `custom_name`: 用户自定义名称 **状态流转**: ``` PENDING (提交任务) → PROCESSING (合成中) → SUCCEEDED (成功) / FAILED (失败) ``` **使用场景**: - 短文本语音合成(< 500字) - 支持多种音色和模型 - 异步生成音频文件 --- ### 3. voice_clone_v2(声音克隆) **用途**: 异步声音克隆任务 **核心字段**: - `task_id`: DashScope返回的任务ID(唯一标识) - `voice_id`: 生成的音色ID(完成后才有) - `target_model`: 目标TTS模型 - `prefix`: 音色前缀名称 - `voice_name`: 音色名称(用户输入) - `audio_url`: 原始音频文件URL - `status`: 任务状态 - `bill`: 费用(元) **状态流转**: ``` PENDING (提交任务) → PROCESSING (训练中) → SUCCEEDED (成功,生成voice_id) / FAILED (失败) ``` **使用场景**: - 用户上传音频样本克隆声音 - 生成个性化音色 - 音色训练完成后可用于TTS **注意事项**: - `voice_id` 在任务成功完成后才有值 - 训练时间较长,需要轮询状态 --- ### 4. long_text_audio(长文本转音频) **用途**: 长文本分段合成和拼接 **核心字段**: - `task_id`: 本地生成的UUID(唯一标识) - `model`: TTS模型 - `voice`: 音色ID - `text`: 原始长文本 - `text_length`: 文本总长度 - `segment_count`: 分段数量 - `segments`: JSONB数组,存储分段信息 - `audio_url`: 最终拼接的音频URL - `status`: 任务状态 - `progress`: 进度百分比(0-100) - `duration`: 总时长(秒) - `bill`: 费用(元) **segments 字段格式**: ```json [ { "index": 1, "text": "第一段文本内容...", "task_id": "dashscope_task_id_1", "audio_url": "https://oss.../segment_1.mp3", "duration": 10.5, "status": "SUCCEEDED" }, { "index": 2, "text": "第二段文本内容...", "task_id": "dashscope_task_id_2", "audio_url": "https://oss.../segment_2.mp3", "duration": 12.3, "status": "PROCESSING" } ] ``` **状态流转**: ``` PENDING (创建任务) → PROCESSING (分段合成中,progress更新) → SUCCEEDED (所有分段完成并拼接) / FAILED (失败) ``` **使用场景**: - 长文本(> 500字)语音合成 - 自动分段处理 - 实时进度反馈 - 最终音频拼接 **处理流程**: 1. 将长文本分段(每段 < 500字) 2. 为每段创建独立的TTS任务 3. 更新 segments 数组和 progress 4. 所有分段完成后拼接音频 5. 更新 audio_url 和 status --- ## 统一状态码 所有表使用相同的状态码: | 状态 | 说明 | 可操作 | |------|------|--------| | PENDING | 任务已创建,等待处理 | 可取消 | | PROCESSING | 任务处理中 | 可查询进度 | | SUCCEEDED | 任务成功完成 | 可下载结果 | | FAILED | 任务失败 | 查看 error_message | ## 与旧表的关系 | 新表 | 旧表 | 关系 | |------|------|------| | asr_recognition_v2 | asr_task + asr_recognition | 合并并统一为异步 | | audio_synthesis_v2 | audio_synthesis | 添加异步支持 | | voice_clone_v2 | voice_clone | 添加 task_id 字段 | | long_text_audio | - | 全新功能 | **迁移策略**: - 旧表保持不变,现有服务继续使用 - 新功能使用新表 - 逐步迁移旧数据到新表 - 最终废弃旧表(需要评估时机) ## 索引设计 所有表都有以下索引: - `user_id` - 用户查询优化 - `task_id` - 任务查询优化(唯一索引) - `status` - 状态过滤优化 - `created_at` - 时间排序优化(降序) ## API 设计建议 ### 创建任务 ``` POST /api/v2/audio/synthesis POST /api/v2/audio/recognition POST /api/v2/audio/voice-clone POST /api/v2/audio/long-text ``` ### 查询任务状态 ``` GET /api/v2/audio/task/{task_id} ``` ### 查询用户任务列表 ``` GET /api/v2/audio/tasks?type=synthesis&status=SUCCEEDED&page=1&size=20 ``` ### 取消任务 ``` DELETE /api/v2/audio/task/{task_id} ``` ## 前端轮询建议 ```typescript // 轮询间隔建议 const POLL_INTERVALS = { PENDING: 2000, // 2秒 PROCESSING: 3000, // 3秒 SUCCEEDED: 0, // 停止轮询 FAILED: 0 // 停止轮询 }; // 最大轮询次数 const MAX_POLL_COUNT = 100; // 5分钟(3秒 * 100) ``` ## 费用计算 所有表都有 `bill` 字段记录费用: - 语音识别:按音频时长计费 - 语音合成:按字符数计费 - 声音克隆:固定费用 - 长文本转音频:按总字符数计费 ## 数据清理策略 建议定期清理: - 失败任务:保留7天 - 成功任务:保留30天 - 音频文件:保留30天后移至冷存储 ## 监控指标 建议监控: - 任务成功率:SUCCEEDED / (SUCCEEDED + FAILED) - 平均处理时长:completed_at - created_at - 任务积压:status = PENDING 的数量 - 费用统计:SUM(bill) 按日/月统计