# 媒体获取
**本文引用的文件**
- [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)
## 目录
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
VideoGeneratorPipeline.run"] --> B["backend/media_fetcher.py
fetch_broll(占位)"]
A --> C["backend/scripter.py
generate_script(占位)"]
A --> D["backend/extractor.py
extract_pdf_data/extract_video_data(占位)"]
A --> E["backend/data_builder.py
build_chart_data(占位)"]
B --> F["backend/investigate_media_fetch.py
KeywordTranslator/PexelsFetcher(完整实现)"]
F --> G["assets/1_processed/translation_cache.json
翻译缓存"]
F --> H["assets/1_processed/broll_fetch_results.json
下载结果汇总"]
D --> I["assets/1_processed/video_extractions/*_extraction.json
视频抽取结果(含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
翻译+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["确定关键词来源
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
VideoGeneratorPipeline"] --> MF["backend/media_fetcher.py
fetch_broll(占位)"]
M --> SCR["backend/scripter.py
generate_script(占位)"]
M --> EXT["backend/extractor.py
extract_pdf/extract_video(占位)"]
M --> DB["backend/data_builder.py
build_chart_data(占位)"]
MF --> IM["backend/investigate_media_fetch.py
翻译+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["抽取关键词
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)