16 KiB
16 KiB
视频数据提取
**本文引用的文件列表** - [main.py](file://main.py) - [PROJECT_README.md](file://PROJECT_README.md) - [backend/extractor.py](file://backend/extractor.py) - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py) - [backend/video_processor/utils.py](file://backend/video_processor/utils.py) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py) - [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py) - [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py) - [tests/test_video_processor.py](file://tests/test_video_processor.py) - [tests/test_video_cli.py](file://tests/test_video_cli.py) - [requirements.txt](file://requirements.txt)目录
简介
本文件围绕“视频数据提取”功能展开,目标是帮助用户理解如何利用 OpenAI Whisper API 从访谈视频中提取语音转录内容与关键时间戳,并将其整合进视频生成流水线。文档重点覆盖:
- VideoExtractor 类的架构设计与职责边界
- 与 FFmpeg 的音频提取集成
- 调用 Whisper 进行语音识别并生成包含时间点、文本内容与关键词的时间戳序列
- 在主流程 main.py 中的 extract_video 方法如何承接该能力,形成完整的数据输出结构(如 transcription 与 timestamps)
- 面向新手的处理流程图与面向资深开发者的优化建议(音频预处理策略、关键词提取逻辑、视频片段分割建议、与 B-Roll 匹配机制)
项目结构
该项目采用“Python 后端 + Node.js 前端”的混合架构,视频数据提取位于 Python 后端模块中,主要涉及以下目录与文件:
- backend/extractor.py:PDF 与视频提取器的接口定义(当前视频提取仍为占位)
- backend/video_processor/:视频分析策略与工具集
- init.py:统一入口 analyze_video,按策略分发
- utils.py:FFmpeg 封装(音频提取、时长查询、视频切片)
- schemas.py:标准化的数据结构(VideoSegment、KeyMoment、VideoAnalysisResult)
- strategy_audio.py:音频优先策略(FFmpeg → Whisper → 文本分析)
- strategy_direct.py:直接视频分析策略(占位,后续扩展)
- tests/:独立测试脚本与单元测试
- main.py:视频生成流水线入口,负责调用 extract_video 并产出渲染所需数据
graph TB
A["main.py<br/>视频生成流水线"] --> B["backend/extractor.py<br/>PDF/视频提取器接口"]
A --> C["backend/video_processor/__init__.py<br/>analyze_video 入口"]
C --> D["backend/video_processor/strategy_audio.py<br/>音频优先策略"]
D --> E["backend/video_processor/utils.py<br/>FFmpeg 工具集"]
D --> F["backend/video_processor/schemas.py<br/>数据结构"]
C --> G["backend/video_processor/strategy_direct.py<br/>直接视频策略占位"]
图表来源
- main.py
- backend/extractor.py
- backend/video_processor/init.py
- backend/video_processor/strategy_audio.py
- backend/video_processor/utils.py
- backend/video_processor/schemas.py
- backend/video_processor/strategy_direct.py
章节来源
核心组件
- VideoExtractor(占位实现):定义了视频提取器的接口与返回结构,包含 transcription、timestamps、segments 字段,用于承载 Whisper 输出与后续脚本/字幕生成。
- AudioFirstStrategy:音频优先策略的核心实现,串联 FFmpeg 提取音频、Whisper 识别、文本段落化与关键时刻识别。
- FFmpeg 工具集:提供音频提取、视频切片、时长查询等基础能力。
- 数据结构:VideoSegment、KeyMoment、VideoAnalysisResult 统一输出格式,便于与前端渲染层对接。
章节来源
- backend/extractor.py
- backend/video_processor/strategy_audio.py
- backend/video_processor/utils.py
- backend/video_processor/schemas.py
架构总览
视频数据提取在整体流水线中的位置如下:
- 输入:PDF 报告与可选的面试视频
- 处理:若提供视频,则调用 extract_video,内部使用 analyze_video(音频优先策略),经 FFmpeg 提取音频后调用 Whisper 获取带时间戳的转录,再转换为 VideoAnalysisResult
- 输出:render_props.json 中的 script 与 assets 字段,供前端渲染
sequenceDiagram
participant U as "用户"
participant M as "main.py<br/>VideoGeneratorPipeline"
participant E as "backend/extractor.py<br/>VideoExtractor"
participant V as "backend/video_processor/__init__.py<br/>analyze_video"
participant S as "strategy_audio.py<br/>AudioFirstStrategy"
participant U2 as "utils.py<br/>FFmpeg 工具"
participant W as "OpenAI Whisper API"
U->>M : 运行命令可带 --video
M->>M : extract_video()mock
M->>E : 调用 extract_video_data(video_path)
E->>V : analyze_video(video_path, strategy="audio")
V->>S : 初始化 AudioFirstStrategy(config)
S->>U2 : extract_audio(video_path)
U2-->>S : 返回音频路径
S->>W : 调用 Whisperverbose_json,segment 级时间戳
W-->>S : 返回转录与时间戳
S->>S : _create_segments() 与 _identify_key_moments()
S-->>V : 返回 VideoAnalysisResult
V-->>E : 返回结果
E-->>M : 返回 transcription 与 timestampsmock
M-->>U : 产出渲染所需数据
图表来源
- main.py
- backend/extractor.py
- backend/video_processor/init.py
- backend/video_processor/strategy_audio.py
- backend/video_processor/utils.py
详细组件分析
VideoExtractor 类与接口
- 职责:定义视频提取器的统一接口,返回包含 transcription、timestamps、segments 的结构,便于后续脚本生成与字幕同步。
- 认证:通过 OPENAI_API_KEY 进行 Whisper 调用认证。
- 当前状态:占位实现,抛出未实现异常;实际功能由 analyze_video(音频优先策略)完成。
classDiagram
class VideoExtractor {
+api_key : str
+extract(video_path) Dict
}
class PDFExtractor {
+api_key : str
+extract(pdf_path) Dict
}
class VideoAnalysisResult {
+source_video : str
+duration : float
+strategy : str
+segments : VideoSegment[]
+key_moments : KeyMoment[]
+metadata : dict
+to_dict() dict
+get_high_importance_segments() VideoSegment[]
+get_quotes() KeyMoment[]
}
class VideoSegment {
+start_time : float
+end_time : float
+description : str
+transcript : str
+importance : str
+tags : str[]
+speaker : str
+duration() float
+to_dict() dict
}
class KeyMoment {
+timestamp : float
+type : str
+content : str
+context : str
+to_dict() dict
}
VideoExtractor --> VideoAnalysisResult : "生成"
VideoAnalysisResult --> VideoSegment : "包含"
VideoAnalysisResult --> KeyMoment : "包含"
图表来源
章节来源
音频优先策略(AudioFirstStrategy)
- 流程要点:
- 使用 FFmpeg 提取音频(单声道、16kHz、PCM 编码)
- 调用 Whisper API,使用 verbose_json 与 segment 级时间戳
- 将 Whisper 段落映射为 VideoSegment
- 简单启发式识别关键时刻(如首段作为 quote)
- 返回 VideoAnalysisResult,包含时长、策略、段落与关键时刻
- 关键配置:
- language:语言代码(默认日语)
- model:Whisper 模型(默认 whisper-1)
- prompt:可选提示词(预留)
flowchart TD
Start(["开始:analyze(video_path)"]) --> Extract["提取音频<br/>extract_audio(video_path)"]
Extract --> Transcribe["Whisper 转录<br/>verbose_json + segment 时间戳"]
Transcribe --> Segments["构建 VideoSegment 列表"]
Segments --> KeyMoments["识别关键时刻启发式"]
KeyMoments --> Duration["获取视频时长<br/>get_video_duration(video_path)"]
Duration --> Cleanup["清理临时音频文件"]
Cleanup --> Result["返回 VideoAnalysisResult"]
Result --> End(["结束"])
图表来源
- backend/video_processor/strategy_audio.py
- backend/video_processor/utils.py
- backend/video_processor/schemas.py
章节来源
- backend/video_processor/strategy_audio.py
- backend/video_processor/utils.py
- backend/video_processor/schemas.py
FFmpeg 工具集
- extract_audio:将视频解复用为 WAV 音频,单声道、16kHz、PCM 编码,适配 Whisper 推荐采样率
- get_video_duration:使用 ffprobe 获取视频时长
- slice_video:基于流复制的快速切片(不重编码),适合生成 B-Roll 片段
- check_ffmpeg_installed:检测 FFmpeg 与 ffprobe 是否可用
flowchart TD
A["输入:video_path"] --> B{"是否指定 output_path?"}
B --> |否| C["生成默认输出路径同名.wav"]
B --> |是| D["使用指定输出路径"]
C --> E["执行 ffmpeg 命令<br/>提取音频单声道、16kHz、PCM"]
D --> E
E --> F{"执行成功?"}
F --> |是| G["返回音频路径"]
F --> |否| H["抛出运行时错误"]
图表来源
章节来源
数据结构与输出约定
- VideoSegment:包含起止时间、描述、转录、重要性、标签、说话人等字段,并提供 to_dict 序列化
- KeyMoment:包含时间戳、类型(quote/chart/emotion/action)、内容与上下文
- VideoAnalysisResult:包含源视频、总时长、策略、段落列表、关键时刻列表与元数据,并提供过滤方法
章节来源
在主流程中的作用与数据输出
- main.py 的 extract_video 方法在流水线第二步被调用,当前为 mock 实现,返回包含 transcription 与 timestamps 的结构,供后续脚本生成与字幕同步使用
- 正式实现应调用 backend.video_processor.analyze_video,返回 VideoAnalysisResult,其中 segments 可映射为 script 的 narration 片段,key_moments 可用于生成字幕与 B-Roll 匹配
章节来源
依赖关系分析
- 外部依赖:
- FFmpeg/ffprobe:用于音频提取与时长查询
- OpenAI Whisper:用于语音识别与时间戳提取
- requests:用于网络请求(如 B-Roll 下载)
- 内部模块耦合:
- strategy_audio 依赖 utils(FFmpeg)与 schemas(数据结构)
- init.py 作为统一入口,按策略导入具体实现
- tests 提供独立 CLI 与单元测试,验证依赖安装与策略执行
graph TB
subgraph "外部依赖"
FF["FFmpeg/ffprobe"]
WH["OpenAI Whisper"]
REQ["requests"]
end
subgraph "Python 模块"
U["utils.py"]
SC["schemas.py"]
SA["strategy_audio.py"]
SD["strategy_direct.py"]
INI["__init__.py"]
end
SA --> U
SA --> SC
SA --> WH
INI --> SA
INI --> SD
REQ -.-> SD
图表来源
- requirements.txt
- backend/video_processor/utils.py
- backend/video_processor/strategy_audio.py
- backend/video_processor/init.py
章节来源
性能考量
- 音频采样率与编码:Whisper 推荐 16kHz 单声道 PCM,有助于降低令牌消耗与提升识别精度
- 流复制切片:slice_video 使用流复制避免重编码,显著减少 CPU 开销
- 分段策略:对于长视频,可考虑按 Whisper 段落或主题变化进行切片,便于并行处理与缓存
- API 调用成本:音频优先策略相比直接视频分析更经济,适合对话密集型视频
故障排查指南
- API 密钥问题
- OPENAI_API_KEY 未设置:AudioFirstStrategy 初始化会抛出异常
- GEMINI_API_KEY 未设置:PDFExtractor 初始化会抛出异常
- 依赖缺失
- FFmpeg/ffprobe 未安装:check_ffmpeg_installed 返回 False,需先安装
- OpenAI 库未安装:测试 CLI 会提示安装
- 视频处理失败
- FFmpeg 执行失败:extract_audio/slice_video 会抛出运行时错误,检查输入路径与权限
- Whisper 请求失败:检查网络与 API 配额
章节来源
- backend/video_processor/strategy_audio.py
- backend/extractor.py
- tests/test_video_cli.py
- backend/video_processor/utils.py
结论
视频数据提取功能以“音频优先策略”为核心,通过 FFmpeg 提取高质量音频并交由 Whisper 生成精确的时间戳转录,随后将结果标准化为 VideoAnalysisResult,为脚本生成与字幕同步提供可靠数据基础。尽管当前 main.py 中的 extract_video 仍为 mock,但 backend.video_processor 已具备完整的实现骨架,可无缝接入真实流水线。
附录
新手处理流程图(概念示意)
flowchart TD
A["输入:面试视频"] --> B["提取音频FFmpeg"]
B --> C["Whisper 转录含时间戳"]
C --> D["文本段落化VideoSegment"]
D --> E["关键信息提取KeyMoment"]
E --> F["生成 VideoAnalysisResult"]
F --> G["写入 render_props.json供前端渲染"]
高级实践建议
- 音频预处理
- 降噪与静音裁剪:在 extract_audio 之后增加降噪滤波,提升 Whisper 精度
- 多语言支持:根据视频语言动态切换 Whisper language 参数
- 关键词提取
- 基于主题词典与 TF-IDF 对 Whisper 段落进行关键词抽取,增强 timestamps 的可检索性
- 片段分割
- 依据 Whisper 段落边界与情感变化进行切片,便于并行处理与缓存
- B-Roll 匹配
- 将 KeyMoment 的内容与类型(quote/chart/emotion)映射到 Pexels 关键词,自动抓取匹配素材
可运行示例(路径指引)
- 独立测试视频分析
- 使用测试 CLI:python tests/test_video_cli.py --input sample.mp4 --strategy audio --language ja
- 输出:控制台打印或保存为 JSON 文件
- 单元测试验证
- pytest tests/test_video_processor.py -v
- 依赖检查
- python tests/test_video_cli.py --check-deps
章节来源