video-generator-plan_466f81ce.md 8.9 KB


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 类型

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 集成

// 快捷生成流程
1. 用户在书籍生成页面点击"生成视频"
2. 自动跳转视频生成页面,预填:
   - 书籍标题、描述
   - 生成的章节内容作为字幕备选
   - 已有TTS音频(如有)
3. 用户选择/上传配图素材
4. 生成视频

与 TTS 集成

// 音频来源
1. 直接选择已有的 TTS 音频
2. 在视频生成页面临时调用 TTS
3. 上传外部音频文件

页面规划(3个核心页面)

页面1:视频项目列表页(index.vue)

  • 顶部导航栏(标题:视频生成)
  • 创建新视频按钮(大卡片样式)
  • 视频项目列表(卡片展示:封面图、标题、时长、状态)
  • 空状态引导

页面2:创建/编辑视频页(create.vue)

  • 步骤导航:选择素材 → 配置效果 → 生成视频
  • 步骤1-素材选择
  • 书籍/音频选择(关联已有资源)
  • 图片上传/素材库选择(支持多图)
  • 背景音乐上传
  • 步骤2-效果配置
  • Ken Burns 效果开关和参数
  • 字幕配置(文本、位置、样式)
  • 视频参数(分辨率、码率)
  • 步骤3-生成
  • 预览效果
  • 开始生成按钮
  • 进度条展示

页面3:视频预览页(preview.vue)

  • 视频播放器
  • 下载按钮
  • 分享按钮
  • 重新编辑入口

设计风格

  • 沿用现有 uniapp-vue3 项目的设计语言
  • 卡片式布局
  • 渐变色按钮
  • 简洁清爽的配色