418 lines
15 KiB
Markdown
418 lines
15 KiB
Markdown
# 快速入门
|
||
|
||
<cite>
|
||
**本文引用的文件**
|
||
- [PROJECT_README.md](file://PROJECT_README.md)
|
||
- [.env.example](file://.env.example)
|
||
- [requirements.txt](file://requirements.txt)
|
||
- [package.json](file://package.json)
|
||
- [main.py](file://main.py)
|
||
- [backend/extractor.py](file://backend/extractor.py)
|
||
- [backend/scripter.py](file://backend/scripter.py)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py)
|
||
- [backend/data_builder.py](file://backend/data_builder.py)
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts)
|
||
- [remotion.config.ts](file://remotion.config.ts)
|
||
- [tests/test_video_cli.py](file://tests/test_video_cli.py)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖与环境配置](#依赖与环境配置)
|
||
7. [输入文件准备](#输入文件准备)
|
||
8. [执行生成流程](#执行生成流程)
|
||
9. [依赖关系分析](#依赖关系分析)
|
||
10. [性能与优化建议](#性能与优化建议)
|
||
11. [故障排查指南](#故障排查指南)
|
||
12. [结论](#结论)
|
||
|
||
## 简介
|
||
本指南面向首次接触本项目的用户,帮助您从零开始完成依赖安装、环境配置、输入准备与完整生成流程。系统采用“Python 后端 + Node.js 前端”的混合架构:Python 负责数据提取、脚本生成、图表模拟与渲染参数构建;前端使用 Remotion 进行程序化视频渲染。通过本指南,您将理解为什么需要 Gemini、Whisper 和 Pexels 的 API 密钥,以及每一步背后的原理。
|
||
|
||
## 项目结构
|
||
项目采用分层组织:
|
||
- 根目录包含入口脚本、依赖清单、环境样例与资产目录
|
||
- backend 子目录包含数据提取、脚本生成、媒体抓取与图表数据构建等模块
|
||
- frontend 子目录为 Remotion 视频渲染前端工程
|
||
- assets 目录用于存放输入、中间产物与最终输出
|
||
|
||
```mermaid
|
||
graph TB
|
||
A["根目录<br/>main.py, .env.example, requirements.txt, package.json"] --> B["backend/<br/>extractor.py, scripter.py, media_fetcher.py, data_builder.py"]
|
||
A --> C["frontend/<br/>src/*"]
|
||
A --> D["assets/<br/>0_input, 1_processed, 2_output"]
|
||
A --> E["remotion.config.ts"]
|
||
```
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L50-L80)
|
||
|
||
## 核心组件
|
||
- 主入口与流水线编排:负责解析 CLI 参数、组织各阶段任务、保存渲染参数并触发前端渲染
|
||
- 数据提取模块:使用 Gemini 解析 PDF,使用 Whisper 提取视频字幕与时间戳
|
||
- 脚本生成模块:基于 PDF 与视频内容生成自然日语旁白脚本
|
||
- 媒体抓取模块:根据关键词从 Pexels 搜索并下载 B-Roll 视频
|
||
- 图表数据构建:基于财务模拟生成资产枯竭与现金流图表数据
|
||
- 渲染契约类型定义:前后端共享的渲染参数结构,确保 Python 生成的数据与前端渲染一致
|
||
|
||
**章节来源**
|
||
- [main.py](file://main.py#L33-L304)
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
|
||
## 架构总览
|
||
系统采用“数据驱动”的流水线式架构:Python 后端负责数据处理与渲染参数生成,前端 Remotion 负责将数据转换为最终视频。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "Python 后端"
|
||
EX["PDF/视频提取<br/>extractor.py"]
|
||
SC["脚本生成<br/>scripter.py"]
|
||
MF["媒体抓取<br/>media_fetcher.py"]
|
||
DB["图表数据构建<br/>data_builder.py"]
|
||
VP["主流水线编排<br/>main.py"]
|
||
end
|
||
subgraph "前端"
|
||
RP["渲染契约类型<br/>render-props-types.ts"]
|
||
RC["Remotion 配置<br/>remotion.config.ts"]
|
||
end
|
||
IN["输入 PDF/视频<br/>assets/0_input"] --> VP
|
||
VP --> EX
|
||
VP --> SC
|
||
VP --> MF
|
||
VP --> DB
|
||
DB --> RP
|
||
SC --> RP
|
||
MF --> RP
|
||
RP --> RC
|
||
RC --> OUT["输出视频<br/>assets/2_output"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [main.py](file://main.py#L33-L304)
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
- [remotion.config.ts](file://remotion.config.ts#L1-L12)
|
||
|
||
## 详细组件分析
|
||
|
||
### 主流水线编排(main.py)
|
||
- 负责解析 CLI 参数、组织六步流程(提取、转录、生成脚本、抓取媒体、构建渲染参数、触发渲染),并在 dry-run 模式下仅生成渲染参数
|
||
- 输出路径默认保存到 assets/2_output/life_plan_video.mp4
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as "用户"
|
||
participant M as "main.py"
|
||
participant B as "后端模块"
|
||
participant R as "Remotion"
|
||
U->>M : 运行 CLI指定 PDF/可选视频/干运行
|
||
M->>B : 步骤1:提取 PDF 数据
|
||
M->>B : 步骤2:提取视频数据可选
|
||
M->>B : 步骤3:生成脚本
|
||
M->>B : 步骤4:抓取 B-Roll
|
||
M->>B : 步骤5:构建渲染参数
|
||
M->>R : 步骤6:触发渲染可选
|
||
R-->>U : 输出最终视频
|
||
```
|
||
|
||
**图示来源**
|
||
- [main.py](file://main.py#L33-L304)
|
||
|
||
**章节来源**
|
||
- [main.py](file://main.py#L33-L304)
|
||
|
||
### 数据提取(PDF/视频)
|
||
- PDF 提取:使用 Gemini 解析 Life Plan 报告,抽取客户信息、财务数据、重大事件等结构化数据
|
||
- 视频提取:使用 Whisper 将面试视频转写为文本与时间戳,便于后续脚本与媒体同步
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["输入:PDF/视频"] --> B["PDF 提取Gemini"]
|
||
A --> C["视频提取Whisper"]
|
||
B --> D["结构化数据"]
|
||
C --> E["转写文本与时间戳"]
|
||
D --> F["脚本生成Gemini"]
|
||
E --> F
|
||
```
|
||
|
||
**图示来源**
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
|
||
**章节来源**
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
|
||
### 媒体抓取(B-Roll)
|
||
- 基于脚本与关键词从 Pexels 搜索并下载 B-Roll 视频,作为背景素材
|
||
- 支持将日文关键词翻译为英文后再搜索,提高检索命中率
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
S["脚本生成结果"] --> K["提取关键词"]
|
||
K --> T["关键词翻译Gemini"]
|
||
T --> P["Pexels 搜索"]
|
||
P --> D["下载视频至本地"]
|
||
D --> A["返回媒体映射"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
|
||
**章节来源**
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
|
||
### 图表数据构建
|
||
- 使用财务模拟引擎计算年金收入、支出、资产余额与关键事件影响
|
||
- 生成资产枯竭与现金流两个图表所需的时间序列数据
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
I["PDF 结构化数据"] --> F["财务模拟器"]
|
||
F --> AD["资产枯竭时间线"]
|
||
F --> CF["现金流时间线"]
|
||
AD --> O["渲染参数charts.assetDepletion"]
|
||
CF --> O
|
||
```
|
||
|
||
**图示来源**
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
|
||
**章节来源**
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
|
||
### 渲染契约类型(前后端数据契约)
|
||
- 定义了渲染参数的完整结构(元信息、图表数据、脚本段落、媒体集合),并与前端类型保持一致
|
||
- 通过 Zod Schema 在运行时进行校验,保证数据一致性
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class YearlySnapshot {
|
||
+year : number
|
||
+ages : {rep : number, spouse? : number}
|
||
+financials : {income, expenditure, assetBalance}
|
||
+events? : string[]
|
||
+isCritical? : boolean
|
||
}
|
||
class CashFlowData {
|
||
+year : number
|
||
+age : number
|
||
+income.total : number
|
||
+expenses : {living, housing, education, tax, event}
|
||
+totalExpense? : number
|
||
+netCashFlow? : number
|
||
+assetBalance? : number
|
||
}
|
||
class ScriptSegment {
|
||
+id : number
|
||
+text : string
|
||
+duration : number
|
||
+type : enum
|
||
+assetUrl? : string
|
||
+chartSync? : {chartId, highlightYear?, animationStart?}
|
||
}
|
||
class AssetCollection {
|
||
+broll : Record<string,string>
|
||
+videoClips : VideoClipReference[]
|
||
+ttsAudio? : string
|
||
}
|
||
class RenderProps {
|
||
+meta : {title, currencyUnit, duration, clientName?, generatedAt?}
|
||
+charts : {assetDepletion, cashFlow}
|
||
+script : ScriptSegment[]
|
||
+assets : AssetCollection
|
||
}
|
||
RenderProps --> YearlySnapshot : "charts.assetDepletion.timeline"
|
||
RenderProps --> CashFlowData : "charts.cashFlow.timeline"
|
||
RenderProps --> ScriptSegment : "script[]"
|
||
RenderProps --> AssetCollection : "assets"
|
||
```
|
||
|
||
**图示来源**
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
|
||
**章节来源**
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
|
||
## 依赖与环境配置
|
||
|
||
### 1) 依赖安装
|
||
- Python 依赖:安装项目所需的 Python 包(含 dotenv、ffmpeg-python、requests、tqdm、rich 等)
|
||
- Node.js 依赖:安装前端渲染与开发工具(Remotion、React、Recharts、TypeScript 等)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
P["Python 依赖"] --> R["requirements.txt"]
|
||
N["Node.js 依赖"] --> PJ["package.json"]
|
||
R --> PY["pip install -r requirements.txt"]
|
||
PJ --> NP["npm install"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [requirements.txt](file://requirements.txt#L1-L34)
|
||
- [package.json](file://package.json#L1-L43)
|
||
|
||
**章节来源**
|
||
- [requirements.txt](file://requirements.txt#L1-L34)
|
||
- [package.json](file://package.json#L1-L43)
|
||
|
||
### 2) 环境配置
|
||
- 复制环境样例文件为实际配置文件,并填入对应 API 密钥
|
||
- 必需密钥:
|
||
- GEMINI_API_KEY:用于 PDF 解析与脚本生成
|
||
- OPENAI_API_KEY:用于 Whisper 音频转写
|
||
- PEXELS_API_KEY:用于 B-Roll 视频搜索与下载
|
||
- 可选配置项(财务模拟参数):
|
||
- DEFAULT_INFLATION_RATE
|
||
- DEFAULT_DEFICIT_INTEREST_RATE
|
||
- DEFAULT_INVESTMENT_RETURN
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
CP[".env.example -> .env"] --> KEYS["填写 API 密钥"]
|
||
KEYS --> RUN["运行生成流程"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [.env.example](file://.env.example#L1-L23)
|
||
|
||
**章节来源**
|
||
- [.env.example](file://.env.example#L1-L23)
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L81-L131)
|
||
|
||
### 3) 为什么需要这些 API 密钥
|
||
- Gemini(Google):用于 PDF 结构化解析与自然日语脚本生成
|
||
- Whisper(OpenAI):用于将面试视频转写为带时间戳的文本,便于脚本与画面同步
|
||
- Pexels:用于按关键词搜索并下载合适的背景视频素材
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L36-L49)
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
|
||
## 输入文件准备
|
||
- 将 Life Plan PDF 报告与面试视频放入 assets/0_input 目录
|
||
- 系统会自动在 assets/1_processed 中生成中间文件,在 assets/2_output 中生成最终视频
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
I["assets/0_input/report.pdf"] --> M["main.py"]
|
||
V["assets/0_input/interview.mp4"] --> M
|
||
M --> O["assets/2_output/life_plan_video.mp4"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L50-L80)
|
||
- [main.py](file://main.py#L33-L84)
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L50-L80)
|
||
- [main.py](file://main.py#L33-L84)
|
||
|
||
## 执行生成流程
|
||
|
||
### 基础运行(仅 PDF)
|
||
- 命令示例:参考项目快速启动说明中的基础用法
|
||
- 流程:提取 PDF → 生成脚本 → 抓取媒体 → 构建渲染参数 → 触发渲染
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L112-L131)
|
||
|
||
### 带视频输入
|
||
- 命令示例:参考项目快速启动说明中的“带面试视频”用法
|
||
- 流程:提取 PDF 与视频 → 生成脚本(结合视频转写)→ 抓取媒体 → 构建渲染参数 → 触发渲染
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L112-L131)
|
||
|
||
### 干运行模式(仅生成渲染参数)
|
||
- 命令示例:参考项目快速启动说明中的“干运行”用法
|
||
- 作用:跳过渲染阶段,仅生成 render_props.json,便于调试与验证数据结构
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L112-L131)
|
||
|
||
### CLI 参数说明
|
||
- --pdf:必填(当未提供配置文件时),指定 Life Plan 报告路径
|
||
- --video:可选,指定面试视频路径
|
||
- --config:可选,指定自定义配置 JSON 文件
|
||
- --output:可选,自定义输出文件名
|
||
- --dry-run:可选,仅生成渲染参数,不触发渲染
|
||
|
||
**章节来源**
|
||
- [main.py](file://main.py#L228-L304)
|
||
|
||
## 依赖关系分析
|
||
- Python 后端模块之间存在清晰的职责分离:extractor 负责数据提取,scripter 负责脚本生成,media_fetcher 负责媒体抓取,data_builder 负责图表数据构建
|
||
- main.py 作为编排者,协调各模块并生成渲染参数
|
||
- 前端通过 render-props-types.ts 严格约束渲染参数结构,确保与后端一致
|
||
- remotion.config.ts 控制渲染图像格式与覆盖策略
|
||
|
||
```mermaid
|
||
graph LR
|
||
EX["extractor.py"] --> DB["data_builder.py"]
|
||
SC["scripter.py"] --> DB
|
||
MF["media_fetcher.py"] --> DB
|
||
DB --> RP["render-props-types.ts"]
|
||
EX --> RP
|
||
SC --> RP
|
||
MF --> RP
|
||
RP --> RC["remotion.config.ts"]
|
||
```
|
||
|
||
**图示来源**
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
- [remotion.config.ts](file://remotion.config.ts#L1-L12)
|
||
|
||
**章节来源**
|
||
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
|
||
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
|
||
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
|
||
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
|
||
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
|
||
- [remotion.config.ts](file://remotion.config.ts#L1-L12)
|
||
|
||
## 性能与优化建议
|
||
- 优先使用 Gemini 直接解析 PDF,避免额外的本地 PDF 处理依赖
|
||
- Whisper 转写建议选择合适语言与采样率,减少不必要的重试与失败
|
||
- Pexels 搜索时尽量提供精准关键词,减少无效请求
|
||
- 在本地缓存翻译结果与媒体下载结果,降低重复调用成本
|
||
- 使用干运行模式先验证数据结构正确性,再进行完整渲染
|
||
|
||
[本节为通用建议,无需特定文件引用]
|
||
|
||
## 故障排查指南
|
||
- “未找到 API 密钥”
|
||
- 确认 .env 文件已创建且包含有效密钥
|
||
- 确认环境变量加载顺序与 dotenv 配置一致
|
||
- “Remotion 渲染失败”
|
||
- 确认 Node.js 依赖已安装
|
||
- 检查前端源码结构是否符合预期
|
||
- “PDF 提取失败”
|
||
- 确认 PDF 可读且未加密
|
||
- 检查 Gemini API 配额与限制
|
||
- “视频分析依赖缺失”
|
||
- 使用测试脚本检查 FFmpeg 与 OpenAI 库是否安装
|
||
|
||
**章节来源**
|
||
- [PROJECT_README.md](file://PROJECT_README.md#L218-L233)
|
||
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L1-L161)
|
||
|
||
## 结论
|
||
通过本快速入门指南,您已经了解了项目的整体架构、关键依赖与环境配置要求,并掌握了从输入准备到完整生成的全流程操作。建议在首次运行时使用干运行模式验证数据结构,随后再进行完整渲染以获得最佳体验。 |