插件开发
本文引用的文件
- server/src/app.ts
- server/src/config/index.ts
- server/src/types/index.ts
- server/src/modules/tts/tts.controller.ts
- server/src/modules/tts/tts.service.ts
- server/src/modules/tts/aliyun.provider.ts
- server/src/modules/tts/minimax.provider.ts
- server/src/modules/tts/mock.provider.ts
- server/src/modules/tts/aliyun-realtime.provider.ts
- server/src/modules/tts/audio-merger.ts
- server/src/services/storage.service.ts
- server/src/services/oss.service.ts
- server/src/middleware/errorHandler.js
目录
- 简介
- 项目结构
- 核心组件
- 架构总览
- 详细组件分析
- 依赖关系分析
- 性能考量
- 故障排查指南
- 结论
- 附录
简介
本文件面向希望为AI有声书生成平台开发“插件”的工程师,系统讲解如何开发三类插件:
- TTS音色提供商插件:对接不同厂商的语音合成能力
- AI模型插件:扩展文本生成、理解等LLM能力
- 存储插件:统一管理本地与云存储(如OSS)
文档覆盖插件架构设计、接口规范、生命周期管理、注册机制、依赖注入与配置管理,并提供开发模板、最佳实践与调试技巧,以及插件间通信、错误处理与性能优化策略。
项目结构
平台采用模块化与分层架构:
图表来源
- server/src/app.ts:1-194
- server/src/modules/tts/tts.controller.ts:1-274
- server/src/modules/tts/tts.service.ts:1-715
- server/src/modules/tts/aliyun.provider.ts:1-152
- server/src/modules/tts/minimax.provider.ts:1-280
- server/src/modules/tts/mock.provider.ts:1-61
- server/src/modules/tts/aliyun-realtime.provider.ts:1-158
- server/src/modules/tts/audio-merger.ts:1-86
- server/src/services/storage.service.ts:1-278
- server/src/services/oss.service.ts:1-256
- server/src/config/index.ts:1-117
- server/src/types/index.ts:1-124
章节来源
- server/src/app.ts:1-194
- server/src/config/index.ts:1-117
- server/src/types/index.ts:1-124
核心组件
- 应用入口与中间件
- 负责全局中间件(CORS、日志、安全、限流、Sentry)、静态资源挂载、路由注册与优雅关闭
- 初始化数据库、Redis、存储、WebSocket、书籍生成队列
- 配置中心
- 统一加载.env与models.json,提供模型枚举、启用筛选、错误识别与自动切换辅助
- TTS控制器与服务
- 控制器负责参数校验、配额检查、路由转发
- 服务负责文本分段、并发合成、合并、上传、状态查询、回调与WebSocket推送
- 存储服务
- 抽象本地与OSS,提供上传/下载/删除/签名URL/目录清理等能力
- 插件(TTS提供商)
- 阿里云HTTP/TTS、MiniMax异步、Mock占位、阿里云实时WebSocket
- 音频合并器
章节来源
- server/src/app.ts:1-194
- server/src/config/index.ts:1-117
- server/src/modules/tts/tts.controller.ts:1-274
- server/src/modules/tts/tts.service.ts:1-715
- server/src/services/storage.service.ts:1-278
- server/src/modules/tts/aliyun.provider.ts:1-152
- server/src/modules/tts/minimax.provider.ts:1-280
- server/src/modules/tts/mock.provider.ts:1-61
- server/src/modules/tts/aliyun-realtime.provider.ts:1-158
- server/src/modules/tts/audio-merger.ts:1-86
架构总览
TTS插件体系通过“服务工厂 + 插件实现 + 统一存储”的方式解耦。服务层根据配置与优先级选择具体插件,插件负责与外部API交互,最终由存储服务统一对外暴露URL。
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "TTS控制器"
participant Svc as "TTS服务"
participant Prov as "TTS插件(阿里云/MiniMax/Mock)"
participant Merge as "音频合并器"
participant Store as "存储服务"
participant OSS as "OSS服务"
Client->>Ctrl : "POST /api/tts/generate"
Ctrl->>Svc : "generateAudio(userId,text,voiceId,params,options)"
Svc->>Svc : "选择插件(优先级/配置)"
Svc->>Prov : "synthesize(分段,参数,输出路径)"
Prov-->>Svc : "返回本地文件路径或云端URL"
Svc->>Merge : "合并多段音频"
Merge-->>Svc : "输出合并文件"
Svc->>Store : "uploadAudio(合并文件,audioId)"
Store->>OSS : "OSS上传(可选)"
Store-->>Svc : "返回访问URL"
Svc-->>Ctrl : "{audioId,audioUrl}"
Ctrl-->>Client : "任务已创建"
图表来源
- server/src/modules/tts/tts.controller.ts:52-127
- server/src/modules/tts/tts.service.ts:200-542
- server/src/modules/tts/aliyun.provider.ts:21-150
- server/src/modules/tts/minimax.provider.ts:234-278
- server/src/modules/tts/mock.provider.ts:12-60
- server/src/modules/tts/audio-merger.ts:9-36
- server/src/services/storage.service.ts:43-49
- server/src/services/oss.service.ts:91-94
详细组件分析
TTS控制器(接口与生命周期)
- 职责
- 参数校验、配额检查、路由转发至服务层
- 生命周期:请求进入 -> 校验 -> 调用服务 -> 返回任务ID/状态
关键点
图表来源
- server/src/modules/tts/tts.controller.ts:52-127
章节来源
- server/src/modules/tts/tts.controller.ts:1-274
TTS服务(工厂、优先级与回退)
- 职责
- 文本分段、并发合成、合并、上传、状态查询、回调与WebSocket推送
- 插件优先级:MiniMax -> 阿里云HTTP -> Mock
- 额度限制错误自动回退到下一个插件
关键点
- MiniMax异步长文本无需分段;阿里云HTTP需分段
- 并发策略:MiniMax串行,其他并行
云端URL降级到本地文件再统一上传
flowchart TD
A["输入: text, voiceId, voiceParams, options"] --> B["构建优先级列表"]
B --> C{"逐个尝试插件"}
C --> |额度限制| D["记录最后错误, 继续下一个"]
C --> |真实失败| E["抛出错误, 停止"]
C --> |成功| F["合并音频 -> 上传存储 -> 更新记录 -> 回调/推送"]
D --> C
F --> G["返回 {audioId,audioUrl,bookId}"]
图表来源
- server/src/modules/tts/tts.service.ts:304-542
章节来源
- server/src/modules/tts/tts.service.ts:1-715
TTS插件(接口规范与实现要点)
- 接口规范
- 统一方法:synthesize(text, voiceId, params, outputPath, retries?, modelOverride?)
- 返回值:本地文件路径或“cloud:”前缀的云端URL
- 错误处理:区分速率限制与服务错误,支持指数退避重试
实现要点
- 阿里云HTTP:支持指令模型参数拼装、云端URL回退
- MiniMax异步:创建任务 -> 轮询 -> tar提取MP3
- Mock:FFmpeg生成占位音频,失败时写入最小MP3头
阿里云实时:WebSocket流式合成,适合长文本
classDiagram
class TtsProvider {
+synthesize(text, voiceId, params, outputPath, retries, modelOverride) string
}
class AliyunTtsProvider {
-apiKey string
-model string
-voice string
}
class MiniMaxTtsProvider {
-apiKey string
}
class MockTtsProvider
class AliyunRealtimeTtsProvider {
-apiKey string
-model string
-voice string
}
TtsProvider <|.. AliyunTtsProvider
TtsProvider <|.. MiniMaxTtsProvider
TtsProvider <|.. MockTtsProvider
TtsProvider <|.. AliyunRealtimeTtsProvider
图表来源
- server/src/modules/tts/aliyun.provider.ts:9-152
- server/src/modules/tts/minimax.provider.ts:42-280
- server/src/modules/tts/mock.provider.ts:11-61
- server/src/modules/tts/aliyun-realtime.provider.ts:11-158
章节来源
- server/src/modules/tts/aliyun.provider.ts:1-152
- server/src/modules/tts/minimax.provider.ts:1-280
- server/src/modules/tts/mock.provider.ts:1-61
- server/src/modules/tts/aliyun-realtime.provider.ts:1-158
存储插件(统一抽象与OSS)
- 职责
- 本地与OSS无缝切换,提供上传/下载/删除/签名URL/目录清理
- 通过环境变量STORAGE_TYPE切换模式
关键点
- OSS服务封装OSS SDK,支持对象键规范化、CDN域名回源
存储服务在本地模式下直接写入uploads目录
classDiagram
class StorageService {
-storageType StorageType
+setStorageType(type)
+getStorageType() StorageType
+uploadAudio(localPath, audioId) string
+uploadVideo(localPath, videoId) string
+uploadCover(localPath, bookId) string
+uploadFile(localPath, category, id) string
+uploadBuffer(buffer, objectKey, contentType) string
+deleteFile(url)
+deleteDirectory(prefix, id)
+downloadFile(url) Buffer
+getSignedUrl(url, expires) string
+testConnection() boolean
}
class OSSService {
-client OSS
-bucket string
-cdnDomain string
+uploadFile(localPath, objectKey) string
+uploadBuffer(buffer, objectKey, contentType) string
+uploadAudio(localPath, audioId) string
+uploadVideo(localPath, videoId) string
+uploadCover(localPath, bookId) string
+deleteFile(objectKey)
+deleteDirectory(prefix)
+getSignedUrl(objectKey, expires) string
+downloadFile(objectKey) Buffer
+getFileUrl(objectKey) string
+testConnection() boolean
}
StorageService --> OSSService : "OSS模式委托"
图表来源
- server/src/services/storage.service.ts:13-278
- server/src/services/oss.service.ts:13-256
章节来源
- server/src/services/storage.service.ts:1-278
- server/src/services/oss.service.ts:1-256
音频合并器(跨域与本地处理)
- 职责
- 合并本地或多段远程URL音频,计算时长
- 远程URL通过FFmpegProcessor处理,本地使用FFmpeg concat
- 关键点
- 单文件直接复制,避免不必要的转码
- 输出格式自动适配
章节来源
- server/src/modules/tts/audio-merger.ts:1-86
配置与类型(模型与参数)
- 配置中心
- 加载.env与models.json,提供模型枚举、启用筛选、错误识别与自动切换辅助
- TTS相关:DashScope API Key、模型列表、实时模型开关
- 类型定义
- VoiceParams、Voice、IUser、IAudio、ApiResponse等
章节来源
- server/src/config/index.ts:1-117
- server/src/types/index.ts:1-124
依赖关系分析
- 组件耦合
- 控制器仅依赖服务接口,低耦合
- 服务层通过工厂选择插件,便于替换与扩展
- 存储服务对上层透明,对下层可替换
- 外部依赖
- HTTP/WS调用第三方TTS
- FFmpeg/ffprobe用于合并与时长探测
- OSS SDK用于对象存储
循环依赖
图表来源
- server/src/app.ts:1-194
- server/src/modules/tts/tts.controller.ts:1-274
- server/src/modules/tts/tts.service.ts:1-715
- server/src/modules/tts/aliyun.provider.ts:1-152
- server/src/modules/tts/minimax.provider.ts:1-280
- server/src/modules/tts/mock.provider.ts:1-61
- server/src/modules/tts/aliyun-realtime.provider.ts:1-158
- server/src/modules/tts/audio-merger.ts:1-86
- server/src/services/storage.service.ts:1-278
- server/src/services/oss.service.ts:1-256
- server/src/config/index.ts:1-117
- server/src/types/index.ts:1-124
性能考量
- 并发与批处理
- 非MiniMax场景采用并行分段合成,提升吞吐
- MiniMax异步轮询较长,串行避免超时
- 重试与退避
- 存储与网络
- 云端URL优先,失败时本地降级并统一上传
- OSS签名URL用于私有桶下载
- 工具链
- FFmpeg/ffprobe用于高效合并与时长探测
章节来源
- server/src/modules/tts/tts.service.ts:348-383
- server/src/modules/tts/aliyun.provider.ts:125-141
- server/src/services/storage.service.ts:184-193
- server/src/modules/tts/audio-merger.ts:69-85
故障排查指南
- 错误处理
- 控制器与服务层均抛出自定义错误,便于统一拦截
- 速率限制自动回退,非速率限制直接失败
- 日志与诊断
- 服务层写入本地日志文件,便于定位
- 应用启动时打印存储模式、上传目录、缓存状态
- 常见问题
- API Key缺失:插件构造时抛错,触发Mock回退
- 云端URL下载失败:自动降级到本地文件再上传
- WebSocket实时合成失败:检查权限与网络,考虑禁用实时模式
章节来源
- server/src/middleware/errorHandler.js:1-41
- server/src/modules/tts/tts.service.ts:268-279
- server/src/modules/tts/aliyun.provider.ts:118-146
- server/src/services/storage.service.ts:160-176
- server/src/app.ts:133-194
结论
平台通过“服务工厂 + 插件实现 + 统一存储”的架构,实现了TTS能力的可插拔扩展。开发者只需遵循统一接口与生命周期规范,即可快速接入新的TTS提供商、AI模型与存储后端。配合完善的错误处理、重试与性能优化策略,可在生产环境中稳定运行。
附录
插件开发模板(TTS提供商)
- 必备接口
- 构造函数:读取配置(API Key/模型/音色映射)
- synthesize(text, voiceId, params, outputPath, retries?, modelOverride?):返回本地路径或“cloud:”URL
- 建议实现
- 明确错误类型(速率限制/服务错误/参数错误)
- 支持重试与指数退避
- 提供最小可用的Mock实现以便联调
章节来源
- server/src/modules/tts/aliyun.provider.ts:15-150
- server/src/modules/tts/minimax.provider.ts:45-278
- server/src/modules/tts/mock.provider.ts:11-61
插件注册机制与依赖注入
- 注册机制
- 服务层通过工厂函数选择插件,无需硬编码依赖
- 配置中心提供模型与供应商列表,便于动态切换
- 依赖注入
- 插件通过构造函数注入配置
- 存储服务通过单例注入,对外透明
章节来源
- server/src/modules/tts/tts.service.ts:163-190
- server/src/config/index.ts:69-117
- server/src/services/storage.service.ts:13-28
配置管理
- 环境变量
- STORAGE_TYPE:存储模式(oss/local)
- DashScope/OSS相关环境变量:API Key、区域、Bucket、Endpoint、CDN域名
- 模型配置
- models.json统一管理供应商与模型,支持启用/禁用与类型过滤
章节来源
- server/src/services/storage.service.ts:16-28
- server/src/config/index.ts:83-117
插件间通信与事件
- WebSocket事件
- 生成完成后推送“音频生成完成”事件,携带bookId与chapterId
- 回调机制
- onComplete回调在服务层执行,确保异步流程可控
章节来源
- server/src/modules/tts/tts.service.ts:510-515
- server/src/modules/tts/tts.service.ts:497-508
最佳实践
- 插件实现
- 明确错误分类与重试策略
- 提供Mock实现,便于本地联调
- 服务层
- 优先级与回退策略清晰,避免单一故障点
- 统一上传与状态查询,保证一致性
- 存储层
- 云端URL优先,失败时本地降级
- OSS签名URL用于私有桶下载
章节来源
- server/src/modules/tts/aliyun.provider.ts:118-146
- server/src/modules/tts/minimax.provider.ts:258-275
- server/src/services/storage.service.ts:39-49