AI-video-lifeplan-demo/.qoder/repowiki/zh/content/架构设计/媒体获取.md

340 lines
17 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>
**本文引用的文件**
- [main.py](file://main.py)
- [backend/media_fetcher.py](file://backend/media_fetcher.py)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py)
- [backend/scripter.py](file://backend/scripter.py)
- [backend/extractor.py](file://backend/extractor.py)
- [backend/data_builder.py](file://backend/data_builder.py)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json)
- [assets/1_processed/translation_cache.json](file://assets/1_processed/translation_cache.json)
- [assets/1_processed/video_extractions/№1_基本情報_extraction.json](file://assets/1_processed/video_extractions/№1_基本情報_extraction.json)
- [assets/1_processed/video_extractions/№2_ライフイベント_extraction.json](file://assets/1_processed/video_extractions/№2_ライフイベント_extraction.json)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕“B-Roll素材获取系统”展开,聚焦于如何通过Pexels API自动检索与财务规划主题相关的背景视频片段。文档解释关键词提取机制(从PDF、视频转写、生成的解说脚本中识别“退休”“家庭”“教育”等关键主题),并结合main.py中的fetch_broll方法说明媒体获取在整个流水线中的协调流程。面向初学者提供媒体获取流程图,面向高级开发者则深入分析API速率限制处理、素材质量评估、版权合规性检查以及本地缓存策略,并给出扩展至其他媒体资源提供商或自定义素材库集成的实践建议。
## 项目结构
媒体获取系统位于后端目录,主要涉及以下模块:
- 后端媒体获取:backend/media_fetcher.py(当前为占位实现)
- 调查与完整实现:backend/investigate_media_fetch.py(包含翻译器与Pexels抓取器)
- 关键词来源:backend/extractor.py(PDF与视频抽取)、backend/scripter.py(脚本生成)
- 渲染参数构建:backend/data_builder.py(用于将B-Roll映射到渲染参数)
- 流水线编排:main.py(VideoGeneratorPipeline.run串联各阶段)
```mermaid
graph TB
A["main.py<br/>VideoGeneratorPipeline.run"] --> B["backend/media_fetcher.py<br/>fetch_broll(占位)"]
A --> C["backend/scripter.py<br/>generate_script(占位)"]
A --> D["backend/extractor.py<br/>extract_pdf_data/extract_video_data(占位)"]
A --> E["backend/data_builder.py<br/>build_chart_data(占位)"]
B --> F["backend/investigate_media_fetch.py<br/>KeywordTranslator/PexelsFetcher(完整实现)"]
F --> G["assets/1_processed/translation_cache.json<br/>翻译缓存"]
F --> H["assets/1_processed/broll_fetch_results.json<br/>下载结果汇总"]
D --> I["assets/1_processed/video_extractions/*_extraction.json<br/>视频抽取结果(含broll_keywords)"]
```
图表来源
- [main.py](file://main.py#L48-L83)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L62-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L148-L268)
- [backend/scripter.py](file://backend/scripter.py#L62-L69)
- [backend/extractor.py](file://backend/extractor.py#L74-L84)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- [assets/1_processed/translation_cache.json](file://assets/1_processed/translation_cache.json#L1-L12)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [assets/1_processed/video_extractions/№1_基本情報_extraction.json](file://assets/1_processed/video_extractions/№1_基本情報_extraction.json#L73-L104)
- [assets/1_processed/video_extractions/№2_ライフイベント_extraction.json](file://assets/1_processed/video_extractions/№2_ライフイベント_extraction.json#L1-L104)
章节来源
- [main.py](file://main.py#L48-L83)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L1-L359)
## 核心组件
- MediaFetcher(占位):定义fetch_broll接口,负责从Pexels搜索并下载B-Roll,当前抛出未实现异常。
- KeywordTranslator(调查实现):使用Gemini将日文关键词翻译为英文,带缓存避免重复调用。
- PexelsFetcher(调查实现):基于Pexels API搜索视频、选择合适清晰度、下载到本地并记录元数据。
- VideoGeneratorPipeline.fetch_broll(占位):在流水线中调用媒体获取,返回字典形式的B-Roll映射。
- 关键词来源:
- PDF抽取:提取客户信息、财务数据、重大事件等,作为脚本生成输入。
- 视频抽取:输出转写文本与时间戳,其中包含broll_keywords。
- 脚本生成:生成分段脚本,供后续抽取关键词。
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L45-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L148-L268)
- [main.py](file://main.py#L136-L144)
- [backend/extractor.py](file://backend/extractor.py#L15-L84)
- [backend/scripter.py](file://backend/scripter.py#L14-L69)
## 架构总览
媒体获取在整体流水线中的位置如下:
```mermaid
sequenceDiagram
participant CLI as "命令行入口(main.py)"
participant Pipe as "VideoGeneratorPipeline"
participant Ext as "extract_pdf/extract_video"
participant Scr as "generate_script"
participant MF as "fetch_broll(占位)"
participant IF as "investigate_media_fetch.py<br/>翻译+Pexels抓取"
participant DB as "data_builder"
CLI->>Pipe : run()
Pipe->>Ext : 提取PDF/视频数据
Pipe->>Scr : 生成脚本(含segments)
Pipe->>MF : fetch_broll(script)
MF-->>IF : 使用翻译器+Pexels抓取
IF-->>Pipe : 返回本地B-Roll路径映射
Pipe->>DB : 构建渲染参数(含assets.broll)
Pipe-->>CLI : 输出视频路径
```
图表来源
- [main.py](file://main.py#L48-L83)
- [main.py](file://main.py#L136-L144)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L62-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L270-L359)
- [backend/data_builder.py](file://backend/data_builder.py#L145-L199)
## 详细组件分析
### 组件A:媒体获取流水线(从脚本抽取关键词到Pexels抓取)
- 关键词来源与映射
- PDF抽取:提供财务与生命周期事件的基础数据。
- 视频抽取:输出转写与时间戳,其中包含broll_keywords,可直接作为关键词源。
- 脚本生成:生成segments,每个segment包含文本,可用于进一步抽取主题关键词(如“退休”“家庭”“教育”)。
- 占位实现与调查实现对比
- 占位实现:MediaFetcher.fetch_broll抛出未实现异常,VideoGeneratorPipeline.fetch_broll返回模拟数据。
- 调查实现:KeywordTranslator与PexelsFetcher提供完整的翻译与抓取逻辑,包括缓存、质量筛选与下载进度显示。
```mermaid
flowchart TD
Start(["开始"]) --> Src["确定关键词来源<br/>PDF/视频抽取/脚本"]
Src --> KWF["关键词清洗与去重"]
KWF --> Trans["翻译为英文(缓存命中优先)"]
Trans --> Search["Pexels搜索(限定时长/尺寸)"]
Search --> Quality{"满足质量要求?"}
Quality --> |否| Search
Quality --> |是| Download["下载到本地assets/1_processed/broll/"]
Download --> Record["记录元数据(路径/时长/摄影师)"]
Record --> End(["结束"])
```
图表来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L67-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L220-L268)
- [assets/1_processed/translation_cache.json](file://assets/1_processed/translation_cache.json#L1-L12)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L41)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L67-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/extractor.py](file://backend/extractor.py#L23-L41)
- [assets/1_processed/video_extractions/№1_基本情報_extraction.json](file://assets/1_processed/video_extractions/№1_基本情報_extraction.json#L73-L104)
- [assets/1_processed/video_extractions/№2_ライフイベント_extraction.json](file://assets/1_processed/video_extractions/№2_ライフイベント_extraction.json#L1-L104)
### 组件B:类关系与职责
```mermaid
classDiagram
class KeywordTranslator {
+translate(japanese_keywords) Dict
-_load_cache() Dict
-_save_cache() void
-cache_file
-cache
-model
}
class PexelsFetcher {
+search_videos(query, max_results, min_duration) List
+download_video(video, keyword) Optional~str~
-api_key
-output_dir
-base_url
}
class MediaFetcher {
+fetch_broll(keywords, max_per_keyword) Dict
-_translate_keyword(japanese_keyword) str
-_download_video(url, output_path) str
-api_key
-base_url
}
KeywordTranslator --> PexelsFetcher : "配合使用"
MediaFetcher ..> KeywordTranslator : "占位实现中计划使用"
MediaFetcher ..> PexelsFetcher : "占位实现中计划使用"
```
图表来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L45-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L148-L268)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
章节来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L45-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L148-L268)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
### 组件C:API调用序列(以调查实现为例)
```mermaid
sequenceDiagram
participant Caller as "调用方"
participant KT as "KeywordTranslator"
participant Pex as "PexelsFetcher"
participant API as "Pexels API"
participant FS as "文件系统"
Caller->>KT : translate(japanese_keywords)
KT->>KT : 检查缓存
KT->>API : Gemini翻译(批量)
API-->>KT : 英文关键词映射
KT->>KT : 更新缓存并保存
Caller->>Pex : search_videos(english_query, ...)
Pex->>API : GET /videos/search
API-->>Pex : 视频列表(JSON)
Pex->>Pex : 过滤HD/时长/尺寸
Pex->>FS : 下载MP4到本地
FS-->>Pex : 文件路径
Pex-->>Caller : 元数据列表
```
图表来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L104-L136)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L220-L268)
章节来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L104-L136)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L220-L268)
## 依赖关系分析
- 外部依赖
- Pexels API:用于视频搜索与下载。
- Gemini API:用于关键词翻译。
- Whisper/OpenAI API:用于视频转写(当前为占位)。
- 内部依赖
- main.py的VideoGeneratorPipeline.run串联PDF抽取、视频抽取、脚本生成、媒体获取、渲染参数构建与渲染。
- media_fetcher.py的fetch_broll接口被pipeline调用,当前返回模拟数据。
- investigate_media_fetch.py提供可运行的翻译与抓取实现,可直接复用。
```mermaid
graph TB
M["main.py<br/>VideoGeneratorPipeline"] --> MF["backend/media_fetcher.py<br/>fetch_broll(占位)"]
M --> SCR["backend/scripter.py<br/>generate_script(占位)"]
M --> EXT["backend/extractor.py<br/>extract_pdf/extract_video(占位)"]
M --> DB["backend/data_builder.py<br/>build_chart_data(占位)"]
MF --> IM["backend/investigate_media_fetch.py<br/>翻译+Pexels抓取"]
IM --> T["translation_cache.json"]
IM --> R["broll_fetch_results.json"]
```
图表来源
- [main.py](file://main.py#L48-L83)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L62-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L270-L359)
- [assets/1_processed/translation_cache.json](file://assets/1_processed/translation_cache.json#L1-L12)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
章节来源
- [main.py](file://main.py#L48-L83)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L62-L72)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L270-L359)
## 性能考量
- API速率限制处理
- 批量翻译:KeywordTranslator对未缓存的关键词进行批量翻译,减少请求次数。
- 请求节流:PexelsFetcher在搜索时设置合理per_page与最小时长,避免无效请求。
- 缓存策略:translation_cache.json持久化翻译结果,避免重复调用Gemini。
- 素材质量评估
- 尺寸与方向:PexelsFetcher优先选择横向、中等尺寸的视频,便于编辑。
- 清晰度与时长:优先选择HD且满足最低时长的视频,确保可用性。
- 版权合规性检查
- Pexels提供商用许可的视频文件链接,下载前应确认授权范围。
- 记录摄影师信息,便于注明来源与合规追踪。
- 本地缓存策略
- 已下载文件存在即跳过,避免重复下载。
- 结果汇总文件broll_fetch_results.json便于二次使用与审计。
章节来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L220-L268)
- [assets/1_processed/translation_cache.json](file://assets/1_processed/translation_cache.json#L1-L12)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
## 故障排查指南
- 环境变量缺失
- PEXELS_API_KEY或GEMINI_API_KEY未配置会导致初始化失败或请求错误。
- 翻译解析失败
- Gemini返回内容格式不符合预期时,调查脚本提供回退逻辑(使用原文)。
- Pexels请求异常
- 捕获网络异常并返回空列表,避免中断流程。
- 下载中断
- 发生异常时删除部分文件,防止损坏文件残留。
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L18-L24)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L139-L145)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L216-L218)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L263-L267)
## 结论
媒体获取系统通过“关键词提取—翻译—Pexels搜索—下载—缓存”的闭环,实现了财务规划主题的B-Roll自动化采集。当前仓库提供了完整的调查实现,可直接用于生产环境;同时保留了占位的media_fetcher与pipeline方法,便于逐步替换为正式实现。建议在正式实现中:
- 完成MediaFetcher.fetch_broll的Pexels集成;
- 在pipeline中注入真实关键词来源(PDF/视频抽取/脚本);
- 引入更严格的错误处理与重试机制;
- 增加素材元数据校验与合规性检查。
## 附录
### 初学者媒体获取流程图
```mermaid
flowchart TD
A["输入:PDF/视频/脚本"] --> B["抽取关键词<br/>PDF/视频抽取/脚本"]
B --> C["翻译为英文(缓存命中优先)"]
C --> D["Pexels搜索(限定时长/清晰度)"]
D --> E{"找到可用素材?"}
E --> |否| C
E --> |是| F["下载到本地assets/1_processed/broll/"]
F --> G["记录元数据并保存汇总"]
G --> H["返回B-Roll映射给渲染参数"]
```
图表来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L67-L146)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L158-L214)
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L220-L268)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
### 高级开发者实践建议
- 扩展支持其他媒体提供商
- 参考PexelsFetcher模式,新增ProviderFetcher类,统一接口(search_videos、download_video)。
- 在pipeline中按优先级或预算策略选择不同提供商。
- 自定义素材库集成
- 将本地素材库路径加入搜索链路,先查本地再查在线API。
- 对本地素材进行索引与元数据管理,保持与在线素材一致的数据结构。
- 错误恢复与重试
- 为Pexels请求与下载增加指数退避重试。
- 对翻译失败的关键词记录日志并人工审核。
- 渲染参数映射
- 将返回的B-Roll映射到render_props.json的assets.broll字段,确保时序与脚本同步。
章节来源
- [backend/investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L148-L268)
- [backend/data_builder.py](file://backend/data_builder.py#L145-L199)