媒体处理服务.md 21 KB

媒体处理服务

本文引用的文件

  • server/src/app.ts
  • server/src/config/index.ts
  • server/src/modules/audioedit/audioedit.controller.ts
  • server/src/modules/audioedit/audioedit.service.ts
  • server/src/services/ffmpeg.processor.ts
  • server/src/services/storage.service.ts
  • server/src/services/queue.service.ts
  • server/src/services/memory-queue.ts
  • server/src/services/redis.service.ts
  • server/src/modules/book-generator/book-queue.processor.ts
  • server/src/middleware/rate-limiter.ts
  • deploy-package/server/modules/templates/templates.controller.js
  • deploy-package/server/modules/templates/templates.service.js
  • docs/TTS成本分析报告.md

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本技术文档面向媒体处理服务,聚焦音频编辑能力、模板管理、批量处理机制与并发架构。文档系统性阐述以下主题:

  • 音频编辑:裁剪、合并、信息查询等接口与实现要点
  • 模板管理:模板分类、增删改查、内容渲染与扩展
  • 批量处理:队列服务、并发控制、进度跟踪与错误恢复
  • 音频处理算法:格式转换、采样率调整、音量标准化、降噪与混响思路
  • 资源调度与内存优化:存储抽象、临时文件清理、Redis 缓存与回退策略
  • 质量评估与成本分析:TTS 成本模型、套餐定价与成本控制

项目结构

后端采用 Koa 应用,模块化组织路由与服务层,统一通过 app.ts 注册路由与中间件,并在启动时初始化队列、存储与监控。

graph TB
A["应用入口<br/>server/src/app.ts"] --> B["中间件与路由注册"]
B --> C["音频编辑模块<br/>audioedit.controller.ts"]
B --> D["模板管理模块<br/>templates.controller.js"]
B --> E["书籍生成队列处理器<br/>book-queue.processor.ts"]
B --> F["TTS/视频生成相关路由<br/>app.ts 路由挂载"]
subgraph "服务层"
G["FFmpeg 处理器<br/>ffmpeg.processor.ts"]
H["存储服务<br/>storage.service.ts"]
I["队列服务<br/>queue.service.ts"]
J["内存队列回退<br/>memory-queue.ts"]
K["Redis 服务<br/>redis.service.ts"]
end
C --> G
C --> H
E --> I
E --> J
I --> K

图表来源

  • server/src/app.ts:100-128
  • server/src/modules/audioedit/audioedit.controller.ts:10-101
  • server/src/services/ffmpeg.processor.ts:24-379
  • server/src/services/storage.service.ts:13-278
  • server/src/services/queue.service.ts:48-347
  • server/src/services/memory-queue.ts:17-119
  • server/src/services/redis.service.ts:3-274
  • server/src/modules/book-generator/book-queue.processor.ts:48-83

章节来源

  • server/src/app.ts:100-130

核心组件

  • 音频编辑控制器与服务:提供裁剪、合并、信息查询等接口与模拟实现
  • FFmpeg 处理器:封装下载、合并、转码、裁剪、音量调整、时长探测、音视频混合等操作
  • 存储服务:统一 OSS/本地存储,支持上传、下载、删除、签名 URL、本地目录管理
  • 队列服务:基于 Bull 的 Redis 队列,提供任务添加、状态查询、进度回调与统计
  • 内存队列:Redis 不可用时的回退实现,维持基本并发与处理
  • Redis 服务:连接管理、键值操作、健康检测与断开
  • 书籍生成队列处理器:任务处理器、并发控制、进度事件与中断恢复
  • 速率限制中间件:基于内存或 Redis 的限流器,支持多场景限流
  • 模板管理:模板分类、增删改查、内容渲染

章节来源

  • server/src/modules/audioedit/audioedit.controller.ts:10-101
  • server/src/modules/audioedit/audioedit.service.ts:4-49
  • server/src/services/ffmpeg.processor.ts:24-379
  • server/src/services/storage.service.ts:13-278
  • server/src/services/queue.service.ts:48-347
  • server/src/services/memory-queue.ts:17-119
  • server/src/services/redis.service.ts:3-274
  • server/src/modules/book-generator/book-queue.processor.ts:16-83
  • server/src/middleware/rate-limiter.ts:17-120
  • deploy-package/server/modules/templates/templates.controller.js:13-167
  • deploy-package/server/modules/templates/templates.service.js:4-103

架构总览

媒体处理服务采用“控制器-服务-处理器-存储”的分层架构,结合队列与 Redis 实现高并发与可扩展的批处理能力。FFmpeg 处理器负责具体音视频操作,存储服务屏蔽 OSS/本地差异,队列服务保障任务有序执行与进度跟踪。

graph TB
subgraph "接入层"
R["Koa 路由<br/>app.ts"]
AC["音频编辑控制器<br/>audioedit.controller.ts"]
TC["模板控制器<br/>templates.controller.js"]
end
subgraph "领域服务"
AS["音频编辑服务<br/>audioedit.service.ts"]
QS["队列服务<br/>queue.service.ts"]
MQ["内存队列<br/>memory-queue.ts"]
RS["Redis 服务<br/>redis.service.ts"]
FS["FFmpeg 处理器<br/>ffmpeg.processor.ts"]
SS["存储服务<br/>storage.service.ts"]
end
subgraph "生成与处理"
BG["书籍生成队列处理器<br/>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
  • server/src/modules/audioedit/audioedit.controller.ts:10-101
  • server/src/modules/audioedit/audioedit.service.ts:4-49
  • server/src/services/queue.service.ts:48-347
  • server/src/services/memory-queue.ts:17-119
  • server/src/services/redis.service.ts:3-274
  • server/src/services/ffmpeg.processor.ts:24-379
  • server/src/services/storage.service.ts:13-278
  • server/src/modules/book-generator/book-queue.processor.ts:48-83

详细组件分析

音频编辑模块

  • 裁剪:接收音频 ID 与起止时间,校验参数合法性后返回模拟结果
  • 合并:接收音频 ID 列表与顺序数组,返回合并结果与估算时长
  • 信息查询:返回音频时长、大小、格式、码率等基础信息

    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
  • server/src/modules/audioedit/audioedit.service.ts:8-34

章节来源

  • server/src/modules/audioedit/audioedit.controller.ts:10-101
  • server/src/modules/audioedit/audioedit.service.ts:4-49

FFmpeg 处理器

  • 下载远程文件至本地临时目录,支持本地路径与 HTTP 地址
  • 合并音频:支持 mp3/wav 输出,使用文件列表与 concat demuxer
  • 音视频混合:支持背景音乐叠加与主音频替换
  • 时长探测:使用 ffprobe 获取音频时长
  • 格式转换:支持 mp3/wav/aac,可指定比特率
  • 裁剪:基于起始时间与持续时间生成片段
  • 音量调整:通过 volume 滤镜调整倍数
  • 临时文件清理:下载与处理完成后清理磁盘空间

    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
  • server/src/services/ffmpeg.processor.ts:346-375

章节来源

  • server/src/services/ffmpeg.processor.ts:24-379

存储服务

  • 统一 OSS/本地存储接口:上传音频、视频、封面与通用文件
  • 支持 Buffer 上传与下载,删除单文件/目录
  • 生成签名 URL(OSS),本地存储直接返回访问路径
  • 本地存储目录结构:/uploads/{category}/{id}/filename
  • 存储类型可通过环境变量切换

    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

章节来源

  • server/src/services/storage.service.ts:13-278

队列服务与并发控制

  • 队列类型:音频生成、视频生成、书籍生成、邮件发送
  • 任务状态:等待、活跃、完成、失败、延迟
  • Redis 队列优先,失败则回退内存队列
  • 进度回调:支持注册回调并在任务状态变更时触发
  • 统计与运维:获取队列统计、清空、暂停/恢复、优雅关闭

    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
  • server/src/services/memory-queue.ts:26-46

章节来源

  • server/src/services/queue.service.ts:48-347
  • server/src/services/memory-queue.ts:17-119

书籍生成队列处理器与中断恢复

  • 处理器:并发 3,捕获进度、完成、失败事件,更新书籍状态
  • 中断恢复:启动时扫描处于生成阶段的书籍,重新入队继续生成

    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
  • server/src/modules/book-generator/book-queue.processor.ts:88-124

章节来源

  • server/src/modules/book-generator/book-queue.processor.ts:16-83
  • server/src/modules/book-generator/book-queue.processor.ts:88-124

模板管理系统

  • 模板分类与列表:支持按分类筛选与总数统计
  • CRUD:创建、更新、删除、按 ID 查询
  • 内容渲染:模板字符串占位符替换(示例:{{xxx}})

    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
  • deploy-package/server/modules/templates/templates.service.js:4-103

章节来源

  • deploy-package/server/modules/templates/templates.controller.js:13-167
  • deploy-package/server/modules/templates/templates.service.js:4-103

速率限制中间件

  • 支持内存与 Redis 两种限流器,自动选择
  • 提供 API 全局限流、登录限流、短信验证码限流、TTS 限流、文件上传限流
  • 429 响应包含 Retry-After 与提示信息

章节来源

  • server/src/middleware/rate-limiter.ts:17-120

依赖关系分析

  • 控制器依赖服务:audioedit.controller 依赖 audioedit.service
  • 服务依赖处理器与存储:audioedit.service 调用 FFmpeg 处理器与存储服务
  • 队列依赖 Redis/内存:queue.service 优先 Redis,失败回退 memory-queue
  • 书籍生成处理器依赖队列与存储:book-queue.processor 调用队列与 FFmpeg/存储
  • 应用入口集中注册路由与中间件,统一初始化

    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
  • server/src/modules/audioedit/audioedit.service.ts:4-49
  • server/src/services/ffmpeg.processor.ts:24-379
  • server/src/services/storage.service.ts:13-278
  • server/src/services/queue.service.ts:48-347
  • server/src/services/memory-queue.ts:17-119
  • server/src/services/redis.service.ts:3-274
  • server/src/modules/book-generator/book-queue.processor.ts:48-83
  • server/src/app.ts:100-128

章节来源

  • server/src/app.ts:100-130

性能考量

  • 并发与超时:队列任务针对不同场景设置超时(音频 5 分钟、视频 10 分钟、书籍 2 小时)
  • 临时文件管理:FFmpeg 处理器在 finally 中清理临时文件,避免磁盘占用
  • 存储切换:通过环境变量切换 OSS/本地,便于测试与生产解耦
  • 限流策略:对高频接口进行限流,防止突发流量导致资源耗尽
  • 进度回调:任务进度通过队列事件上报,前端可实时展示

章节来源

  • server/src/services/queue.service.ts:166-190
  • server/src/services/ffmpeg.processor.ts:109
  • server/src/services/storage.service.ts:17-28
  • server/src/middleware/rate-limiter.ts:77-120

故障排查指南

  • 队列不可用:Redis 不可用时自动回退内存队列,检查 Redis 连接状态与日志
  • 任务失败:查看队列失败事件与书籍状态更新,定位具体环节
  • 存储异常:确认存储类型与路径,OSS 需检查凭证与网络连通性
  • 临时文件未清理:检查清理逻辑与权限,必要时手动清理临时目录
  • 限流触发:根据 429 响应头 Retry-After 调整请求节奏

章节来源

  • server/src/services/queue.service.ts:53-66
  • server/src/modules/book-generator/book-queue.processor.ts:66-74
  • server/src/services/ffmpeg.processor.ts:346-375
  • server/src/middleware/rate-limiter.ts:52-71

结论

媒体处理服务以清晰的分层架构与可扩展的队列机制为基础,结合 FFmpeg 处理器与统一存储抽象,实现了音频编辑、模板管理与批量处理的核心能力。通过 Redis/内存双轨队列与进度回调,系统具备良好的并发控制与可观测性。建议在生产环境中完善错误恢复策略、引入更细粒度的质量评估指标与成本控制模块。

附录

处理流程说明(音频编辑)

  • 裁剪:校验参数 → 下载 → 裁剪 → 上传 → 返回结果
  • 合并:校验参数 → 下载 → 构建列表 → 合并 → 上传 → 返回结果
  • 信息查询:返回预设信息(时长、大小、格式、码率)

章节来源

  • server/src/modules/audioedit/audioedit.controller.ts:10-101
  • server/src/modules/audioedit/audioedit.service.ts:8-48
  • server/src/services/ffmpeg.processor.ts:69-122

参数配置指南

  • 存储类型:通过环境变量切换 OSS/本地
  • 队列超时:按任务类型配置超时时间
  • 限流策略:按接口场景配置限流参数

章节来源

  • server/src/services/storage.service.ts:17-28
  • server/src/services/queue.service.ts:166-190
  • server/src/middleware/rate-limiter.ts:77-120

质量评估标准与成本分析

  • TTS 成本模型:AI 生成成本 + TTS 合成成本
  • 套餐定价:覆盖成本与合理利润,提供多档位套餐
  • 成本控制:每日使用限制、单次生成上限、服务商切换策略

章节来源

  • docs/TTS成本分析报告.md:32-152
  • docs/TTS成本分析报告.md:156-329