AI-video-lifeplan-demo/.qoder/repowiki/zh/content/核心功能/B-Roll素材获取.md

309 lines
15 KiB
Markdown
Raw 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.

# B-Roll素材获取
<cite>
**本文引用的文件**
- [backend/media_fetcher.py](file://backend/media_fetcher.py)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json)
- [main.py](file://main.py)
- [PROJECT_README.md](file://PROJECT_README.md)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts)
- [requirements.txt](file://requirements.txt)
- [backend/extractor.py](file://backend/extractor.py)
- [backend/scripter.py](file://backend/scripter.py)
- [.gitignore](file://.gitignore)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本技术文档聚焦于B-Roll素材自动获取功能,围绕 backend/media_fetcher.py 展开,说明其如何通过 Pexels API 根据脚本内容智能检索匹配的背景视频片段。文档涵盖:
- 关键词提取与翻译:从日语解说脚本中识别关键主题(如“家庭”“退休”“教育”),并映射为英文搜索词。
- 视频筛选标准:分辨率、时长、版权许可等要求及下载管理机制。
- 代码示例路径:API请求构造、响应处理与本地缓存策略。
- broll_fetch_results.json 结构说明及其在后续渲染阶段的引用方式。
- 故障排查:API密钥失效、网络超时、素材质量不佳等问题的应对。
- 扩展方案:替换其他素材源(如Pixabay、Coverr等)的思路。
## 项目结构
该仓库采用“Python后端 + Node.js/Remotion 前端”的混合架构。与B-Roll素材获取直接相关的目录与文件如下:
- backend/media_fetcher.py:B-Roll素材抓取器,负责调用Pexels API、关键词翻译、下载与缓存。
- assets/1_processed/broll_fetch_results.json:已抓取素材的结果索引,供渲染阶段引用。
- main.py:主流程编排,串联PDF提取、脚本生成、B-Roll抓取、图表数据构建、渲染属性生成与渲染。
- frontend/src/render-props-types.ts:渲染属性的数据契约,定义了assets.broll的结构。
- requirements.txt:Python依赖清单,包含requests等网络与媒体处理相关库。
- backend/extractor.py、backend/scripter.py:分别负责PDF与视频提取、脚本生成(当前为占位实现,未来用于提供关键词)。
- .gitignore:忽略输出视频与环境变量文件,保留JSON元数据。
```mermaid
graph TB
A["main.py<br/>主流程编排"] --> B["backend/media_fetcher.py<br/>B-Roll抓取器"]
A --> C["assets/1_processed/broll_fetch_results.json<br/>抓取结果索引"]
A --> D["frontend/src/render-props-types.ts<br/>渲染属性契约"]
B --> E["Pexels API"]
B --> F["本地缓存目录<br/>assets/1_processed/broll/"]
```
图示来源
- [main.py](file://main.py#L136-L144)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L132-L141)
- [.gitignore](file://.gitignore#L36-L58)
## 核心组件
- MediaFetcher 类:封装Pexels API交互、关键词翻译、视频下载与缓存逻辑。
- fetch_broll 函数:便捷入口,从脚本中抽取关键词并触发抓取。
- broll_fetch_results.json:记录每个关键词对应的英文名与本地视频列表,包含时长与摄影师信息。
- 渲染属性契约:定义 assets.broll 的键值映射,供前端渲染使用。
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
## 架构总览
下图展示了B-Roll抓取在整体流水线中的位置与数据流。
```mermaid
sequenceDiagram
participant CLI as "命令行入口<br/>main.py"
participant Gen as "脚本生成器<br/>backend/scripter.py"
participant MF as "B-Roll抓取器<br/>backend/media_fetcher.py"
participant PEX as "Pexels API"
participant FS as "本地存储<br/>assets/1_processed/broll/"
participant RP as "渲染属性<br/>render_props.json"
participant FE as "前端渲染<br/>Remotion"
CLI->>Gen : 生成日语脚本
CLI->>MF : 提供脚本并请求B-Roll
MF->>MF : 抽取关键词并翻译为英文
MF->>PEX : 发送搜索请求
PEX-->>MF : 返回视频资源列表
MF->>FS : 下载并保存视频
MF-->>CLI : 返回本地路径映射
CLI->>RP : 写入render_props.json
FE-->>CLI : 使用render_props.json进行渲染
```
图示来源
- [main.py](file://main.py#L136-L144)
- [backend/scripter.py](file://backend/scripter.py#L1-L69)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L72)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
## 详细组件分析
### MediaFetcher 类设计与职责
- 负责初始化与校验PEXELS_API_KEY,设置基础URL。
- 提供 fetch_broll(keywords, max_per_keyword) 接口,返回关键词到视频URL的映射。
- 提供 _translate_keyword(japanese_keyword) 占位方法,未来接入Gemini进行日英翻译并缓存。
- 提供 _download_video(url, output_path) 占位方法,未来实现下载、进度条、格式校验与缓存。
```mermaid
classDiagram
class MediaFetcher {
+api_key : string
+base_url : string
+__init__(api_key)
+fetch_broll(keywords, max_per_keyword) Dict
+_translate_keyword(japanese_keyword) string
+_download_video(url, output_path) string
}
```
图示来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L72)
### 关键词提取与翻译策略
- 输入:来自脚本生成器的脚本对象,包含分段文本。
- 提取:遍历脚本的分段,从每段文本中抽取关键词(占位实现,未来可结合NLP或LLM)。
- 翻译:将日文关键词翻译为英文(占位实现,建议使用Gemini Pro),并缓存翻译结果以减少重复调用。
- 映射:将英文关键词作为Pexels搜索词,限制每关键词最多返回若干个视频。
```mermaid
flowchart TD
Start(["开始"]) --> LoadScript["加载脚本对象"]
LoadScript --> Iterate["遍历脚本分段"]
Iterate --> Extract["抽取关键词占位"]
Extract --> Translate["翻译为英文Gemini并缓存"]
Translate --> Search["调用Pexels搜索接口"]
Search --> Filter["按分辨率/时长/许可筛选"]
Filter --> Download["下载到本地缓存目录"]
Download --> Index["写入broll_fetch_results.json"]
Index --> End(["结束"])
```
图示来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L72)
- [backend/scripter.py](file://backend/scripter.py#L22-L48)
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L72)
- [backend/scripter.py](file://backend/scripter.py#L22-L48)
### 视频筛选标准与下载管理
- 分辨率与时长:建议在搜索后对返回结果按分辨率与目标时长范围进行过滤,优先选择高分辨率且时长接近目标的素材。
- 版权许可:Pexels默认许可适合商用,但应确保符合项目用途;必要时可在筛选中排除非CC0或非商业许可的素材。
- 下载与缓存:
- 将视频下载至 assets/1_processed/broll/ 目录,命名规则建议包含关键词与唯一标识,便于去重与复用。
- 在 broll_fetch_results.json 中记录每个关键词的英文名、本地文件路径、时长与摄影师信息,便于渲染阶段引用。
- 使用缓存避免重复下载同一素材,可基于哈希或URL指纹判断是否已存在。
```mermaid
flowchart TD
A["Pexels搜索结果"] --> B["按分辨率筛选"]
B --> C["按时长范围筛选"]
C --> D["按许可筛选"]
D --> E["下载到本地缓存"]
E --> F["更新broll_fetch_results.json"]
F --> G["返回本地路径映射"]
```
图示来源
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [.gitignore](file://.gitignore#L36-L58)
章节来源
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [.gitignore](file://.gitignore#L36-L58)
### API请求构造与响应处理
- 请求构造:使用 requests 库发送HTTP GET请求到 Pexels 搜索接口,携带认证头与查询参数(关键词、数量上限等)。
- 响应处理:解析JSON,提取视频URL、时长、分辨率、许可等字段;对不符合条件的条目进行过滤。
- 错误处理:捕获网络异常、超时、HTTP状态码错误;对空结果或失败重试进行降级处理。
章节来源
- [requirements.txt](file://requirements.txt#L16-L18)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L72)
### broll_fetch_results.json 结构与渲染引用
- 结构要点:
- 键为日文关键词(如“家族”“老後”“教育”)。
- 字段 english:英文关键词。
- 字段 videos:数组,包含多个视频条目,每项含 filepath、duration、photographer。
- 渲染引用:
- 渲染属性 assets.broll 期望为“关键词 -> 路径”的映射;当前broll_fetch_results.json以关键词为根节点,渲染阶段需将其转换为 assets.broll 的扁平映射,或将渲染阶段直接读取该JSON并按需转换。
- 前端契约中 assets.broll 为 Record<string, string>,即“关键词 -> 视频路径”。
```mermaid
erDiagram
KEYWORDS {
string 日文关键词 PK
string 英文关键词
}
VIDEOS {
string filepath
number duration
string photographer
}
KEYWORDS ||--o{ VIDEOS : "包含"
```
图示来源
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
章节来源
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
### 代码示例路径(不展示具体代码)
- 初始化与校验API密钥与基础URL
- 参考路径:[backend/media_fetcher.py](file://backend/media_fetcher.py#L18-L24)
- fetch_broll 接口与占位实现
- 参考路径:[backend/media_fetcher.py](file://backend/media_fetcher.py#L25-L43)
- _translate_keyword 占位方法
- 参考路径:[backend/media_fetcher.py](file://backend/media_fetcher.py#L44-L51)
- _download_video 占位方法
- 参考路径:[backend/media_fetcher.py](file://backend/media_fetcher.py#L52-L60)
- 主流程中调用 fetch_broll
- 参考路径:[main.py](file://main.py#L136-L144)
- 渲染属性契约中 assets.broll 的定义
- 参考路径:[frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
## 依赖关系分析
- 外部依赖:
- requests:用于HTTP请求与下载。
- ffmpeg-python:用于视频处理(当前媒体抓取模块为占位,未来可能在此集成)。
- 内部依赖:
- main.py 编排调用 media_fetcher.fetch_broll。
- frontend/src/render-props-types.ts 定义渲染阶段消费的数据结构。
- .gitignore 控制资产目录的版本控制行为,避免大文件入库。
```mermaid
graph LR
REQ["requests"] --> MF["backend/media_fetcher.py"]
FFPY["ffmpeg-python"] --> MF
MF --> MAIN["main.py"]
MF --> TYPES["frontend/src/render-props-types.ts"]
GIT[".gitignore"] --> MF
```
图示来源
- [requirements.txt](file://requirements.txt#L16-L18)
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72)
- [main.py](file://main.py#L136-L144)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
- [.gitignore](file://.gitignore#L36-L58)
章节来源
- [requirements.txt](file://requirements.txt#L16-L18)
- [main.py](file://main.py#L136-L144)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
- [.gitignore](file://.gitignore#L36-L58)
## 性能考量
- 并发与限速:Pexels搜索接口可能有限额,建议对关键词并发请求进行节流,避免触发速率限制。
- 缓存策略:对翻译结果与下载的视频建立本地缓存,命中则跳过网络请求,显著降低延迟与成本。
- 过滤前置:在下载前完成分辨率与时长过滤,减少无效IO。
- 断点续传:对于大文件下载,可考虑断点续传以提升稳定性。
## 故障排查指南
- API密钥失效
- 现象:初始化时报错或请求返回未授权。
- 处理:检查 .env 文件是否正确配置PEXELS_API_KEY;确认密钥有效且有访问权限。
- 参考路径:[backend/media_fetcher.py](file://backend/media_fetcher.py#L18-L24)
- 网络超时或连接失败
- 现象:请求抛出超时或连接异常。
- 处理:增加重试次数与指数退避;检查代理与防火墙;在网络稳定后再试。
- 素材质量不佳
- 现象:分辨率过低、时长不符、许可不满足需求。
- 处理:在筛选阶段严格限定分辨率与时长;优先选择高评分与合适许可的素材;必要时回退到备用关键词。
- 渲染阶段找不到B-Roll路径
- 现象:渲染报错提示缺少assets.broll映射。
- 处理:确认 broll_fetch_results.json 已生成且路径正确;若渲染阶段使用扁平映射,请在生成 render_props.json 时将该JSON转换为 assets.broll 的键值对。
- 参考路径:[assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- 参考路径:[frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
章节来源
- [backend/media_fetcher.py](file://backend/media_fetcher.py#L18-L24)
- [assets/1_processed/broll_fetch_results.json](file://assets/1_processed/broll_fetch_results.json#L1-L77)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L107-L112)
## 结论
当前 B-Roll 素材获取功能处于占位实现阶段,核心流程已在 main.py 中串联,MediaFetcher 类已预留Pexels API集成、翻译与下载的扩展点。通过明确的筛选标准与本地缓存策略,可有效提升素材质量与系统性能。broll_fetch_results.json 作为中间产物,为渲染阶段提供了稳定的素材索引;未来建议在渲染阶段直接消费该JSON或转换为扁平映射,以契合前端契约。
## 附录
- 扩展方案:替换其他素材源
- Pixabay:提供免费与付费素材,支持相似的搜索与过滤能力;需适配其API与许可条款。
- Coverr:专注免费短视频,适合短时长B-Roll;注意其许可与可用性。
- 自建素材库:将已有素材归档到 assets/1_processed/broll/,并在 broll_fetch_results.json 中维护索引,便于统一管理与渲染引用。
- 开发建议
- 在 media_fetcher.py 中逐步实现 _translate_keyword 与 _download_video。
- 在 main.py 中启用实际的 backend.extractor 与 backend.scripter,以提供真实脚本与关键词。
- 在渲染阶段完善对 broll_fetch_results.json 的转换逻辑,确保 assets.broll 符合前端契约。