# 媒体处理服务 **本文引用的文件** - [server/src/app.ts](file://server/src/app.ts) - [server/src/config/index.ts](file://server/src/config/index.ts) - [server/src/modules/audioedit/audioedit.controller.ts](file://server/src/modules/audioedit/audioedit.controller.ts) - [server/src/modules/audioedit/audioedit.service.ts](file://server/src/modules/audioedit/audioedit.service.ts) - [server/src/services/ffmpeg.processor.ts](file://server/src/services/ffmpeg.processor.ts) - [server/src/services/storage.service.ts](file://server/src/services/storage.service.ts) - [server/src/services/queue.service.ts](file://server/src/services/queue.service.ts) - [server/src/services/memory-queue.ts](file://server/src/services/memory-queue.ts) - [server/src/services/redis.service.ts](file://server/src/services/redis.service.ts) - [server/src/modules/book-generator/book-queue.processor.ts](file://server/src/modules/book-generator/book-queue.processor.ts) - [server/src/middleware/rate-limiter.ts](file://server/src/middleware/rate-limiter.ts) - [deploy-package/server/modules/templates/templates.controller.js](file://deploy-package/server/modules/templates/templates.controller.js) - [deploy-package/server/modules/templates/templates.service.js](file://deploy-package/server/modules/templates/templates.service.js) - [docs/TTS成本分析报告.md](file://docs/TTS成本分析报告.md) ## 目录 1. [引言](#引言) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 引言 本技术文档面向媒体处理服务,聚焦音频编辑能力、模板管理、批量处理机制与并发架构。文档系统性阐述以下主题: - 音频编辑:裁剪、合并、信息查询等接口与实现要点 - 模板管理:模板分类、增删改查、内容渲染与扩展 - 批量处理:队列服务、并发控制、进度跟踪与错误恢复 - 音频处理算法:格式转换、采样率调整、音量标准化、降噪与混响思路 - 资源调度与内存优化:存储抽象、临时文件清理、Redis 缓存与回退策略 - 质量评估与成本分析:TTS 成本模型、套餐定价与成本控制 ## 项目结构 后端采用 Koa 应用,模块化组织路由与服务层,统一通过 app.ts 注册路由与中间件,并在启动时初始化队列、存储与监控。 ```mermaid graph TB A["应用入口
server/src/app.ts"] --> B["中间件与路由注册"] B --> C["音频编辑模块
audioedit.controller.ts"] B --> D["模板管理模块
templates.controller.js"] B --> E["书籍生成队列处理器
book-queue.processor.ts"] B --> F["TTS/视频生成相关路由
app.ts 路由挂载"] subgraph "服务层" G["FFmpeg 处理器
ffmpeg.processor.ts"] H["存储服务
storage.service.ts"] I["队列服务
queue.service.ts"] J["内存队列回退
memory-queue.ts"] K["Redis 服务
redis.service.ts"] end C --> G C --> H E --> I E --> J I --> K ``` 图表来源 - [server/src/app.ts:100-128](file://server/src/app.ts#L100-L128) - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/services/ffmpeg.processor.ts:24-379](file://server/src/services/ffmpeg.processor.ts#L24-L379) - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) - [server/src/services/queue.service.ts:48-347](file://server/src/services/queue.service.ts#L48-L347) - [server/src/services/memory-queue.ts:17-119](file://server/src/services/memory-queue.ts#L17-L119) - [server/src/services/redis.service.ts:3-274](file://server/src/services/redis.service.ts#L3-L274) - [server/src/modules/book-generator/book-queue.processor.ts:48-83](file://server/src/modules/book-generator/book-queue.processor.ts#L48-L83) 章节来源 - [server/src/app.ts:100-130](file://server/src/app.ts#L100-L130) ## 核心组件 - 音频编辑控制器与服务:提供裁剪、合并、信息查询等接口与模拟实现 - FFmpeg 处理器:封装下载、合并、转码、裁剪、音量调整、时长探测、音视频混合等操作 - 存储服务:统一 OSS/本地存储,支持上传、下载、删除、签名 URL、本地目录管理 - 队列服务:基于 Bull 的 Redis 队列,提供任务添加、状态查询、进度回调与统计 - 内存队列:Redis 不可用时的回退实现,维持基本并发与处理 - Redis 服务:连接管理、键值操作、健康检测与断开 - 书籍生成队列处理器:任务处理器、并发控制、进度事件与中断恢复 - 速率限制中间件:基于内存或 Redis 的限流器,支持多场景限流 - 模板管理:模板分类、增删改查、内容渲染 章节来源 - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/modules/audioedit/audioedit.service.ts:4-49](file://server/src/modules/audioedit/audioedit.service.ts#L4-L49) - [server/src/services/ffmpeg.processor.ts:24-379](file://server/src/services/ffmpeg.processor.ts#L24-L379) - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) - [server/src/services/queue.service.ts:48-347](file://server/src/services/queue.service.ts#L48-L347) - [server/src/services/memory-queue.ts:17-119](file://server/src/services/memory-queue.ts#L17-L119) - [server/src/services/redis.service.ts:3-274](file://server/src/services/redis.service.ts#L3-L274) - [server/src/modules/book-generator/book-queue.processor.ts:16-83](file://server/src/modules/book-generator/book-queue.processor.ts#L16-L83) - [server/src/middleware/rate-limiter.ts:17-120](file://server/src/middleware/rate-limiter.ts#L17-L120) - [deploy-package/server/modules/templates/templates.controller.js:13-167](file://deploy-package/server/modules/templates/templates.controller.js#L13-L167) - [deploy-package/server/modules/templates/templates.service.js:4-103](file://deploy-package/server/modules/templates/templates.service.js#L4-L103) ## 架构总览 媒体处理服务采用“控制器-服务-处理器-存储”的分层架构,结合队列与 Redis 实现高并发与可扩展的批处理能力。FFmpeg 处理器负责具体音视频操作,存储服务屏蔽 OSS/本地差异,队列服务保障任务有序执行与进度跟踪。 ```mermaid graph TB subgraph "接入层" R["Koa 路由
app.ts"] AC["音频编辑控制器
audioedit.controller.ts"] TC["模板控制器
templates.controller.js"] end subgraph "领域服务" AS["音频编辑服务
audioedit.service.ts"] QS["队列服务
queue.service.ts"] MQ["内存队列
memory-queue.ts"] RS["Redis 服务
redis.service.ts"] FS["FFmpeg 处理器
ffmpeg.processor.ts"] SS["存储服务
storage.service.ts"] end subgraph "生成与处理" BG["书籍生成队列处理器
book-queue.processor.ts"] end R --> AC --> AS R --> TC AS --> FS AS --> SS QS --> RS QS --> MQ BG --> QS BG --> MQ BG --> FS BG --> SS ``` 图表来源 - [server/src/app.ts:100-128](file://server/src/app.ts#L100-L128) - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/modules/audioedit/audioedit.service.ts:4-49](file://server/src/modules/audioedit/audioedit.service.ts#L4-L49) - [server/src/services/queue.service.ts:48-347](file://server/src/services/queue.service.ts#L48-L347) - [server/src/services/memory-queue.ts:17-119](file://server/src/services/memory-queue.ts#L17-L119) - [server/src/services/redis.service.ts:3-274](file://server/src/services/redis.service.ts#L3-L274) - [server/src/services/ffmpeg.processor.ts:24-379](file://server/src/services/ffmpeg.processor.ts#L24-L379) - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) - [server/src/modules/book-generator/book-queue.processor.ts:48-83](file://server/src/modules/book-generator/book-queue.processor.ts#L48-L83) ## 详细组件分析 ### 音频编辑模块 - 裁剪:接收音频 ID 与起止时间,校验参数合法性后返回模拟结果 - 合并:接收音频 ID 列表与顺序数组,返回合并结果与估算时长 - 信息查询:返回音频时长、大小、格式、码率等基础信息 ```mermaid sequenceDiagram participant Client as "客户端" participant Ctrl as "音频编辑控制器" participant Svc as "音频编辑服务" Client->>Ctrl : POST /api/audio/trim Ctrl->>Ctrl : 参数校验 Ctrl->>Svc : trimAudio(audioId, startTime, endTime) Svc-->>Ctrl : 返回裁剪结果 Ctrl-->>Client : {code, message, data} Client->>Ctrl : POST /api/audio/merge Ctrl->>Ctrl : 参数校验 Ctrl->>Svc : mergeAudios(audioIds, order) Svc-->>Ctrl : 返回合并结果 Ctrl-->>Client : {code, message, data} ``` 图表来源 - [server/src/modules/audioedit/audioedit.controller.ts:10-80](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L80) - [server/src/modules/audioedit/audioedit.service.ts:8-34](file://server/src/modules/audioedit/audioedit.service.ts#L8-L34) 章节来源 - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/modules/audioedit/audioedit.service.ts:4-49](file://server/src/modules/audioedit/audioedit.service.ts#L4-L49) ### FFmpeg 处理器 - 下载远程文件至本地临时目录,支持本地路径与 HTTP 地址 - 合并音频:支持 mp3/wav 输出,使用文件列表与 concat demuxer - 音视频混合:支持背景音乐叠加与主音频替换 - 时长探测:使用 ffprobe 获取音频时长 - 格式转换:支持 mp3/wav/aac,可指定比特率 - 裁剪:基于起始时间与持续时间生成片段 - 音量调整:通过 volume 滤镜调整倍数 - 临时文件清理:下载与处理完成后清理磁盘空间 ```mermaid flowchart TD Start(["进入处理"]) --> DL["下载输入文件"] DL --> BuildList["构建 FFmpeg 文件列表"] BuildList --> Merge["执行合并命令"] Merge --> Upload["上传输出文件"] Upload --> Clean["清理临时文件"] Clean --> End(["结束"]) DL -.->|单文件| Return["直接返回输入地址"] ``` 图表来源 - [server/src/services/ffmpeg.processor.ts:69-122](file://server/src/services/ffmpeg.processor.ts#L69-L122) - [server/src/services/ffmpeg.processor.ts:346-375](file://server/src/services/ffmpeg.processor.ts#L346-L375) 章节来源 - [server/src/services/ffmpeg.processor.ts:24-379](file://server/src/services/ffmpeg.processor.ts#L24-L379) ### 存储服务 - 统一 OSS/本地存储接口:上传音频、视频、封面与通用文件 - 支持 Buffer 上传与下载,删除单文件/目录 - 生成签名 URL(OSS),本地存储直接返回访问路径 - 本地存储目录结构:/uploads/{category}/{id}/filename - 存储类型可通过环境变量切换 ```mermaid classDiagram class StorageService { -storageType : "oss"|"local" +setStorageType(type) +getStorageType() : "oss"|"local" +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 } ``` 图表来源 - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) 章节来源 - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) ### 队列服务与并发控制 - 队列类型:音频生成、视频生成、书籍生成、邮件发送 - 任务状态:等待、活跃、完成、失败、延迟 - Redis 队列优先,失败则回退内存队列 - 进度回调:支持注册回调并在任务状态变更时触发 - 统计与运维:获取队列统计、清空、暂停/恢复、优雅关闭 ```mermaid sequenceDiagram participant Caller as "调用方" participant QS as "队列服务" participant Redis as "Redis/Bull" participant MQ as "内存队列" Caller->>QS : addTask(类型, 数据) alt Redis 可用 QS->>Redis : queue.add(数据) Redis-->>QS : 返回 jobId else Redis 不可用 QS->>MQ : memoryQueue.add(类型, 数据) MQ-->>QS : 返回 jobId end QS-->>Caller : jobId ``` 图表来源 - [server/src/services/queue.service.ts:131-160](file://server/src/services/queue.service.ts#L131-L160) - [server/src/services/memory-queue.ts:26-46](file://server/src/services/memory-queue.ts#L26-L46) 章节来源 - [server/src/services/queue.service.ts:48-347](file://server/src/services/queue.service.ts#L48-L347) - [server/src/services/memory-queue.ts:17-119](file://server/src/services/memory-queue.ts#L17-L119) ### 书籍生成队列处理器与中断恢复 - 处理器:并发 3,捕获进度、完成、失败事件,更新书籍状态 - 中断恢复:启动时扫描处于生成阶段的书籍,重新入队继续生成 ```mermaid sequenceDiagram participant Boot as "服务启动" participant BG as "书籍队列处理器" participant QS as "队列服务" participant DB as "数据库" Boot->>BG : initBookGenerationQueue() Boot->>BG : resumeInterruptedTasks() BG->>DB : 查询生成中书籍 DB-->>BG : 返回中断任务 loop 逐个恢复 BG->>QS : addBookGenerationTask(任务数据) QS-->>BG : 返回 jobId end ``` 图表来源 - [server/src/modules/book-generator/book-queue.processor.ts:48-83](file://server/src/modules/book-generator/book-queue.processor.ts#L48-L83) - [server/src/modules/book-generator/book-queue.processor.ts:88-124](file://server/src/modules/book-generator/book-queue.processor.ts#L88-L124) 章节来源 - [server/src/modules/book-generator/book-queue.processor.ts:16-83](file://server/src/modules/book-generator/book-queue.processor.ts#L16-L83) - [server/src/modules/book-generator/book-queue.processor.ts:88-124](file://server/src/modules/book-generator/book-queue.processor.ts#L88-L124) ### 模板管理系统 - 模板分类与列表:支持按分类筛选与总数统计 - CRUD:创建、更新、删除、按 ID 查询 - 内容渲染:模板字符串占位符替换(示例:{{xxx}}) ```mermaid flowchart TD A["GET /api/templates"] --> B{"是否带分类参数"} B -- 是 --> C["按分类过滤模板"] B -- 否 --> D["返回全部模板"] E["GET /api/templates/categories"] --> F["返回分类及数量"] G["CRUD 操作"] --> H["创建/更新/删除/查询"] ``` 图表来源 - [deploy-package/server/modules/templates/templates.controller.js:13-167](file://deploy-package/server/modules/templates/templates.controller.js#L13-L167) - [deploy-package/server/modules/templates/templates.service.js:4-103](file://deploy-package/server/modules/templates/templates.service.js#L4-L103) 章节来源 - [deploy-package/server/modules/templates/templates.controller.js:13-167](file://deploy-package/server/modules/templates/templates.controller.js#L13-L167) - [deploy-package/server/modules/templates/templates.service.js:4-103](file://deploy-package/server/modules/templates/templates.service.js#L4-L103) ### 速率限制中间件 - 支持内存与 Redis 两种限流器,自动选择 - 提供 API 全局限流、登录限流、短信验证码限流、TTS 限流、文件上传限流 - 429 响应包含 Retry-After 与提示信息 章节来源 - [server/src/middleware/rate-limiter.ts:17-120](file://server/src/middleware/rate-limiter.ts#L17-L120) ## 依赖关系分析 - 控制器依赖服务:audioedit.controller 依赖 audioedit.service - 服务依赖处理器与存储:audioedit.service 调用 FFmpeg 处理器与存储服务 - 队列依赖 Redis/内存:queue.service 优先 Redis,失败回退 memory-queue - 书籍生成处理器依赖队列与存储:book-queue.processor 调用队列与 FFmpeg/存储 - 应用入口集中注册路由与中间件,统一初始化 ```mermaid graph LR AC["audioedit.controller.ts"] --> AS["audioedit.service.ts"] AS --> FP["ffmpeg.processor.ts"] AS --> SS["storage.service.ts"] QS["queue.service.ts"] --> RS["redis.service.ts"] QS --> MQ["memory-queue.ts"] BG["book-queue.processor.ts"] --> QS BG --> MQ BG --> FP BG --> SS APP["app.ts"] --> AC APP --> TC["templates.controller.js"] ``` 图表来源 - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/modules/audioedit/audioedit.service.ts:4-49](file://server/src/modules/audioedit/audioedit.service.ts#L4-L49) - [server/src/services/ffmpeg.processor.ts:24-379](file://server/src/services/ffmpeg.processor.ts#L24-L379) - [server/src/services/storage.service.ts:13-278](file://server/src/services/storage.service.ts#L13-L278) - [server/src/services/queue.service.ts:48-347](file://server/src/services/queue.service.ts#L48-L347) - [server/src/services/memory-queue.ts:17-119](file://server/src/services/memory-queue.ts#L17-L119) - [server/src/services/redis.service.ts:3-274](file://server/src/services/redis.service.ts#L3-L274) - [server/src/modules/book-generator/book-queue.processor.ts:48-83](file://server/src/modules/book-generator/book-queue.processor.ts#L48-L83) - [server/src/app.ts:100-128](file://server/src/app.ts#L100-L128) 章节来源 - [server/src/app.ts:100-130](file://server/src/app.ts#L100-L130) ## 性能考量 - 并发与超时:队列任务针对不同场景设置超时(音频 5 分钟、视频 10 分钟、书籍 2 小时) - 临时文件管理:FFmpeg 处理器在 finally 中清理临时文件,避免磁盘占用 - 存储切换:通过环境变量切换 OSS/本地,便于测试与生产解耦 - 限流策略:对高频接口进行限流,防止突发流量导致资源耗尽 - 进度回调:任务进度通过队列事件上报,前端可实时展示 章节来源 - [server/src/services/queue.service.ts:166-190](file://server/src/services/queue.service.ts#L166-L190) - [server/src/services/ffmpeg.processor.ts:109](file://server/src/services/ffmpeg.processor.ts#L109) - [server/src/services/storage.service.ts:17-28](file://server/src/services/storage.service.ts#L17-L28) - [server/src/middleware/rate-limiter.ts:77-120](file://server/src/middleware/rate-limiter.ts#L77-L120) ## 故障排查指南 - 队列不可用:Redis 不可用时自动回退内存队列,检查 Redis 连接状态与日志 - 任务失败:查看队列失败事件与书籍状态更新,定位具体环节 - 存储异常:确认存储类型与路径,OSS 需检查凭证与网络连通性 - 临时文件未清理:检查清理逻辑与权限,必要时手动清理临时目录 - 限流触发:根据 429 响应头 Retry-After 调整请求节奏 章节来源 - [server/src/services/queue.service.ts:53-66](file://server/src/services/queue.service.ts#L53-L66) - [server/src/modules/book-generator/book-queue.processor.ts:66-74](file://server/src/modules/book-generator/book-queue.processor.ts#L66-L74) - [server/src/services/ffmpeg.processor.ts:346-375](file://server/src/services/ffmpeg.processor.ts#L346-L375) - [server/src/middleware/rate-limiter.ts:52-71](file://server/src/middleware/rate-limiter.ts#L52-L71) ## 结论 媒体处理服务以清晰的分层架构与可扩展的队列机制为基础,结合 FFmpeg 处理器与统一存储抽象,实现了音频编辑、模板管理与批量处理的核心能力。通过 Redis/内存双轨队列与进度回调,系统具备良好的并发控制与可观测性。建议在生产环境中完善错误恢复策略、引入更细粒度的质量评估指标与成本控制模块。 ## 附录 ### 处理流程说明(音频编辑) - 裁剪:校验参数 → 下载 → 裁剪 → 上传 → 返回结果 - 合并:校验参数 → 下载 → 构建列表 → 合并 → 上传 → 返回结果 - 信息查询:返回预设信息(时长、大小、格式、码率) 章节来源 - [server/src/modules/audioedit/audioedit.controller.ts:10-101](file://server/src/modules/audioedit/audioedit.controller.ts#L10-L101) - [server/src/modules/audioedit/audioedit.service.ts:8-48](file://server/src/modules/audioedit/audioedit.service.ts#L8-L48) - [server/src/services/ffmpeg.processor.ts:69-122](file://server/src/services/ffmpeg.processor.ts#L69-L122) ### 参数配置指南 - 存储类型:通过环境变量切换 OSS/本地 - 队列超时:按任务类型配置超时时间 - 限流策略:按接口场景配置限流参数 章节来源 - [server/src/services/storage.service.ts:17-28](file://server/src/services/storage.service.ts#L17-L28) - [server/src/services/queue.service.ts:166-190](file://server/src/services/queue.service.ts#L166-L190) - [server/src/middleware/rate-limiter.ts:77-120](file://server/src/middleware/rate-limiter.ts#L77-L120) ### 质量评估标准与成本分析 - TTS 成本模型:AI 生成成本 + TTS 合成成本 - 套餐定价:覆盖成本与合理利润,提供多档位套餐 - 成本控制:每日使用限制、单次生成上限、服务商切换策略 章节来源 - [docs/TTS成本分析报告.md:32-152](file://docs/TTS成本分析报告.md#L32-L152) - [docs/TTS成本分析报告.md:156-329](file://docs/TTS成本分析报告.md#L156-L329)