# B-Roll素材获取 **本文引用的文件** - [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) ## 目录 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
主流程编排"] --> B["backend/media_fetcher.py
B-Roll抓取器"] A --> C["assets/1_processed/broll_fetch_results.json
抓取结果索引"] A --> D["frontend/src/render-props-types.ts
渲染属性契约"] B --> E["Pexels API"] B --> F["本地缓存目录
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 "命令行入口
main.py" participant Gen as "脚本生成器
backend/scripter.py" participant MF as "B-Roll抓取器
backend/media_fetcher.py" participant PEX as "Pexels API" participant FS as "本地存储
assets/1_processed/broll/" participant RP as "渲染属性
render_props.json" participant FE as "前端渲染
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,即“关键词 -> 视频路径”。 ```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 符合前端契约。