AI-video-lifeplan-demo/.qoder/repowiki/zh/content/核心功能/数据提取.md

377 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据提取
<cite>
**本文引用的文件列表**
- [backend/extractor.py](file://backend/extractor.py)
- [backend/data_builder.py](file://backend/data_builder.py)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py)
- [backend/investigate_video_extraction.py](file://backend/investigate_video_extraction.py)
- [backend/investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts)
- [PROJECT_README.md](file://PROJECT_README.md)
- [requirements.txt](file://requirements.txt)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件聚焦于“数据提取”模块,系统性阐述两类输入数据的提取与结构化流程:
- PDF 报告(财务规划类):通过大模型解析并抽取结构化信息(如客户基本信息、资产/收入/支出、重大事件、保险建议等)。
- 访谈视频:通过音频转写与时间戳抽取,生成可用于视频剪辑与B-Roll素材匹配的结构化片段。
同时,文档说明数据提取后的内部表示形式、与后续脚本生成与数据构建模块的数据契约关系,并给出常见问题与扩展方法。
## 项目结构
数据提取相关的核心文件分布如下:
- 提取层:backend/extractor.py(待实现)、backend/video_processor/utils.py(FFmpeg工具)、backend/investigate_video_extraction.py 与 backend/investigate_subtitle_extraction.py(演示实现)
- 结构化输出与契约:backend/video_processor/schemas.py(视频分析结果结构)、frontend/src/render-props-types.ts(前端渲染契约)
- 数据构建:backend/data_builder.py(基于PDF提取参数进行财务模拟)
```mermaid
graph TB
subgraph "输入"
PDF["PDF 报告"]
VIDEO["访谈视频"]
end
subgraph "提取层"
EX["extractor.py<br/>PDF/视频提取接口待实现"]
VU["video_processor/utils.py<br/>FFmpeg 工具"]
IVV["investigate_video_extraction.py<br/>视频提取演示"]
ISV["investigate_subtitle_extraction.py<br/>字幕/转写演示"]
end
subgraph "结构化输出"
VS["schemas.py<br/>VideoSegment/KeyMoment/VideoAnalysisResult"]
RP["render-props-types.ts<br/>前端渲染契约"]
end
subgraph "后续模块"
DB["data_builder.py<br/>财务模拟与图表数据"]
end
PDF --> EX
VIDEO --> EX
VIDEO --> VU
EX --> VS
VS --> RP
EX --> DB
DB --> RP
```
图表来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L291)
- [backend/investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L1-L413)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L132-L142)
- [requirements.txt](file://requirements.txt#L1-L34)
## 核心组件
- PDF 提取器(PDFExtractor):面向财务规划PDF,期望返回结构化数据(客户信息、财务数据、重大事件、保险建议等),当前为占位实现,需接入大模型API完成解析。
- 视频提取器(VideoExtractor):面向访谈视频,期望返回转写文本、时间戳片段、推荐B-Roll片段等,当前为占位实现,需接入Whisper与FFmpeg。
- 视频处理工具(FFmpeg封装):提供视频时长查询、音频提取、视频切片等能力,支撑视频提取流程。
- 视频结构化模式(schemas.py):定义视频片段、关键时刻、完整分析结果的标准结构,确保与前端契约一致。
- 数据构建(data_builder.py):消费PDF提取结果,进行财务模拟与图表数据转换,输出与前端契约一致的结构。
章节来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
## 架构总览
下图展示了从原始文件到结构化数据再到前端渲染的整体流程。
```mermaid
sequenceDiagram
participant U as "用户"
participant EX as "extractor.py"
participant VU as "FFmpeg 工具"
participant IV as "视频提取演示"
participant IS as "字幕提取演示"
participant VS as "schemas.py"
participant DB as "data_builder.py"
participant RP as "render-props-types.ts"
U->>EX : 提供 PDF/视频
EX->>EX : 占位实现待完成
EX->>VU : 使用 FFmpeg 获取时长/提取音频视频流程
EX->>IV : 参考演示实现上传视频、结构化抽取
EX->>IS : 参考演示实现字幕/转写
EX-->>VS : 输出 VideoSegment/KeyMoment/VideoAnalysisResult
EX-->>DB : 输出 PDF 结构化数据
DB-->>RP : 输出图表数据资产枯竭/现金流
VS-->>RP : 输出视频片段与脚本同步点
```
图表来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L291)
- [backend/investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L1-L413)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [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)
## 详细组件分析
### PDF 提取流程与内部表示
- 输入:财务规划PDF(日文)。
- 处理目标:结构化关键信息,便于后续财务模拟与脚本生成。
- 当前状态:占位实现,需接入大模型API完成PDF解析与结构化输出。
- 内部表示(预期):包含客户信息、财务数据、重大事件、保险建议等字段,作为data_builder的输入。
```mermaid
flowchart TD
Start(["开始:接收 PDF 路径"]) --> CheckKey["检查环境变量<br/>GEMINI_API_KEY"]
CheckKey --> KeyOK{"密钥存在?"}
KeyOK --> |否| RaiseErr["抛出异常:缺少 API 密钥"]
KeyOK --> |是| Upload["上传 PDF 至 Gemini API"]
Upload --> Prompt["构造提示词<br/>要求结构化 JSON 输出"]
Prompt --> Parse["解析响应并校验结构"]
Parse --> Done(["返回结构化数据"])
RaiseErr --> End(["结束"])
Done --> End
```
图表来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
章节来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
### 视频元数据与转写流程(FFmpeg + Whisper)
- 元数据提取:使用ffprobe获取视频时长;使用ffmpeg提取音频(采样率、编码等可配置)。
- 转写与时间戳:参考演示脚本,先提取音频,再调用Whisper API进行转写与时间戳抽取。
- 片段结构化:输出VideoSegment/KeyMoment等结构,便于后续B-Roll匹配与视频剪辑。
```mermaid
sequenceDiagram
participant V as "视频文件"
participant U as "FFmpeg 工具"
participant W as "Whisper API"
participant S as "schemas.py"
participant R as "render-props-types.ts"
V->>U : get_video_duration()
U-->>V : 返回时长秒
V->>U : extract_audio()
U-->>V : 输出音频文件
V->>W : 上传音频并请求转写
W-->>V : 返回转写文本与时间戳
V->>S : 组装 VideoSegment/KeyMoment
S-->>R : 输出符合前端契约的结构
```
图表来源
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
章节来源
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L291)
- [backend/investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L1-L413)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
### 视频结构化模式(schemas.py)
- VideoSegment:视频片段,包含起止时间、描述、转写、重要性、标签、说话人等。
- KeyMoment:关键时刻,包含时间戳、类型(引述/图表/情感/动作)、内容与上下文。
- VideoAnalysisResult:完整分析结果,包含源视频路径、总时长、策略、片段列表、关键时刻列表与额外元数据。
```mermaid
classDiagram
class VideoSegment {
+float start_time
+float end_time
+string description
+string transcript
+string importance
+string[] tags
+string speaker
+float duration
+to_dict() dict
}
class KeyMoment {
+float timestamp
+string type
+string content
+string context
+to_dict() dict
}
class VideoAnalysisResult {
+string source_video
+float duration
+string strategy
+VideoSegment[] segments
+KeyMoment[] key_moments
+dict metadata
+to_dict() dict
+get_high_importance_segments() VideoSegment[]
+get_quotes() KeyMoment[]
}
VideoAnalysisResult --> VideoSegment : "包含"
VideoAnalysisResult --> KeyMoment : "包含"
```
图表来源
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
章节来源
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
### 数据契约与前后端衔接
- 前端契约(render-props-types.ts):定义YearlySnapshot、CashFlowData、ScriptSegment、AssetCollection等类型,确保后端生成的数据与前端渲染一致。
- 后端数据构建(data_builder.py):将PDF提取参数转化为财务模拟时间线与图表数据,输出与前端契约一致的结构。
```mermaid
erDiagram
YEARLYSNAPSHOT {
int year
int repAge
int spouseAge
int income
int expenditure
int assetBalance
string[] events
boolean isCritical
}
CASHFLOWDATA {
int year
int age
int totalIncome
int livingExpense
int housingExpense
int educationExpense
int taxExpense
int eventExpense
int totalExpense
int netCashFlow
int assetBalance
}
RENDERPROPS {
string title
string currencyUnit
int duration
string clientName
string generatedAt
}
RENDERPROPS ||--o{ YEARLYSNAPSHOT : "assetDepletion.timeline"
RENDERPROPS ||--o{ CASHFLOWDATA : "cashFlow.timeline"
```
图表来源
- [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)
章节来源
- [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)
## 依赖关系分析
- 外部依赖:Google Gemini(PDF/视频理解)、OpenAI Whisper(音频转写)、FFmpeg/ffprobe(媒体处理)、Pexels(B-Roll素材检索,当前占位)。
- 内部耦合:extractor.py 与 video_processor/utils.py、video_processor/schemas.py 存在潜在协作关系;data_builder.py 依赖 PDF 提取结果;前端契约约束后端输出。
```mermaid
graph LR
REQ["requirements.txt"] --> GEM["google-generativeai"]
REQ --> OAI["openai"]
REQ --> FFPY["ffmpeg-python"]
REQ --> REQ["requests"]
EX["extractor.py"] --> GEM
EX --> OAI
EX --> FFPY
VU["video_processor/utils.py"] --> FFPY
VS["video_processor/schemas.py"] --> RP["render-props-types.ts"]
DB["data_builder.py"] --> RP
```
图表来源
- [requirements.txt](file://requirements.txt#L1-L34)
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)
- [backend/data_builder.py](file://backend/data_builder.py#L1-L200)
章节来源
- [requirements.txt](file://requirements.txt#L1-L34)
## 性能考量
- API成本控制:视频/音频上传与转写会产生Token/调用费用,应优先选择合适粒度(电影级摘要 vs 秒级/词级时间戳)以平衡精度与成本。
- 媒体处理优化:音频提取采用流复制(stream copy)可避免重编码,提升速度;批量处理时注意并发与资源限制。
- 缓存与复用:翻译与API调用结果可缓存,减少重复请求;视频片段与B-Roll素材可本地缓存以降低网络开销。
## 故障排查指南
- API密钥缺失
- 现象:初始化PDF/视频提取器时报错。
- 排查:确认环境变量是否正确设置;检查.env文件是否存在且包含有效密钥。
- FFmpeg/ffprobe不可用
- 现象:获取视频时长或提取音频失败。
- 排查:安装FFmpeg/ffprobe并加入PATH;使用工具函数检测可用性。
- PDF格式不兼容或加密
- 现象:PDF解析失败或返回空数据。
- 排查:确认PDF可读且未加密;若为扫描版PDF,考虑OCR预处理;优先使用大模型直接解析PDF而非本地库。
- 视频/音频质量差导致转写不准
- 现象:转写文本与实际内容不符。
- 排查:提高音频采样率、清理背景噪音;必要时人工校正关键片段。
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L217-L233)
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
## 结论
- 当前数据提取模块处于占位阶段,PDF与视频提取逻辑尚未实现,但已明确技术栈与数据契约。
- 建议优先完成以下工作:PDF解析(Gemini API)、视频转写(Whisper)、FFmpeg工具链完善、结构化输出规范化(schemas)。
- 完成后,数据将严格遵循前端契约,无缝衔接财务模拟与视频渲染流程。
## 附录
### 接口调用方式与错误处理(基于现有占位实现)
- PDF提取
- 函数入口:[extract_pdf_data](file://backend/extractor.py#L74-L84)
- 类入口:[PDFExtractor.extract](file://backend/extractor.py#L23-L43)
- 错误处理:当前抛出未实现异常,需补充API调用与参数校验。
- 视频提取
- 函数入口:[extract_video_data](file://backend/extractor.py#L79-L84)
- 类入口:[VideoExtractor.extract](file://backend/extractor.py#L53-L72)
- 错误处理:当前抛出未实现异常,需补充FFmpeg与Whisper调用。
- FFmpeg工具
- 获取时长:[get_video_duration](file://backend/video_processor/utils.py#L13-L47)
- 提取音频:[extract_audio](file://backend/video_processor/utils.py#L49-L95)
- 切片视频:[slice_video](file://backend/video_processor/utils.py#L97-L146)
- 检测安装:[check_ffmpeg_installed](file://backend/video_processor/utils.py#L148-L164)
章节来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
### 扩展自定义解析器的方法
- PDF解析器扩展
- 在PDFExtractor中实现extract方法,调用Gemini API并按预期字段返回。
- 建议:增加参数校验、响应解析与schema验证。
- 视频解析器扩展
- 在VideoExtractor中实现extract方法,调用Whisper API并解析时间戳。
- 建议:支持多粒度(电影级/秒级/词级)与多策略(视频直传/音频转写)。
- 媒体处理扩展
- 在video_processor/utils.py中新增工具函数,统一管理FFmpeg命令与错误处理。
- 契约一致性
- 保持输出结构与frontend/src/render-props-types.ts一致,避免前后端不匹配。
章节来源
- [backend/extractor.py](file://backend/extractor.py#L1-L84)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251)