- 人工智能
- AI 应用
- 大模型
- 计算机视觉
- 语音
- 本地部署
- 视频处理
【免费下载链接】video-analyzer
Analyze videos using LLMs, Computer Vision and Automatic Speech Recognition
本文基于开源项目 video-analyzer 的主包文档展开,完整讲解其"关键帧提取 + 语音转写 → 视觉 LLM 逐帧分析 → 视频整体重建描述"的三阶段处理流水线,并覆盖安装步骤、全部命令行参数、三级级联配置体系、JSON 输出结构与基于 DSPy 的提示词自动调优流程。读完后可在本地或任意 OpenAI 兼容 API 上搭建一条开箱即用、完全可配置的视频分析管线。
项目定位与核心特性
video-analyzer 是一个结合视觉语言模型(如 Llama 3.2 11B Vision)与 OpenAI Whisper 的视频分析工具:从视频中抽取关键帧送入视觉模型获取画面细节,再把逐帧描述与(可选的)语音转写文本综合成一段完整的视频内容描述。
README 列出的核心特性如下:
- 💻 可完全本地运行,不依赖云服务或 API Key;
- ☁️ 也可接入任意 OpenAI API 兼容的 LLM 服务(OpenRouter、OpenAI 等)以获得速度与时扩展性;
- 🎬 基于帧差的关键帧智能提取;
- 🔊 使用 Whisper 完成高质量语音转写;
- 👁️ 通过 Ollama 与 Llama3.2 11B Vision 模型完成帧分析;
- 📝 输出自然语言形式的视频内容描述;
- 🔄 自动处理低质量音频;
- 📊 输出详细的 JSON 分析结果;
- ⚙️ 通过命令行参数或配置文件高度可配置。
依赖见 requirements.txt:opencv-python、numpy、torch、openai-whisper、faster-whisper、requests、Pillow、pydub等;setup.py 通过console_scripts入口注册了video-analyzer命令,指向 video_analyzer/cli.py 的main。
三阶段处理架构
README 将系统描述为三个阶段,以下逐阶段结合源码说明其实现细节。
阶段一:帧提取与音频处理
帧提取由 video_analyzer/frame.py 中的VideoProcessor.extract_keyframes实现,算法要点:
- 目标帧数计算:
target_frames = 视频时长(分钟) × frames.per_minute(内置默认配置为每分钟 60 帧),并受视频总帧数与max_frames约束,至少为 1; - 自适应采样:以
total_frames // (target_frames × 2)为步长扫描,采样密度高于目标以积累足够候选; - 帧差分析:将候选帧转灰度后用
cv2.absdiff求平均差异,超过类常量FRAME_DIFFERENCE_THRESHOLD = 10.0的进入候选集(与配置项frames.analysis_threshold的默认值 10.0 一致); - 最终选择:按差异分取 Top N,再按帧号重排恢复时间顺序,逐帧保存为
output/frames/frame_N.jpg。若指定了max_frames且候选更多,则在候选中均匀采样(例如 5 分钟视频取 5 帧约等于每分钟 1 帧,而不是取前 5 帧)。
音频处理由 video_analyzer/audio_processor.py 的AudioProcessor完成:
- 先用 FFmpeg 抽取音频为 16kHz、单声道、
pcm_s16le的 WAV 文件;视频无音轨时(FFmpeg 报 "Output file does not contain any stream")直接跳过转写;FFmpeg 失败时回退到 pydub; - 转写使用
faster-whisper,参数为beam_size=5、开启 VAD 过滤(min_silence_duration_ms=500)、启用词级时间戳; --language指定的语言会先对照内置语言白名单校验,非法代码自动回退到自动检测;无有效语音或转写异常时返回None,主流程会打印 "Could not generate reliable transcript. Proceeding with video analysis only." 并继续纯视觉分析——这正是 README 所说"自动处理低质量音频"的落地方式。
阶段二:逐帧分析
video_analyzer/analyzer.py 的VideoAnalyzer.analyze_frame对每个帧调用一次视觉模型:
- 提示模板为 frame_analysis.txt,通过替换
{PREVIOUS_FRAMES}占位符注入此前所有帧的分析文本,使模型在时间轴上保持上下文连续; - 用户通过
--prompt传入的问题经_format_user_prompt加前缀 "I want to know …" 后注入{prompt}占位符; - 提示末尾追加 "This is frame {N} captured at {T} seconds." 标明帧序号与时间戳;
- 帧图片经 LLMClient.encode_image 做 Base64 编码后随请求发送,
num_predict固定为 300,temperature取自配置。
模板本身是一套结构化的"帧笔记"指令:要求模型依次记录 Setting/Scene、Action/Movement、New Information、Continuity Points,并以 "Key continuation points" 列出供后续帧关注的 2–3 个元素,用现在时态、避免主观推断。
阶段三:视频重建
analyzer.py 的 reconstruct_video 将阶段二的产物综合为最终描述:
- 提示模板为 describe.txt,依次替换
{FRAME_NOTES}(全部帧笔记,按时间顺序、带帧号与时间戳)、{FIRST_FRAME}(第一帧分析文本)、{TRANSCRIPT}(语音转写全文)与{prompt}(用户问题); - 该次调用不附带图片,
num_predict为 1000; - 模板要求模型以首帧分析建立开场、按时间顺序推进叙事、纳入音频信息,并给出一份提交前自查清单(无矛盾、元素齐全、未看过视频的人也能读懂等)。
更完整的设计与修改指南见 docs/DESIGN.md。
项目结构
主包目录布局(README 目录项之一,对应仓库实际结构):
video-analyzer/ ├── video_analyzer/ # 主包 │ ├── cli.py # 命令行入口与三阶段编排 │ ├── config.py # 级联配置与客户端/模型解析 │ ├── frame.py # OpenCV 关键帧提取 │ ├── audio_processor.py # 音频抽取与 Whisper 转写 │ ├── analyzer.py # 逐帧分析与视频重建 │ ├── prompt.py # 提示词加载器 │ ├── clients/ # ollama.py / generic_openai_api.py / llm_client.py │ ├── config/default_config.json # 内置默认配置 │ └── prompts/frame_analysis/ # 默认提示模板(frame_analysis.txt / describe.txt) ├── video-analyzer-tune/ # DSPy 提示词自动调优子包 ├── video-analyzer-ui/ # Web UI 子包 ├── docs/ # USAGES / DESIGN / 示例输出 ├── setup.py └── requirements.txt三阶段的编排逻辑集中在 cli.py 的 main:按--start-stage判断依次执行 Stage 1(音频+帧提取)、Stage 2(逐帧分析)、Stage 3(视频重建),结果写入output/analysis.json,最后根据keep_frames决定是否调用cleanup_files清理frames/与audio.wav临时文件。
环境要求与安装
系统要求
- Python 3.11 或更高版本(setup.py 中
python_requires声明为>=3.8,以 README 的 3.11+ 为推荐前提); - FFmpeg(音频处理必需);
- 本地运行 LLM 时(使用 OpenRouter 等云服务时不需要):
- 至少 16GB 内存(推荐 32GB);
- GPU 显存至少 12GB,或 Apple M 系列芯片且内存至少 32GB。
安装步骤
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/vi/video-analyzer.git cd video-analyzer- 创建并激活虚拟环境:
python3 -m venv .venv source .venv/bin/activate # Windows 下为 .venv\Scripts\activate- 安装包:
pip install . # 常规安装 # 或 pip install -e . # 开发模式安装- 安装 FFmpeg:
# Ubuntu/Debian sudo apt-get update && sudo apt-get install -y ffmpeg # macOS brew install ffmpeg # Windows choco install ffmpegOllama 配置(本地视觉模型)
- 按 Ollama 官方说明安装 Ollama(
ollama.ai); - 拉取默认视觉模型:
ollama pull llama3.2-vision- 启动服务:
ollama serveOpenAI 兼容 API 配置(可选)
若希望改用 OpenRouter、OpenAI 等 OpenAI 兼容服务:
- 从服务提供方获取 API Key;
- 通过命令行配置:
# OpenRouter video-analyzer video.mp4 --client openai_api --api-key your-key --api-url https://openrouter.ai/api/v1 --model gpt-4o # OpenAI video-analyzer video.mp4 --client openai_api --api-key your-key --api-url https://api.openai.com/v1 --model gpt-4o或写入工作目录下的config/config.json:
{ "clients": { "default": "openai_api", "openai_api": { "api_key": "your-api-key", "api_url": "https://openrouter.ai/api/v1" } } }注意:README 提示在 OpenRouter 上为模型名追加:free可免费使用 llama 3.2 11b vision。
客户端的创建逻辑见 cli.py 的 create_client:clients.default为ollama时构造 OllamaClient(调用/api/generate),为openai_api时构造 GenericOpenAIAPIClient(调用{api_url}/chat/completions,内置 3 次重试、429 时读取Retry-After头等待)。配置缺失校验在 config.py 的 get_client:openai_api缺少api_key或api_url会抛出ValueError。
使用指南
完整的参数说明与更多用例见 docs/USAGES.md。
快速开始
# 本地分析(默认 Ollama) video-analyzer video.mp4 # 云端分析(OpenRouter) video-analyzer video.mp4 \ --client openai_api \ --api-key your-key \ --api-url https://openrouter.ai/api/v1 \ --model meta-llama/llama-3.2-11b-vision-instruct:free # 自定义提示词 + 更大 Whisper 模型 video-analyzer video.mp4 \ --prompt "What activities are happening in this video?" \ --whisper-model large全部命令行参数
| 参数 | 说明 | 默认值 | 示例 |
|---|---|---|---|
video_path | 输入视频文件路径 | (必填) | video.mp4 |
--config | 配置目录路径 | config/ | --config /path/to/config/ |
--output | 分析结果输出目录 | output/ | --output ./results/ |
--client | LLM 客户端(ollama 或 openai_api) | ollama | --client openai_api |
--ollama-url | Ollama 服务地址 | http://localhost:11434 | --ollama-url http://localhost:11434 |
--api-key | OpenAI 兼容服务的 API Key | 无 | --api-key sk-xxx... |
--api-url | OpenAI 兼容 API 地址 | 无 | --api-url https://openrouter.ai/api/v1 |
--model | 视觉模型名 | llama3.2-vision(Ollama) | --model gpt-4-vision-preview |
--duration | 处理的视频时长(秒) | 无(整段视频) | --duration 60 |
--keep-frames | 分析后保留提取的帧 | False | --keep-frames |
--whisper-model | Whisper 模型尺寸或本地模型路径 | medium | --whisper-model large |
--start-stage | 起始处理阶段(1–3) | 1 | --start-stage 2 |
--max-frames | 处理的最大帧数;指定后在候选帧中均匀采样,而非只取前 N 帧 | sys.maxsize | --max-frames 100 |
--log-level | 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL) | INFO | --log-level DEBUG |
--prompt | 关于视频的问题 | "" | --prompt "What activities are shown?" |
--language | 转写语言 | 由配置决定(内置默认en,不传则按配置自动检测) | --language es |
--device | Whisper 运行设备 | cpu | --device cuda |
--temperature | LLM 生成温度 | 0.2(内置默认配置为0.0) | --temperature 0.2 |
参数与配置的映射并非简单同名覆盖,config.py 的 update_from_args 实现了若干特化规则,值得注意:
--api-key单独出现(未显式--client)时会自动把默认客户端切换为openai_api;--model写入的是当前默认客户端的model字段,即它同时兼容 Ollama 模型名与 OpenRouter 模型名;--whisper-model/--language/--device写入audio子配置;--temperature写入clients.temperature;--start-stage、--max-frames属于纯命令行参数,不落配置。
处理阶段
--start-stage控制从哪个阶段开始,便于断点续跑:
- 帧与音频处理;
- 帧分析;
- 视频重建。
例如先跑完阶段一再中断,可用video-analyzer video.mp4 --start-stage 2 --max-frames 50 --keep-frames从帧分析阶段继续(前提是--keep-frames保留了帧文件)。
配置系统
README 说明工具采用级联配置:命令行参数优先级最高,其次是用户配置(工作目录下的config/config.json),最后是默认配置。从 config.py 的源码看,其具体语义是:若存在用户config.json则整体加载该文件(而非与内置默认逐项合并),找不到用户配置时才回退到内置的 default_config.json(先查--config目录,再回退到安装包内的副本);命令行参数随后覆盖对应字段。
内置默认配置 video_analyzer/config/default_config.json 全文如下(以仓库实际文件为准):
{ "clients": { "default": "ollama", "temperature": 0.0, "ollama": { "url": "http://localhost:11434", "model": "llama3.2-vision" }, "openai_api": { "api_key": "", "model": "meta-llama/llama-3.2-11b-vision-instruct", "api_url": "https://openrouter.ai/api/v1" } }, "prompt_dir": "prompts", "prompts": [ { "name": "Frame Analysis", "path": "frame_analysis/frame_analysis.txt" }, { "name": "Video Reconstruction", "path": "frame_analysis/describe.txt" } ], "output_dir": "output", "frames": { "per_minute": 60, "analysis_threshold": 10.0, "min_difference": 5.0, "max_count": 30, "start_stage": 1, "max_frames": 2147483647 }, "response_length": { "frame": 300, "reconstruction": 1000, "narrative": 500 }, "audio": { "whisper_model": "medium", "sample_rate": 16000, "channels": 1, "quality_threshold": 0.2, "chunk_length": 30, "language_confidence_threshold": 0.8, "language": "en", "device": "cpu" }, "keep_frames": false, "prompt": "" }各字段含义:
客户端设置(clients)
clients.default:默认 LLM 客户端(ollama/openai_api);clients.temperature:生成温度(0.0–1.0,越高越有创造性);clients.ollama.url/clients.ollama.model:Ollama 服务地址与视觉模型名;clients.openai_api.api_key/api_url/model:OpenAI 兼容服务的 Key、端点与模型名。
帧分析设置(frames)
per_minute:每分钟目标提取帧数,直接决定 extract_keyframes 的目标帧数;analysis_threshold:关键帧检测阈值,与frame.py中FRAME_DIFFERENCE_THRESHOLD(10.0)一致,从源码结构看当前实现直接使用该类常量;min_difference/max_count/max_frames:帧间最小差异、提取上限与命令行--max-frames对应的默认上限(2147483647,即不限制)。
响应长度设置(response_length)
frame(300)/reconstruction(1000):分别对应 analyzer.py 中逐帧分析与视频重建两次调用的num_predict取值;narrative:为增强叙述预留的长度配置,当前主流程的两阶段提示中未消费该字段。
音频处理设置(audio)
whisper_model:Whisper 模型尺寸(tiny/base/small/medium/large)或本地模型路径,默认medium;sample_rate(16000 Hz)/channels(1):与audio_processor.py中 FFmpeg 抽取参数一致;language:强制语言代码,null表示自动检测,内置默认值为"en";device:Whisper 运行设备(cpu/cuda);quality_threshold/language_confidence_threshold/chunk_length:转写质量与语言置信度相关阈值配置。
通用设置
prompt_dir:自定义提示词目录(配合prompts列表使用);prompts:提示文件清单,Frame Analysis与Video Reconstruction分别按索引 0/1 被 analyzer.py 加载;output_dir:结果输出目录;keep_frames:是否保留帧图片;prompt:自定义分析问题。
提示:docs/USAGES.md 中的示例配置文件为讲解用途,个别数值(如frames.per_minute: 10、response_length一组值)与仓库内置默认值不同,实操时以上面的default_config.json实际内容为准。
输出
分析完成后,工具在output_dir(默认output/)生成analysis.json,包含四部分:
- metadata:分析元数据——所用客户端、模型、Whisper 模型、
frames_per_minute、已处理时长、提取/处理的帧数、起始阶段、音频语言、转写是否成功; - transcript:语音转写(如有),含全文
text与带词级时间戳和概率的segments; - frame_analyses:逐帧分析结果(每帧的模型响应及 Ollama 返回的统计信息);
- video_description:最终视频描述。
README 给出的示例输出(节选):
The video begins with a person with long blonde hair, wearing a pink t-shirt and yellow shorts, standing in front of a black plastic tub or container on wheels. The ground appears to be covered in wood chips. As the video progresses, the person remains facing away from the camera, looking down at something inside the tub. ……
完整样例见 docs/sample_analysis.json。若不想保留中间文件,默认行为会自动删除frames/目录与audio.wav;加--keep-frames可保留,便于复查帧提取质量或供调优子包使用(见下文)。
提示词模板与提示词调优
双模板机制
主包默认使用两个提示文件(由default_config.json的prompts列表声明):
- frame_analysis.txt:每帧调用一次,占位符为
{PREVIOUS_FRAMES}(此前帧笔记)与{prompt}(用户问题); - describe.txt:末尾调用一次,占位符为
{FRAME_NOTES}、{FIRST_FRAME}、{TRANSCRIPT}、{prompt}。
video_analyzer/prompt.py 的PromptLoader按三级顺序查找提示文件:安装包资源(pkg_resources)→ 包目录(开发模式)→ 用户prompt_dir目录(支持绝对/相对路径)。替换全部为纯字符串替换,因此任何保留占位符的自定义模板都可以直接替换使用。仓库根目录的 test_prompt_loading.py 验证了"包内默认提示 + 临时目录自定义提示"两条加载路径。
用 video-analyzer-tune 自动优化提示词
仓库内的子包 video-analyzer-tune 提供基于 DSPy MIPROv2 的提示词优化器:它把上述两个提示包进一条与主包逻辑一致的 DSPy 流水线,用 LLM-as-judge 对候选提示打分(1–5 分,最终描述质量按--description-weight加权),自动找到更优的指令文本,并写成新的.txt文件——主包不受任何影响,只需在配置中指向新文件。
工作流程(摘自 video-analyzer-tune/README.md):
- 对若干代表性视频运行分析并保留帧:
pip install video-analyzer-tune video-analyzer my_video.mp4 --keep-frames- 编辑
output/analysis.json:video_description.response必须改为"理想的最终描述";建议同时逐条编辑frame_analyses[i].response为"理想的帧笔记",两级都给出样例信号更强; - 创建
training_data.json,每个视频一条记录:
{ "examples": [ { "output_dir": "output/video1" }, { "output_dir": "output/video2" } ] }- 运行调优器:
video-analyzer-tune --training-data training_data.json --output-dir tuned_prompts/- 将打印出的配置片段贴入
config/config.json,之后video-analyzer即自动使用调优后的提示:
"prompt_dir": "tuned_prompts", "prompts": [ {"name": "Frame Analysis", "path": "frame_analysis_tuned.txt"}, {"name": "Video Reconstruction", "path": "describe_tuned.txt"} ]调优器常用 CLI 参数:
| 参数 | 默认 | 说明 |
|---|---|---|
--training-data | 必填 | training_data.json 路径 |
--output-dir | tuned_prompts | 调优提示输出目录 |
--client | ollama | ollama或openai_api |
--model | llama3.2-vision | 优化运行使用的视觉模型 |
--num-candidates | 10 | 每个模块生成的提示变体数(5–20) |
--num-trials | 20 | 优化试验次数(10–50) |
--description-weight | 0.7 | 最终描述质量在总分中的权重(0.0–1.0),其余权重给帧分析质量 |
--log-level | INFO | 日志级别 |
官方建议:使用 3–5 个风格多样的视频样例、同时编辑帧笔记与最终描述、调优与推理使用同一模型。
卸载、协议与贡献
卸载:
pip uninstall video-analyzer项目采用 Apache License(见 LICENSE)。贡献流程(审阅设计、通过 GitHub Discussions 提议变更、提交 PR)见 docs/CONTRIBUTING.md。
小结
video-analyzer 的价值在于把"视频理解"拆成了三条可独立配置、可断点续跑的管线:OpenCV 帧差关键帧提取、faster-whisper 语音转写、视觉 LLM 的双提示词分析-重建。默认全本地(Ollama + llama3.2-vision + Whisper medium)即可运行;需要规模或更强模型时切换--client openai_api一行即可。所有行为——帧密度、Whisper 模型与设备、温度、输出目录、提示词——都通过"命令行 > 用户配置 > 内置默认"的级联体系收敛,配合video-analyzer-tune还可以把提示词针对自有内容自动化调优,构成一条从部署到定制的完整闭环。
- 人工智能
- AI 应用
- 大模型
- 计算机视觉
- 语音
- 本地部署
- 视频处理
【免费下载链接】video-analyzer
Analyze videos using LLMs, Computer Vision and Automatic Speech Recognition
相关推荐
video-analyzer 设计深解:关键帧提取、Whisper 转写与视觉 LLM 视频重建的完整技术管线
video analyzer 设计深解:关键帧提取、Whisper 转写与视觉 LLM 视频重建的完整技术管线 本文基于仓库内的设计文档 docs/DESIGN
人工智能AI 应用大模型计算机视觉语音本地部署视频处理用 Llama 3.2 Vision 构建 100% 本地运行的 OCR 应用:Ollama 模型服务与 Streamlit 界面实战
用 Llama 3.2 Vision 构建 100% 本地运行的 OCR 应用:Ollama 模型服务与 Streamlit 界面实战 本指南围绕开源仓库 ai
示例工程Daft 音频转写实践:用 Whisper 构建列式数据与本地文件两条批量转写流水线
Daft 音频转写实践:用 Whisper 构建列式数据与本地文件两条批量转写流水线 本文基于 Daft 官方示例文档 docs/examples/audio
大数据数据分析数据工程AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考