关于 video-frames
video-frames 是用于从视频文件提取帧并制作视觉预览的技能,支持按时间戳或索引提取、定时批量处理、联系表和 GIF,还可报告元数据与进度,并验证输入及限制处理规模。
主要功能
- 01按时间戳或索引提取帧
- 02按间隔批量提取
- 03制作缩略图网格和 GIF
- 04报告视频元数据与进度
- 05验证输入并执行限制
适用场景
- 01截取指定时间戳的画面
- 02制作故事板联系表
- 03创建短动画视频预览
- 04查看视频尺寸和时长
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ winsorllc/ upgraded-carnival --skill video-frames安装后在 Claude Code 中输入/video-frames确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
frame.shgif.shthumbnails.shvideo-frames.js详细介绍
视频帧技能
生产级视频帧提取,具备全面的质量控制、进度跟踪和安全限制。
适用场景
✅ 在以下情况下使用此技能:
- 在指定时间戳提取视频中的特定帧
- 创建缩略图网格/联系表,以预览视频内容
- 从视频片段生成动画 GIF
- 按间隔批量提取帧(例如,每隔 N 秒)
- 创建视频预览或故事板
- 需要按索引精确访问像素级的帧
- 以特定质量级别提取帧
❌ 在以下情况下不要使用此技能:
- 简单格式转换 → 使用 ffmpeg-tools
- 视频编辑(特效)→ 使用视频编辑器
- 实时帧捕获 → 使用流媒体工具
- 从摄像头捕获视频 → 使用 camsnap
- 图像生成 → 使用 image-gen
前提条件
# Install FFmpeg
brew install ffmpeg # macOS
sudo apt install ffmpeg # Ubuntu/Debian
# Optional: Install ImageMagick for better grid generation
brew install imagemagick # macOS
sudo apt install imagemagick # Ubuntu
# Verify installation
ffmpeg -version
ffprobe -version
命令
1. 提取单帧
在指定时间或按帧索引提取单帧。
# Extract frame at timestamp
{baseDir}/video-frames.js frame video.mp4 --time 30 --out frame.jpg
{baseDir}/video-frames.js frame video.mp4 --time 00:02:30 --out frame.jpg
{baseDir}/video-frames.js frame video.mp4 --time 150.5 --out frame.jpg
# Extract by frame index
{baseDir}/video-frames.js frame video.mp4 --index 0 --out first-frame.jpg
{baseDir}/video-frames.js frame video.mp4 --index 1000 --out frame-1000.jpg
# With quality settings
{baseDir}/video-frames.js frame video.mp4 --time 30 --format png --out high-quality.png
{baseDir}/video-frames.js frame video.mp4 --time 30 --quality 1 --out best-quality.jpg
{baseDir}/video-frames.js frame video.mp4 --time 30 --format jpg --quality 2
时间格式:
| 格式 | 示例 | 说明 |
|---|---|---|
| 秒 | 30 | 简单的秒数 |
| MM:SS | 2:30 | 分钟:秒 |
| HH:MM:SS | 00:02:30 | 完整时间码 |
| 小数 | 90.5 | 毫秒精度 |
质量设置(JPEG):
| 值 | 质量 | 文件大小 | 使用场景 |
|---|---|---|---|
1 | 最佳 | 大 | 存档、保留质量 |
2-3 | 高 | 中 | 默认设置,平衡良好 |
5 | 中 | 小 | Web、快速预览 |
10+ | 低 | 很小 | 草稿、缩略图 |
支持的格式:
jpg/jpeg- 针对 Web 优化,支持压缩png- 无损、支持透明度、质量最佳bmp- 未压缩原始格式tiff- 专业格式webp- 新一代 Web 格式
2. 提取多帧
按固定间隔批量提取帧。
# Extract 1 frame per second
{baseDir}/video-frames.js frames video.mp4 --fps 1
# Extract specific segment
{baseDir}/video-frames.js frames video.mp4 --fps 1 --start 00:01:00 --duration 60
{baseDir}/video-frames.js frames video.mp4 --fps 5 --start 30 --duration 120
# Higher quality extraction
{baseDir}/video-frames.js frames video.mp4 --fps 1 --quality 1 --prefix keyframe
# Resize during extraction
{baseDir}/video-frames.js frames video.mp4 --fps 1 --width 1920 --quality 1
帧率选项:
| 帧率 | 说明 | 使用场景 |
|---|---|---|
--fps 1 | 每秒 1 帧 | 时间线提取 |
--fps 5 | 每秒 5 帧 | 详细分析 |
--fps 0.1 | 每 10 秒 1 帧 | 内容概览、故事板 |
--fps 0.5 | 每 2 秒 1 帧 | 中等细节 |
输出:
/tmp/frames_1234567890/
├── frame_00001.jpg
├── frame_00002.jpg
├── frame_00003.jpg
└── ...
3. 生成缩略图网格(联系表)
创建缩略图网格,以预览视频内容。
# Basic grid
{baseDir}/video-frames.js grid video.mp4 --output grid.jpg
# Custom size and layout
{baseDir}/video-frames.js grid video.mp4 --count 16 --columns 4 --width 480 --out grid.jpg
# Compact preview
{baseDir}/video-frames.js grid video.mp4 --count 20 --columns 5 --width 320 --out overview.jpg
# High resolution grid
{baseDir}/video-frames.js grid video.mp4 --count 9 --columns 3 --width 640 --format png --out detailed.png
网格布局示例:
| 数量 | 列 | 行 | 适用场景 |
|---|---|---|---|
| 4 | 2 | 2 | 快速预览 |
| 9 | 3 | 3 | 标准概览 |
| 12 | 4 | 3 | 详细时间线 |
| 16 | 4 | 4 | 完整故事板 |
| 20 | 5 | 4 | 长视频 |
输出格式:
+---+---+---+---+
| 1 | 2 | 3 | 4 | <- 5 seconds into video
+---+---+---+---+
| 5 | 6 | 7 | 8 | <- 25 seconds into video
+---+---+---+---+
| 9 |10 |11 |12 | <- 45 seconds into video
+---+---+---+---+
4. 创建动画 GIF
将视频片段提取为动画 GIF。
# Basic GIF (5 seconds from start)
{baseDir}/video-frames.js gif video.mp4 --output clip.gif
# Specific time and duration
{baseDir}/video-frames.js gif video.mp4 --start 00:01:30 --duration 5 --out highlight.gif
{baseDir}/video-frames.js gif video.mp4 --start 30 --duration 10 --out segment.gif
# Quality presets
{baseDir}/video-frames.js gif video.mp4 --start 60 --duration 3 --preset fast --out quick.gif
{baseDir}/video-frames.js gif video.mp4 --start 60 --duration 3 --preset quality --out smooth.gif
{baseDir}/video-frames.js gif video.mp4 --start 60 --duration 3 --preset cinematic --out cinema.gif
# Custom parameters
{baseDir}/video-frames.js gif video.mp4 --start 30 --duration 5 --fps 30 --width 720 --out preview.gif
GIF 预设:
| 预设 | FPS | 宽度 | 颜色数 | 大小 | 适用场景 |
|---|---|---|---|---|---|
fast | 15 | 480px | 128 | 小 | 快速生成 |
balanced | 20 | 640px | 256 | 中 | 默认设置 |
quality | 24 | 720px | 512 | 大 | 流畅动态效果 |
cinematic | 30 | 1080px | 1024 | 很大 | 最高质量 |
最长时长: 300 帧(30fps 时约为 10 秒)
5. 获取视频信息
显示详细的视频元数据。
{baseDir}/video-frames.js info video.mp4
输出:
{
"stats": { "size": 1234567890, "mtime": "..." },
"duration": 3665,
"width": 1920,
"height": 1080,
"fps": 29.97,
"totalFrames": 109785,
"info": { ... } // Full ffprobe output
}
进度跟踪
操作过程中会实时显示进度:
⏳ Extracting frames: 15/30 (50.0%) | Elapsed: 12.3s
⏳ Generating thumbnails: 8/12 (66.7%) | Elapsed: 5.2s
安全功能
限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 视频最大大小 | 50 GB | 输入文件大小限制 |
| 最长时长 | 4 小时 | 视频时长限制 |
| 最大帧数 | 1,000 | 批量帧提取限制 |
| 最大网格大小 | 60 张缩略图 | 联系表限制 |
| GIF 最大帧数 | 300 | 动画 GIF 限制 |
| 超时时间 | 30 分钟 | 默认操作超时时间 |
视频验证
处理前,此技能会验证:
- 文件存在且可读取
- 文件大小未超出限制
- 视频格式有效
- 时长未超出限制
- 包含视频流
- 文件未损坏
错误处理
错误代码
| 代码 | 名称 | 描述 |
|---|---|---|
| 0 | SUCCESS | 操作已完成 |
| 1 | INVALID_INPUT | 缺少参数或参数无效 |
| 2 | FILE_NOT_FOUND | 未找到视频 |
| 3 | INVALID_FORMAT | 不支持的格式 |
| 4 | INVALID_TIME_RANGE | 时间戳无效 |
| 5 | FFMPEG_ERROR | FFmpeg 执行失败 |
| 6 | OUT_OF_MEMORY | 超出内存限制 |
| 7 | TIMEOUT | 操作超时 |
| 8 | INTERRUPTED | 用户已中断 |
| 9 | PERMISSION_DENIED | 无法读取或写入 |
| 10 | VALIDATION_FAILED | 视频验证失败 |
| 99 | UNKNOWN | 意外错误 |
常见场景
帧索引超出范围:
{baseDir}/video-frames.js frame video.mp4 --index 999999
# ❌ ERROR: Frame index 999999 out of range (0-109784)
时间戳超出视频范围:
{baseDir}/video-frames.js frame video.mp4 --time 10000
# ❌ ERROR: Timestamp 02:46:40 out of range (0-01:01:05)
帧数过多:
{baseDir}/video-frames.js frames video.mp4 --fps 100
# ❌ ERROR: Too many frames requested: 366500 (max: 1000)
GIF 请求过大:
{baseDir}/video-frames.js gif video.mp4 --duration 60 --fps 60
# ❌ ERROR: GIF too long: 3600 frames (max: 300)
技术细节
帧提取方法
-
分段定位(
-ss位于-i之前)- 快速访问帧
- 用于
--time选项 - 起始位置的精度略有折衷
-
帧选择(
-vf select)- 精确提取指定帧索引
- 速度较慢,但帧级精确
- 用于
--index选项
-
按间隔提取(
fps滤镜)- 高效批量提取
- 帧率转换
- 用于批量操作
质量设置
JPEG 质量(CRF - 恒定码率因子):
-q:v 1 -> 100% quality (best, largest)
-q:v 2 -> ~95% quality (default)
-q:v 5 -> ~85% quality (web)
-q:v 10 -> ~70% quality (low)
-q:v 31 -> ~10% quality (minimum)
PNG 输出:
- 始终无损
- 文件较大
- 最适合归档
- 支持透明背景
缩放(Lanczos):
-vf scale=320:-2:flags=lanczos
- 使用 Lanczos 重采样以获得最佳质量
-2可确保尺寸为偶数(编码要求)- 保持宽高比
GIF 优化
调色板生成:
- 解析视频片段
- 生成最佳的 256 色调色板
- 将调色板应用于所有帧
- 使用抖动处理,让渐变更平滑
文件大小优化:
- 固定帧率
- 限制调色板颜色数
- 编码前调整大小
- 优化编码设置
示例
创建视频故事板
#!/bin/bash
VIDEO="movie.mp4"
OUTDIR="storyboard"
mkdir -p $OUTDIR
# Create overview grid
echo "Creating overview grid..."
{baseDir}/video-frames.js grid "$VIDEO" --count 20 --columns 5 --width 480 --out "$OUTDIR/overview.jpg"
# Extract key frames every minute
echo "Extracting key frames..."
{baseDir}/video-frames.js frames "$VIDEO" --fps 0.0167 --prefix key --out "$OUTDIR/"
# Create chapter thumbnails
echo "Creating chapter thumbnails..."
for time in 0:00 10:00 20:00 30:00; do
{baseDir}/video-frames.js frame "$VIDEO" --time $time --quality 1 --out "$OUTDIR/chapter_${time//:/}.png"
done
echo "Storyboard complete in $OUTDIR/"
视频预览图库
#!/bin/bash
for video in *.mp4; do
echo "Processing: $video"
# Create 3x3 grid
{baseDir}/video-frames.js grid "$video" --count 9 --columns 3 --width 640 --out "${video%.*}-grid.jpg"
# Create 5-second preview GIF
{baseDir}/video-frames.js gif "$video" --start 30 --duration 5 --preset balanced --out "${video%.*}-preview.gif"
done
每隔 N 秒提取帧
# Extract frame at beginning of every minute
for i in {0..60}; do
{baseDir}/video-frames.js frame video.mp4 --time $((i*60)) --out "frames/minute_${i}.jpg"
done
# Shell script for batch extraction
extract_frames() {
local video="$1"
local interval="${2:-10}" # default 10 seconds
local duration
duration=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$video")
for ((t=0; t<duration; t+=interval)); do
{baseDir}/video-frames.js frame "$video" --time $t --out "frames/frame_${t}.jpg"
done
}
生成高质量缩略图
# Best quality single frame
{baseDir}/video-frames.js frame video.mp4 \
--time 10 \
--format png \
--width 1920 \
--out thumbnail.png
# Best quality grid
{baseDir}/video-frames.js grid video.mp4 \
--count 9 \
--columns 3 \
--width 640 \
--format png \
--out grid.png
性能提示
1. 使用 JPEG 提高速度
JPEG 编码比 PNG 更快:
{baseDir}/video-frames.js frame video.mp4 --format jpg # Faster
{baseDir}/video-frames.js frame video.mp4 --format png # Better quality, slower
2. 草稿使用较低质量
# Quick preview
{baseDir}/video-frames.js grid video.mp4 --count 9 --width 320 # Small, fast
# Final quality
{baseDir}/video-frames.js grid video.mp4 --count 16 --width 640 # Higher detail
3. 并行处理
# Process multiple videos in parallel
{baseDir}/video-frames.js grid video1.mp4 --out g1.jpg &
{baseDir}/video-frames.js grid video2.mp4 --out g2.jpg &
{baseDir}/video-frames.js grid video3.mp4 --out g3.jpg &
wait
4. 提取时调整大小
优于先按原尺寸提取再缩放:
# Good
{baseDir}/video-frames.js frame video.mp4 --width 320 --out thumb.jpg
# Less efficient
{baseDir}/video-frames.js frame video.mp4 --out full.jpg
# Then resize externally
注意事项
- 如果可用,网格生成会使用 ImageMagick(质量更好);否则使用 FFmpeg 平铺滤镜
- 帧索引 0 始终是视频的第一帧
- 时间戳会根据视频 FPS 四舍五入到最近的帧
- GIF 使用 256 色调色板进行优化,以平衡质量和文件大小
- 保留 PNG 透明度(适用于叠加层)
- 所有操作都会自动清理临时文件
- JSON 输出便于以编程方式集成
- 网格缩略图会按视频间隔标注时间戳
评论
支持 Markdown