mcpField
V
video-frames

video-frames

github.com/mugnimaestra创意与媒体14169 次安装32 周前更新
代码仓库

关于 video-frames

Video Frames 是一项从视频提取 JPEG 帧供大模型视觉分析的技能。它支持按固定帧率、场景变化或目标帧数选帧,并提供质量预设和适配模型的尺寸调整。

主要功能

  1. 01按帧率、场景变化或目标数量提取帧
  2. 02选择图像质量与处理预设
  3. 03按指定视觉模型调整帧尺寸
  4. 04为文字处理应用灰度、增强对比度和锐化
  5. 05叠加源文件名与时间戳
  6. 06在 JSON 输出中估算图像 Token 用量

适用场景

  1. 01在帧数限制内抽取长视频画面
  2. 02按演示文稿的场景变化提取画面
  3. 03读取屏幕录制或文档视频中的文字
  4. 04为指定模型的图像输入准备视频帧

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mugnimaestra/video-frames-skill --skill video-frames

安装后在 Claude Code 中输入/video-frames确认已加载。

附带文件references/llm-image-specs.mdscripts/extract_frames.py

详细介绍

视频帧

使用 ffmpeg 从视频文件中提取帧,并生成针对大模型视觉分析优化的 JPEG 图像。支持多种帧选择策略(固定 FPS、场景检测、目标帧数)、质量预设、针对模型优化尺寸,以及 OCR 增强。

先决条件

必须安装 ffmpeg 和 ffprobe,并将其添加到 PATH 中:

brew install ffmpeg  # macOS

工作流

  1. 接收用户提供的视频文件路径
  2. 运行 scripts/extract_frames.py 提取 JPEG 帧
  3. 解析 JSON 输出,获取帧路径、分辨率和令牌估算值
  4. 将提取的帧作为图像附件读取并进行分析
  5. 回答用户关于视频内容的问题
  6. 完成后清理临时目录

快速入门

最简单的调用方式——以均衡质量每秒提取 1 帧:

python3 scripts/extract_frames.py video.mp4

大多数情况下,使用 --max-frames 让脚本自动计算 FPS:

python3 scripts/extract_frames.py video.mp4 --max-frames 30

与手动设置 --fps 相比,更推荐这种方式,因为它能适应任意视频时长,并使帧数保持可预测。

预设

四种质量预设用于控制分辨率、JPEG 质量和图像处理:

预设最大尺寸质量附加处理适用场景
efficient768px5--批量帧、长视频
balanced1024px3--常规分析(默认)
detailed1568px2--精细细节、小物体
ocr1568px1灰度 + 高对比度 + 锐化文本/文档提取
# Long video, keep costs low
python3 scripts/extract_frames.py long_video.mp4 --max-frames 20 --preset efficient

# Need to read text in a screencast
python3 scripts/extract_frames.py screencast.mp4 --max-frames 40 --preset ocr

质量(1 = 最佳,31 = 最差)和最大尺寸可分别覆盖:

python3 scripts/extract_frames.py video.mp4 --preset balanced --quality 1 --max-dimension 1568

场景变化检测

不按固定频率提取帧,而是检测视觉场景变化,并为每个场景提取一帧。这适用于具有明显分段的视频(演示文稿、剪辑视频、教程)。

python3 scripts/extract_frames.py video.mp4 --scene-threshold 0.3
  • --scene-threshold(浮点数,0.0-1.0):灵敏度。数值越低,灵敏度越高,可检测较小的变化。建议从 0.3 开始(使用此标志时的默认值)。
  • --min-scene-interval(浮点数,默认值:1.0):检测到的场景之间的最小间隔秒数。可避免快速剪切时连续触发检测。

注意: --fps 和 --scene-threshold 不能同时使用。--max-frames 只能用于 --fps 模式,不能用于场景检测。

# Presentation with clear slide transitions
python3 scripts/extract_frames.py presentation.mp4 --scene-threshold 0.2

# Action footage -- less sensitive, min 2s apart
python3 scripts/extract_frames.py action.mp4 --scene-threshold 0.5 --min-scene-interval 2.0

针对模型优化

使用 --target-model 将帧调整为与特定模型的图块边界对齐的尺寸,以尽量减少浪费的令牌:

模型最大尺寸原因
claude1568px自动调整尺寸前的最大原生分辨率
openai768px与 512px 图块网格对齐(短边为 768)
gemini768px与 768px 图块边界对齐
universal768px适用于所有模型的理想尺寸(默认)
# Optimized for Claude -- maximum detail
python3 scripts/extract_frames.py video.mp4 --max-frames 30 --target-model claude

# Optimized for GPT-4o -- efficient tile packing
python3 scripts/extract_frames.py video.mp4 --max-frames 30 --target-model openai

除非明确提供 --max-dimension,否则 --target-model 会设置最大尺寸(CLI 覆盖优先)。

有关各模型的详细令牌公式、图块计算和最佳尺寸表,请参阅 references/llm-image-specs.md。

OCR 和灰度模式

适用于包含文本的视频(屏幕录制、演示文稿、文档、终端录制):

# Full OCR pipeline via preset
python3 scripts/extract_frames.py screencast.mp4 --preset ocr --max-frames 40

# Manual OCR flags (can combine with any preset)
python3 scripts/extract_frames.py video.mp4 --grayscale --high-contrast
  • --grayscale:将帧转换为灰度。文件大小可减少约 60%,且不会降低 OCR 准确率。
  • --high-contrast:应用 contrast=1.3, brightness=0.05,提升文本与背景的区分度。
  • ocr 预设会启用这两个标志,并且在 1568px、质量 1 下应用反遮罩锐化(最佳 JPEG)。

高级选项

FPS 选择指南

直接使用 --fps 而非 --max-frames 时:

视频时长建议 FPS原因
< 30s2-5短片段,捕捉细节
30s - 5min1在覆盖范围与帧数之间取得良好平衡
5min - 30min0.5避免帧数过多
> 30min0.1 - 0.2仅采样关键时刻

为优化大模型上下文使用,将总帧数控制在约 50 帧以内。公式:duration_seconds * fps = frame_count。

优先使用 --max-frames,而不是手动设置 FPS——它会自动计算合适的帧率,并将其限制在 0.05-30.0 FPS。

时间戳叠加
python3 scripts/extract_frames.py video.mp4 --timestamps --max-frames 30

在每帧右下角叠加源文件名和 hh:mm:ss 时间戳(半透明黑色方框上的白色文字)。当用户需要引用视频中的特定时刻时使用。

CLI 选项完整参考
选项类型默认值描述
video_pathpos.(必填)视频文件路径
--fpsfloat1.0每秒帧数(不能与 --scene-threshold 同时使用)
--scene-thresholdfloat--场景变化灵敏度 0.0-1.0(不能与 --fps 同时使用)
--min-scene-intervalfloat1.0场景变化帧之间的最小秒数
--max-framesint--自动计算 FPS,以生成约 N 帧
--presetchoicebalancedefficient / balanced / detailed / ocr
--max-dimensionint--覆盖最大像素尺寸(最长边)
--qualityint--JPEG 质量 1-31(1=最佳,31=最差)
--target-modelchoice--claude / openai / gemini / universal
--grayscaleflagoff转换为灰度图
--high-contrastflagoff增强对比度,提高文字可读性
--timestampsflagoff在帧上叠加文件名和时间戳
--output-dirstringtemp dir提取帧的输出目录

输出 JSON 结构

脚本会将以下结构的 JSON 打印到 stdout:

{
  "output_dir": "/tmp/video_frames_abc123/",
  "frames": ["/tmp/video_frames_abc123/frame_00001.jpg", "..."],
  "preset": "balanced",
  "resolution": { "width": 1024, "height": 576 },
  "token_estimate": {
    "frame_count": 30,
    "per_frame": {
      "claude": 787,
      "openai_high": 765,
      "openai_low": 85,
      "openai_patch": 934,
      "gemini": 258
    },
    "total": {
      "claude": 23610,
      "openai_high": 22950,
      "openai_low": 2550,
      "openai_patch": 28020,
      "gemini": 7740
    }
  },
  "summary": {
    "video_duration_seconds": 120.5,
    "extraction_method": "max_frames",
    "scene_changes_detected": null,
    "frames_extracted": 30,
    "estimated_total_tokens": {
      "claude": 23610,
      "openai_high": 22950,
      "openai_low": 2550,
      "openai_patch": 28020,
      "gemini": 7740
    }
  }
}

将帧附加到提示词之前,使用 token_estimate.total 确认这组帧符合模型上下文限制。

注意: openai_high 和 openai_low 用于旧版模型(GPT-4o、GPT-4.1)。openai_patch 用于较新的模型(gpt-5.4+、gpt-5-mini、o4-mini)。详情请参阅 references/llm-image-specs.md。

发生错误时,会将包含 "error" 键的 JSON 打印到 stderr,并且脚本以代码 1 退出。

提取后

  1. 解析 JSON 输出,从 frames 获取帧路径列表
  2. 检查 token_estimate.total,确保这些帧符合上下文限制
  3. 使用 Read 工具读取每张帧图像(它们是 JPEG 文件)
  4. 分析这些帧,以回答用户的问题
  5. 清理:完成后,如果输出目录是临时目录,则将其删除

评论

支持 Markdown