--- name: video-generator-plan overview: 为有声书项目新增图片+音频生成配图视频功能,采用FFmpeg方案,无需GPU,完全免费,适合快速上线。 design: styleKeywords: - 卡片式布局 - 步骤导航 - 进度反馈 fontSystem: fontFamily: system-ui heading: size: 18px weight: 600 subheading: size: 16px weight: 500 body: size: 14px weight: 400 colorSystem: primary: - "#3B82F6" - "#2563EB" background: - "#F5F5F5" - "#FFFFFF" text: - "#333333" - "#666666" functional: - "#10B981" - "#EF4444" - "#F59E0B" todos: - id: db-video-model content: 添加 VideoProject 数据模型到 Prisma schema status: completed - id: backend-ffmpeg-module content: 创建 video-generator FFmpeg 命令封装模块 status: completed dependencies: - db-video-model - id: backend-service content: 实现 video-generator.service.ts 业务逻辑 status: completed dependencies: - backend-ffmpeg-module - id: backend-controller content: 实现 video-generator.controller.ts API 路由 status: completed dependencies: - backend-service - id: frontend-api content: 创建前端 video-generator-api.ts 调用封装 status: completed dependencies: - backend-controller - id: frontend-list-page content: 开发视频项目列表页(index.vue) status: completed dependencies: - frontend-api - id: frontend-create-page content: 开发创建/编辑视频页(create.vue) status: completed dependencies: - frontend-list-page - id: frontend-preview-page content: 开发视频预览页(preview.vue) status: completed dependencies: - frontend-create-page - id: integration-book-generator content: 集成到 BookGenerator:从书籍快捷生成视频 status: completed dependencies: - frontend-create-page - id: feature-list-entry content: 添加 feature_list.json 条目并更新进度 status: completed dependencies: - integration-book-generator --- ## 用户需求 1. **主要场景**:生成有声书配图视频 2. **优先级**:快速实现 > 效果 3. **资源约束**:无GPU、希望免费 4. **可选需求**:支持自定义图片素材 ## 功能概述 基于 FFmpeg 将静态图片+音频合成带 Ken Burns 效果的视频,实现"有声书配图视频"生成功能。 ## 核心功能 1. **图片处理**:支持上传单张/多张图片,自动适配视频尺寸 2. **Ken Burns 效果**:慢速缩放/平移动画,让静态图片"动起来" 3. **音频同步**:图片切换与音频时长自动匹配 4. **字幕叠加**:可选添加文字字幕 5. **背景音乐**:可选添加背景BGM混音 6. **素材库**:提供预设图片素材供选择 7. **与书籍生成集成**:从已生成的书籍/音频直接生成视频 ## 输出结果 - 输出 MP4 格式视频文件 - 支持预览和下载 - 生成进度实时反馈 ## 技术方案:FFmpeg 图片+音频视频合成 ### 技术选型 - **后端框架**:Node.js + TypeScript + fluent-ffmpeg(复用现有) - **前端框架**:uniapp-vue3(复用现有) - **数据库**:MySQL + Prisma ORM(复用现有) - **视频处理**:FFmpeg(开源免费,CPU计算) ### 核心实现方案 #### 1. Ken Burns 效果实现 使用 FFmpeg zoompan 滤镜实现图片动态效果: ``` # 缩放+平移动画示例 ffmpeg -loop 1 -i image.jpg -vf "zoompan=z='min(zoom+0.001,1.5)':d=125,trim=duration=5" -t 5 output.mp4 ``` #### 2. 图片+音频合成 ``` # 基础合成命令 ffmpeg -loop 1 -i image.jpg -i audio.mp3 \ -vf "zoompan=z='1+0.3*sin(0.1*t)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=250,setsar=1" \ -c:v libx264 -tune stillimage -c:a aac -b:a 192k \ -pix_fmt yuv420p -shortest output.mp4 ``` #### 3. 多图轮播 使用 FFmpeg concat 滤镜实现多图自动切换 ### 数据模型设计 #### VideoProject 模型(数据库) ``` model VideoProject { id Int @id @default(autoincrement()) userId Int? title String // 项目标题 description String? // 描述 coverUrl String? // 封面图 // 素材配置(JSON存储) configJson String? @db.LongText // VideoConfig JSON // 输出视频 outputUrl String? // 生成后的视频URL duration Int? // 视频时长(秒) fileSize Int? // 文件大小(字节) // 关联 bookId Int? // 关联的书籍ID(可选) audioId Int? // 关联的音频ID(可选) status String @default("draft") // draft, processing, completed, failed progress Int @default(0) // 0-100 errorMsg String? @db.Text createdAt DateTime @default(now()) updatedAt DateTime @updatedAt book Book? @relation(fields: [bookId], references: [id]) audio Audio? @relation(fields: [audioId], references: [id]) } ``` #### VideoConfig 类型 ```typescript interface VideoConfig { // 图片配置 images: { url: string; // 图片URL duration: number; // 显示时长(秒) transition: 'none' | 'fade' | 'slide'; // 转场效果 }[]; // 音频配置 audio: { url: string; // 主音频URL(必填) startTime?: number; // 音频开始时间(截取) volume: number; // 音量 0-1 }; // 背景音乐配置(可选) bgm?: { url: string; volume: number; loop: boolean; }; // 字幕配置(可选) subtitle?: { text: string; position: 'top' | 'bottom' | 'center'; fontSize: number; color: string; backgroundColor?: string; }; // 视频参数 video: { width: number; // 视频宽度 height: number; // 视频高度 fps: number; // 帧率 bitrate: string; // 码率 }; // Ken Burns 效果参数 kenburns: { enabled: boolean; minZoom: number; // 最小缩放 maxZoom: number; // 最大缩放 panSpeed: number; // 平移速度 zoomSpeed: number; // 缩放速度 }; } ``` ### API 接口设计 | 接口 | 方法 | 描述 | | --- | --- | --- | | `/api/video/projects` | GET | 获取视频项目列表 | | `/api/video/projects` | POST | 创建视频项目 | | `/api/video/projects/:id` | GET | 获取项目详情 | | `/api/video/projects/:id` | PUT | 更新项目配置 | | `/api/video/projects/:id` | DELETE | 删除项目 | | `/api/video/projects/:id/generate` | POST | 开始生成视频 | | `/api/video/projects/:id/status` | GET | 获取生成状态 | | `/api/video/materials` | GET | 获取预设素材库 | | `/api/video/materials/upload` | POST | 上传自定义素材 | | `/api/video/books/:bookId/generate` | POST | 从书籍生成视频(快捷接口) | ### 模块目录结构 ``` server/src/modules/video-generator/ ├── video-generator.controller.ts # 控制器 ├── video-generator.service.ts # 业务逻辑 ├── video-generator.types.ts # 类型定义 ├── video-generator.ffmpeg.ts # FFmpeg命令封装 ├── video-generator.queue.ts # 生成任务队列 └── README.md # 模块文档 my-uniapp-vue3/src/pages/ ├── video-generator/ │ ├── index.vue # 项目列表页 │ ├── create.vue # 创建/编辑项目 │ └── preview.vue # 视频预览页 my-uniapp-vue3/src/utils/ └── video-generator-api.ts # API调用封装 ``` ### 与现有系统集成 #### 与 BookGenerator 集成 ```typescript // 快捷生成流程 1. 用户在书籍生成页面点击"生成视频" 2. 自动跳转视频生成页面,预填: - 书籍标题、描述 - 生成的章节内容作为字幕备选 - 已有TTS音频(如有) 3. 用户选择/上传配图素材 4. 生成视频 ``` #### 与 TTS 集成 ```typescript // 音频来源 1. 直接选择已有的 TTS 音频 2. 在视频生成页面临时调用 TTS 3. 上传外部音频文件 ``` ## 页面规划(3个核心页面) ### 页面1:视频项目列表页(index.vue) - 顶部导航栏(标题:视频生成) - 创建新视频按钮(大卡片样式) - 视频项目列表(卡片展示:封面图、标题、时长、状态) - 空状态引导 ### 页面2:创建/编辑视频页(create.vue) - 步骤导航:选择素材 → 配置效果 → 生成视频 - **步骤1-素材选择**: - 书籍/音频选择(关联已有资源) - 图片上传/素材库选择(支持多图) - 背景音乐上传 - **步骤2-效果配置**: - Ken Burns 效果开关和参数 - 字幕配置(文本、位置、样式) - 视频参数(分辨率、码率) - **步骤3-生成**: - 预览效果 - 开始生成按钮 - 进度条展示 ### 页面3:视频预览页(preview.vue) - 视频播放器 - 下载按钮 - 分享按钮 - 重新编辑入口 ## 设计风格 - 沿用现有 uniapp-vue3 项目的设计语言 - 卡片式布局 - 渐变色按钮 - 简洁清爽的配色