# 视频项目模型 **本文引用的文件** - [video-generator.types.ts](file://server/src/modules/video-generator/video-generator.types.ts) - [video-generator.service.ts](file://server/src/modules/video-generator/video-generator.service.ts) - [video-generator.controller.ts](file://server/src/modules/video-generator/video-generator.controller.ts) - [video-generator.ffmpeg.ts](file://server/src/modules/video-generator/video-generator.ffmpeg.ts) - [schema.prisma](file://server/prisma/schema.prisma) - [video-generator.ts](file://my-uniapp-vue3/src/types/video-generator.ts) - [video-generator-api.ts](file://my-uniapp-vue3/src/utils/video-generator-api.ts) - [storage.service.ts](file://server/src/services/storage.service.ts) - [websocket.service.ts](file://server/src/services/websocket.service.ts) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向AI有声书生成平台的“视频项目模型”,系统性阐述VideoProject模型的字段设计、生命周期状态机、与书籍/章节的关联关系、配置管理与参数传递机制,并提供创建、更新、查询、生成等操作的实现要点与最佳实践。同时给出视频文件的存储、压缩与分发策略,帮助开发者在前后端协同下高效构建视频生成能力。 ## 项目结构 视频项目相关的核心代码分布在后端模块与前端类型/工具层: - 后端模块 - 类型与数据模型:video-generator.types.ts - 业务逻辑:video-generator.service.ts - 控制器路由:video-generator.controller.ts - FFmpeg封装:video-generator.ffmpeg.ts - 数据库模型:Prisma schema.prisma - 存储与分发:storage.service.ts - 实时通知:websocket.service.ts - 前端类型与API - 类型定义:video-generator.ts - API封装:video-generator-api.ts ```mermaid graph TB subgraph "后端" Types["类型定义
video-generator.types.ts"] Service["业务逻辑
video-generator.service.ts"] Controller["控制器
video-generator.controller.ts"] FFMPEG["FFmpeg封装
video-generator.ffmpeg.ts"] Prisma["数据库模型
schema.prisma"] Storage["存储服务
storage.service.ts"] WS["WebSocket服务
websocket.service.ts"] end subgraph "前端" FE_Types["类型定义
video-generator.ts"] FE_API["API封装
video-generator-api.ts"] end FE_API --> Controller Controller --> Service Service --> FFMPEG Service --> Prisma Service --> Storage Service --> WS Types --> Service Types --> Controller Types --> FFMPEG FE_Types --> FE_API ``` 图表来源 - [video-generator.types.ts:1-308](file://server/src/modules/video-generator/video-generator.types.ts#L1-L308) - [video-generator.service.ts:1-556](file://server/src/modules/video-generator/video-generator.service.ts#L1-L556) - [video-generator.controller.ts:1-244](file://server/src/modules/video-generator/video-generator.controller.ts#L1-L244) - [video-generator.ffmpeg.ts:1-300](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L1-L300) - [schema.prisma:194-218](file://server/prisma/schema.prisma#L194-L218) - [video-generator.ts:1-116](file://my-uniapp-vue3/src/types/video-generator.ts#L1-L116) - [video-generator-api.ts:1-188](file://my-uniapp-vue3/src/utils/video-generator-api.ts#L1-L188) 章节来源 - [video-generator.types.ts:1-308](file://server/src/modules/video-generator/video-generator.types.ts#L1-L308) - [video-generator.service.ts:1-556](file://server/src/modules/video-generator/video-generator.service.ts#L1-L556) - [video-generator.controller.ts:1-244](file://server/src/modules/video-generator/video-generator.controller.ts#L1-L244) - [video-generator.ffmpeg.ts:1-300](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L1-L300) - [schema.prisma:194-218](file://server/prisma/schema.prisma#L194-L218) - [video-generator.ts:1-116](file://my-uniapp-vue3/src/types/video-generator.ts#L1-L116) - [video-generator-api.ts:1-188](file://my-uniapp-vue3/src/utils/video-generator-api.ts#L1-L188) ## 核心组件 - VideoProject模型(数据库) - 字段与约束:见Prisma模型定义与类型定义 - 关联关系:与Book、BookChapter的外键关联 - 配置模型 - VideoConfig:包含图片、音频、背景音乐、字幕、视频参数、全局Ken Burns等 - 预设配置:portrait/landscape/square三套预设 - 生命周期状态 - draft、processing、completed、failed - 生成流程 - 从章节音频优先获取,支持带/不带BGM两种合成路径 - 生成完成后回写项目与章节状态并推送WebSocket事件 章节来源 - [schema.prisma:194-218](file://server/prisma/schema.prisma#L194-L218) - [video-generator.types.ts:75-93](file://server/src/modules/video-generator/video-generator.types.ts#L75-L93) - [video-generator.types.ts:214-275](file://server/src/modules/video-generator/video-generator.types.ts#L214-L275) - [video-generator.service.ts:154-312](file://server/src/modules/video-generator/video-generator.service.ts#L154-L312) ## 架构总览 视频项目从“创建—生成—回写—分发”的全链路如下: ```mermaid sequenceDiagram participant FE as "前端应用" participant API as "控制器
video-generator.controller.ts" participant Svc as "业务逻辑
video-generator.service.ts" participant DB as "数据库
Prisma schema.prisma" participant FF as "FFmpeg封装
video-generator.ffmpeg.ts" participant ST as "存储服务
storage.service.ts" participant WS as "WebSocket服务
websocket.service.ts" FE->>API : 创建视频项目 API->>Svc : createVideoProject() Svc->>DB : 插入VideoProject(draft, progress=0) DB-->>Svc : 新项目记录 Svc-->>API : 返回项目(含config解析) API-->>FE : 成功响应 FE->>API : 开始生成 API->>Svc : generateVideoForProject() Svc->>DB : 更新status=processing, progress=0 Svc->>FF : generateVideo()/generateVideoWithBgm() FF-->>Svc : 输出视频元数据(duration,size) Svc->>DB : 更新status=completed, progress=100, outputUrl,duration,fileSize Svc->>DB : 若有chapterId, 更新章节videoUrl/videoDuration Svc->>WS : 推送video_generation_complete事件 API-->>FE : 返回outputUrl/duration/fileSize ``` 图表来源 - [video-generator.controller.ts:44-129](file://server/src/modules/video-generator/video-generator.controller.ts#L44-L129) - [video-generator.service.ts:33-57](file://server/src/modules/video-generator/video-generator.service.ts#L33-L57) - [video-generator.service.ts:157-312](file://server/src/modules/video-generator/video-generator.service.ts#L157-L312) - [video-generator.ffmpeg.ts:23-118](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L23-L118) - [schema.prisma:194-218](file://server/prisma/schema.prisma#L194-L218) - [websocket.service.ts:81-86](file://server/src/services/websocket.service.ts#L81-L86) ## 详细组件分析 ### VideoProject模型字段设计与约束 - 主键与标识 - id:自增主键 - 用户与归属 - userId:可空,关联用户 - bookId/chapterId:可空,直接关联书籍与章节 - 基础信息 - title、description、coverUrl - 配置与产物 - configJson:序列化后的VideoConfig - outputUrl:生成视频的访问地址 - duration、fileSize:生成后回填 - 状态与进度 - status:枚举值draft/processing/completed/failed - progress:百分比 - errorMsg:失败原因 - 时间戳 - createdAt、updatedAt 字段约束与校验要点 - configJson必须为合法JSON字符串;解析失败时应降级为空配置 - status默认draft,progress默认0 - outputUrl在生成完成后回填,需确保路径可访问 - 与Book/BookChapter的外键关系允许为NULL,便于独立项目或跨章节生成 章节来源 - [schema.prisma:194-218](file://server/prisma/schema.prisma#L194-L218) - [video-generator.types.ts:97-115](file://server/src/modules/video-generator/video-generator.types.ts#L97-L115) - [video-generator.types.ts:279-292](file://server/src/modules/video-generator/video-generator.types.ts#L279-L292) - [video-generator.service.ts:39-56](file://server/src/modules/video-generator/video-generator.service.ts#L39-L56) ### 生命周期状态机 状态流转 - draft → processing:开始生成 - processing → completed:生成成功 - processing → failed:生成异常 - draft → failed:配置缺失或素材不可用 ```mermaid stateDiagram-v2 [*] --> 草稿 草稿 --> 处理中 : "开始生成" 处理中 --> 完成 : "成功" 处理中 --> 失败 : "异常" 完成 --> [*] 失败 --> [*] ``` 图表来源 - [video-generator.types.ts:8-9](file://server/src/modules/video-generator/video-generator.types.ts#L8-L9) - [video-generator.service.ts:171-173](file://server/src/modules/video-generator/video-generator.service.ts#L171-L173) - [video-generator.service.ts:293-299](file://server/src/modules/video-generator/video-generator.service.ts#L293-L299) 章节来源 - [video-generator.types.ts:8-9](file://server/src/modules/video-generator/video-generator.types.ts#L8-L9) - [video-generator.service.ts:157-312](file://server/src/modules/video-generator/video-generator.service.ts#L157-L312) ### 配置模型与参数传递 - VideoConfig组成 - images:图片数组,每张含URL、显示时长、转场、可选Ken Burns - audio:音频URL、起止截取、音量 - bgm:可选,含URL、音量、循环、淡入淡出 - subtitle:可选,文本、字号、颜色、背景色、位置、边距、样式 - video:分辨率、帧率、码率、格式 - kenburns:全局开关与缩放范围 - 预设配置 - portrait/landscape/square三套模板,便于快速生成 - 参数传递 - 前端通过VideoConfig对象提交 - 后端将VideoConfig序列化为configJson存库 - 生成时从数据库读取并反序列化为运行时配置 章节来源 - [video-generator.types.ts:75-93](file://server/src/modules/video-generator/video-generator.types.ts#L75-L93) - [video-generator.types.ts:214-275](file://server/src/modules/video-generator/video-generator.types.ts#L214-L275) - [video-generator.types.ts:279-292](file://server/src/modules/video-generator/video-generator.types.ts#L279-L292) - [video-generator-api.ts:10-26](file://my-uniapp-vue3/src/utils/video-generator-api.ts#L10-L26) ### 与书籍/章节的关联关系 - 直接关联 - VideoProject.bookId → Book - VideoProject.chapterId → BookChapter - 生成时优先策略 - 若项目包含chapterId,则优先从章节表读取audioUrl与content,作为音频与字幕内容来源 - 回写行为 - 生成完成后,若存在chapterId,同步更新章节videoUrl与videoDuration 章节来源 - [schema.prisma:211-212](file://server/prisma/schema.prisma#L211-L212) - [video-generator.service.ts:192-202](file://server/src/modules/video-generator/video-generator.service.ts#L192-L202) - [video-generator.service.ts:271-283](file://server/src/modules/video-generator/video-generator.service.ts#L271-L283) ### 视频生成流程与实现要点 - 输入准备 - 校验项目状态与必要素材(图片URL、音频URL) - 将URL统一转换为本地文件路径并检查存在性 - 生成执行 - 无BGM:调用generateVideo - 有BGM:先下载BGM至临时目录,再调用generateVideoWithBgm - 多图轮播:generateSlideshow - 输出与回写 - 生成完成后计算duration与fileSize,回写数据库 - 若关联章节,同步更新章节视频信息 - 推送WebSocket事件,通知前端 - 错误处理 - 捕获异常,回写status=failed与errorMsg - 推送失败事件 ```mermaid flowchart TD Start(["开始生成"]) --> CheckProj["读取项目与状态"] CheckProj --> StatusOK{"状态为draft/processing?"} StatusOK --> |processing| ErrBusy["返回已在生成中"] StatusOK --> |draft| UpdateProc["更新为processing(progress=0)"] UpdateProc --> LoadCfg["加载配置(configJson)"] LoadCfg --> HasMedia{"图片/音频可用?"} HasMedia --> |否| ErrMedia["返回缺少素材"] HasMedia --> |是| Paths["转换URL为本地路径并校验存在"] Paths --> GenType{"是否包含BGM?"} GenType --> |是| GenBGM["下载BGM并生成(带BGM)"] GenType --> |否| Gen["生成(无BGM)"] GenBGM --> WriteBack["回写结果: url,duration,size,status=completed,progress=100"] Gen --> WriteBack WriteBack --> UpdateChapter{"是否关联章节?"} UpdateChapter --> |是| UpdChap["更新章节videoUrl/videoDuration"] UpdateChapter --> |否| SkipChap["跳过"] UpdChap --> Notify["推送WebSocket事件"] SkipChap --> Notify Notify --> End(["完成"]) ErrBusy --> End ErrMedia --> End ``` 图表来源 - [video-generator.service.ts:164-312](file://server/src/modules/video-generator/video-generator.service.ts#L164-L312) - [video-generator.ffmpeg.ts:23-118](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L23-L118) - [video-generator.ffmpeg.ts:123-199](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L123-L199) 章节来源 - [video-generator.service.ts:154-312](file://server/src/modules/video-generator/video-generator.service.ts#L154-L312) - [video-generator.ffmpeg.ts:1-300](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L1-L300) ### FFmpeg参数与压缩策略 - 视频编码 - 编码器:libx264 - 预设:fast - CRF:18(质量优先) - 像素格式:yuv420p(兼容性) - 音频编码 - 编码器:aac - 码率:192k - 滤镜链 - Ken Burns:zoompan(动态缩放) - 缩放与填充:scale + pad(保持比例并居中) - 字幕:drawtext(按位置渲染) - 混音 - amix:将主音频与BGM混合,取最长时长 章节来源 - [video-generator.ffmpeg.ts:38-98](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L38-L98) - [video-generator.ffmpeg.ts:169-186](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L169-L186) ### 存储、压缩与分发策略 - 本地存储 - 输出视频存放于public/videos,访问路径为/videos/{filename} - 素材下载至temp/images或temp/audio临时目录 - OSS存储(可选) - 通过storage.service.ts统一抽象,支持OSS与本地无缝切换 - 提供上传/下载/删除/签名URL等能力 - 压缩与分发 - 采用H.264+AAC组合,CRF 18兼顾画质与体积 - 生成完成后回写duration与fileSize,便于前端展示与统计 - 可结合CDN加速公开视频资源 章节来源 - [video-generator.ffmpeg.ts:11-18](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L11-L18) - [video-generator.service.ts:236-237](file://server/src/modules/video-generator/video-generator.service.ts#L236-L237) - [storage.service.ts:1-278](file://server/src/services/storage.service.ts#L1-L278) ### API与操作示例(路径指引) - 创建视频项目 - 后端:POST /api/video/projects - 前端:createVideoProject() - 查询项目列表 - 后端:GET /api/video/projects - 前端:getVideoProjects() - 获取项目详情 - 后端:GET /api/video/projects/:id - 前端:getVideoProject() - 更新项目 - 后端:PUT /api/video/projects/:id - 前端:updateVideoProject() - 删除项目 - 后端:DELETE /api/video/projects/:id - 前端:deleteVideoProject() - 开始生成 - 后端:POST /api/video/projects/:id/generate - 前端:generateVideo() - 获取生成进度 - 后端:GET /api/video/projects/:id/status - 前端:getGenerateProgress() - 从书籍生成项目 - 后端:POST /api/video/books/:bookId/generate - 前端:createVideoProjectFromBook() 章节来源 - [video-generator.controller.ts:28-140](file://server/src/modules/video-generator/video-generator.controller.ts#L28-L140) - [video-generator-api.ts:78-187](file://my-uniapp-vue3/src/utils/video-generator-api.ts#L78-L187) ## 依赖分析 - 模块耦合 - controller依赖service;service依赖types、ffmpeg、prisma、storage、websocket - ffmpeg封装与配置解耦,便于扩展其他合成引擎 - 外部依赖 - fluent-ffmpeg:视频合成 - Prisma:数据库ORM - WebSocket:实时事件推送 - 潜在风险 - 生成流程阻塞IO,建议引入队列异步化 - FFmpeg命令行依赖系统环境,需容器化部署保证一致性 ```mermaid graph LR Controller["控制器"] --> Service["业务逻辑"] Service --> Types["类型定义"] Service --> FFMPEG["FFmpeg封装"] Service --> Prisma["Prisma模型"] Service --> Storage["存储服务"] Service --> WS["WebSocket服务"] ``` 图表来源 - [video-generator.controller.ts:1-244](file://server/src/modules/video-generator/video-generator.controller.ts#L1-L244) - [video-generator.service.ts:1-556](file://server/src/modules/video-generator/video-generator.service.ts#L1-L556) - [video-generator.types.ts:1-308](file://server/src/modules/video-generator/video-generator.types.ts#L1-L308) - [video-generator.ffmpeg.ts:1-300](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L1-L300) - [schema.prisma:1-470](file://server/prisma/schema.prisma#L1-L470) - [storage.service.ts:1-278](file://server/src/services/storage.service.ts#L1-L278) - [websocket.service.ts:1-136](file://server/src/services/websocket.service.ts#L1-L136) 章节来源 - [video-generator.controller.ts:1-244](file://server/src/modules/video-generator/video-generator.controller.ts#L1-L244) - [video-generator.service.ts:1-556](file://server/src/modules/video-generator/video-generator.service.ts#L1-L556) ## 性能考虑 - IO与CPU瓶颈 - FFmpeg合成为CPU密集型任务,建议使用专用GPU或容器资源限制 - 异步化 - 将生成放入队列,避免阻塞HTTP请求 - 缓存与复用 - 重复素材可缓存至临时目录,减少网络下载 - 并发控制 - 限制同一用户的并发生成数量,防止资源争抢 - CDN与分发 - 使用CDN加速public/videos下的视频资源 ## 故障排查指南 常见问题与定位 - 项目不存在或状态异常 - 检查项目ID与状态;避免重复触发生成 - 缺少必要素材 - 确认images与audio.url存在且可访问 - FFmpeg命令失败 - 查看stderr日志;确认系统已安装ffmpeg - WebSocket未收到事件 - 检查/upgrade路径与clientId参数;确认wss实例已初始化 - 存储异常 - 若使用OSS,检查凭证与Bucket权限;本地存储检查目录权限 章节来源 - [video-generator.service.ts:166-173](file://server/src/modules/video-generator/video-generator.service.ts#L166-L173) - [video-generator.service.ts:204-206](file://server/src/modules/video-generator/video-generator.service.ts#L204-L206) - [video-generator.service.ts:291-311](file://server/src/modules/video-generator/video-generator.service.ts#L291-L311) - [websocket.service.ts:102-133](file://server/src/services/websocket.service.ts#L102-L133) - [storage.service.ts:252-272](file://server/src/services/storage.service.ts#L252-L272) ## 结论 VideoProject模型以清晰的字段设计与严格的生命周期管理为基础,配合灵活的配置体系与稳健的FFmpeg合成流程,实现了从书籍章节到视频的自动化生产。通过Prisma的外键约束与WebSocket的实时通知,系统在数据一致性与用户体验上取得平衡。建议后续引入队列异步化与容器化部署,进一步提升稳定性与可扩展性。 ## 附录 - 关键实现路径参考 - VideoProject创建:[video-generator.service.ts:33-57](file://server/src/modules/video-generator/video-generator.service.ts#L33-L57) - 视频生成主流程:[video-generator.service.ts:157-312](file://server/src/modules/video-generator/video-generator.service.ts#L157-L312) - FFmpeg合成实现:[video-generator.ffmpeg.ts:23-118](file://server/src/modules/video-generator/video-generator.ffmpeg.ts#L23-L118) - WebSocket事件推送:[websocket.service.ts:81-86](file://server/src/services/websocket.service.ts#L81-L86) - 前端API封装:[video-generator-api.ts:78-187](file://my-uniapp-vue3/src/utils/video-generator-api.ts#L78-L187)