视频分镜拆分 bozo-scene

👤 bozoyan 📦 v1.0.0 ⭐ 4.7 ⬇️ 306 下载
🎨 设计多媒体 免费

📖 技能介绍


name: bozo-scene description: 本地视频分镜(场景)分析与拆分工具。基于 PySceneDetect 自动检测视频中的场景切换点,支持两类核心任务:(1) 分镜首尾帧提取——为每个分镜分别导出一张首帧 + 一张尾帧图片;(2) 分镜视频导出——把每个分镜切成一段独立的 mp4 片段,并自动减去 1 帧时长避免「上一段尾帧=下一段首帧」的常见问题。当用户提到"分镜"、"场景切换"、"镜头切换"、"视频拆段"、"按分镜切视频"、"提取分镜首尾帧"、"拆分分镜视频"、"分镜预览图"、"按画面变化把视频切开"、"按镜头分段"、需要把一段长视频按场景变化切成多段、或需要批量分析视频的分镜结构时,必须使用此技能。即使用户没有明确提到 PySceneDetect,只要意图是「按画面变化把视频拆开」或「分析视频里有几个分镜」,都应优先使用此技能而不是让用户手动写 ffmpeg 命令。


bozo-scene:本地视频分镜分析与拆分

基于 PySceneDetect + ffmpeg,对本地视频文件做两件事:

  1. 分镜首尾帧提取scripts/scene_frames.py) 分析视频分镜结构,为每个分镜单独提取一张首帧 + 一张尾帧。 常用于:分镜脚本预览、AI 绘图/视频生成的关键帧参考、镜头风格评估。

  2. 分镜视频导出scripts/export_scenes.py) 把每个分镜切成一段独立的 mp4 片段。 常用于:二次剪辑素材准备、短视频批量分发、给每个分镜单独加特效后再合并。

终端日志会打印每个分镜的精确时间段(HH:MM:SS.mmm 毫秒精度),方便后续在剪辑软件或 ffmpeg 命令里直接复用。


何时使用

用户表达 调用脚本
"把这段视频按分镜切开" / "按场景拆段" scripts/export_scenes.py
"拆分分镜视频" / "按镜头切视频" scripts/export_scenes.py
"提取每个分镜的首尾帧" / "我要分镜预览图" scripts/scene_frames.py
"帮我分析下这段视频有几个分镜" 任一脚本都会先打印分镜列表
"把视频切成单独的镜头片段" scripts/export_scenes.py
"我要给每个分镜做关键帧" scripts/scene_frames.py
"批量分析这个文件夹下所有视频的分镜" 循环调用两个脚本之一

环境要求

  • Python 3.8+
  • ffmpeg / ffprobe(系统可执行,用于切分和取帧)
  • PySceneDetect + OpenCV 后端

如果环境没装 scenedetect,先帮用户装:

pip install scenedetect opencv-python

脚本调用

1. 提取分镜首尾帧

python scripts/scene_frames.py <video> [options]

参数: - <video>:视频文件路径(必填) - --output, -o:输出目录,默认 ./scene_frames - --threshold:分镜检测灵敏度,默认 27.0值越小越敏感(检出更多分镜),典型范围 20~35 - --min-scene-len:最短分镜时长(秒),默认 0.6,比这短的分镜会被丢弃 - --tail-offset:尾帧提前偏移(秒),默认 0.05,避免尾帧落在下一分镜首帧

输出命名(每个分镜两张 jpg):

{视频名}_scene01_首帧.jpg
{视频名}_scene01_尾帧.jpg
{视频名}_scene02_首帧.jpg
{视频名}_scene02_尾帧.jpg
...

2. 导出分镜视频片段

python scripts/export_scenes.py <video> [options]

参数: - <video>:视频文件路径(必填) - --output, -o:输出目录,默认 ./scene_clips - --name, -n:片段文件名前缀,默认用视频文件名 - --threshold:分镜检测灵敏度,默认 27.0 - --min-scene-len:最短分镜时长(秒),默认 0.6 - --no-trim-frame:禁用「减 1 帧」尾帧修正(默认开启,不建议关闭)

输出命名(每个分镜一段 mp4):

{name}_01.mp4
{name}_02.mp4
...

关键实现:默认开启「减 1 帧」尾帧修正——PySceneDetect 返回的 scene.end 是「下一分镜首帧」的时间戳(半开区间),如果直接按 end-start 切,下一分镜首帧会出现在本片段末尾。脚本自动把每个片段时长减去 1/fps(30fps 下约 33ms),保证片段末帧正好停在本分镜的真实末帧。如果用户明确不需要这个修正,加 --no-trim-frame


参数选择建议

threshold(分镜检测灵敏度)

视频类型 推荐值
默认 / 商业视频 / TikTok 短视频 27.0
画面变化平缓(长镜头、监控、纪录片) 30~35(避免误判)
剪辑很碎(MV、广告、运动集锦) 20~25(避免漏检)

如果检测出来的分镜数明显偏多/偏少,先调这个

min_scene_len(最短分镜时长)

  • 默认 0.6 秒,过滤抖动和闪屏
  • 用户明确说「我只要 3 秒以上的分镜」时,按用户给的秒数改
  • 处理 30fps 短视频保持默认;处理慢节奏长镜头可以拉到 1.0~2.0

输出说明

时间格式

日志里所有时间都是 HH:MM:SS.mmm(毫秒精度),可以直接复制到 ffmpeg 命令里用:

ffmpeg -ss 00:00:01.767 -i input.mp4 -t 1.366 -c copy out.mp4

命名规则

  • 首尾帧:{base}_scene{NN}_首帧.jpg / {base}_scene{NN}_尾帧.jpg
  • 视频片段:{name}_{NN}.mp4
  • 序号 NN01 开始,两位数补零

工作流程建议

  1. 先用默认参数跑一遍,看终端打印的分镜数和时间段是否合理
  2. 分镜数明显不对(太多/太少)→ 调 --threshold(小→更敏感→更多分镜)
  3. 分镜数对了但片段太碎 → 提高 --min-scene-len
  4. 把日志里的时间段记下来,后续可用于精确剪辑或自定义 ffmpeg 提取

批量处理

如果用户给的是文件夹而不是单个文件,列出文件夹内所有 .mp4 / .mov / .avi / .mkv / .flv / .wmv 然后循环调用脚本:

for v in /path/to/folder/*.mp4; do
  python scripts/export_scenes.py "$v" --output ./out
done

或者在 Python 里直接调用公共模块函数(见下)。


作为 Python 库使用

scripts/scene_common.py 暴露了可复用函数,便于在批量任务或更复杂流程里直接 import:

import sys
sys.path.insert(0, "path/to/bozo-scene/scripts")
from scene_common import detect_scenes, extract_frame, cut_segment, fmt_time

scenes, fps = detect_scenes("video.mp4", threshold=27.0, min_scene_len_sec=0.6)
for i, (s, e) in enumerate(scenes, 1):
    print(f"分镜 {i}: {fmt_time(s)} ~ {fmt_time(e)}")
    extract_frame("video.mp4", s, f"out/scene{i:02d}_first.jpg")
    cut_segment("video.mp4", s, e, fps, f"out/scene{i:02d}.mp4")

可用函数

函数 用途
fmt_time(seconds) 秒数格式化为 HH:MM:SS.mmm
probe_duration(video_path) 通过 ffprobe 获取视频总时长
detect_scenes(video_path, threshold, min_scene_len_sec) 返回 (scenes, fps)
extract_frame(video_path, timestamp_sec, output_path) 提取指定时间点的单帧
cut_segment(video_path, start_sec, end_sec, fps, output_path, trim_one_frame=True) 切分视频片段(默认减 1 帧避免尾帧泄漏)

常见问题

Q: 检测到的分镜数明显太多 / 太少怎么办?

--threshold。多→调大(30~35),少→调小(20~25)。

Q: 切出来的视频片段尾帧怎么和下一段首帧一样?

不应该出现——脚本默认已经减去 1 帧时长。如果仍出现: 1. 检查是否手动加了 --no-trim-frame,去掉它 2. 源视频可能是 VFR(可变帧率),先用 ffmpeg 转成 CFR: bash ffmpeg -i input.mp4 -vsync cfr -r 30 -c:v libx264 -crf 18 output.mp4

Q: 某些片段开头有黑屏?

源视频在该时间点附近是关键帧,ffmpeg 用 -ss 做快速 seek 可能从最近关键帧开始。脚本默认已经用 -c:v libx264 重编码(不是流拷贝),通常不会有这问题;若仍出现,先转 CFR 再处理。

Q: 没装 scenedetect 怎么办?

pip install scenedetect opencv-python

Q: 处理大视频太慢?

分镜检测阶段是 CPU 密集(PySceneDetect 逐帧解码对比),无法绕过。切分阶段每段约等于源视频同码率重编码时间。如果只是要分镜列表不要切视频,跑 scene_frames.pyexport_scenes.py 快很多。


设计要点

  • 底层一致:两个脚本共用 scene_common.py,分镜检测逻辑只在一处实现,修改一处即可同时影响两个工具
  • 半开区间处理:PySceneDetect 的 scene.end 是「下一分镜首帧」,所有切片/取帧操作都会做相应偏移
  • 可观测:终端日志永远打印每个分镜的精确时间段,方便用户核对和复用
  • 可批量:所有函数都设计为可独立 import,方便在 Python 里做更复杂的批量任务

🤖 AI 评测

这个工具质量不错,能可靠地帮你把视频按场景切开或提取分镜首尾帧。文档写得很清楚,参数调节有明确的建议,常见的坑(如片段尾帧重复)也有处理。上手容易,但需要自己安装 ffmpeg 和相关依赖,没有自动安装脚本,对新手不太友好。

📊 多维度评分

适应性4.8
规范性4.5
有效性4.9
可靠性4.4
可信度5

📁 包含文件 (4 个)

📄 SKILL.md 8.8 KB
📄 scripts/export_scenes.py 3.7 KB
📄 scripts/scene_common.py 5.7 KB
📄 scripts/scene_frames.py 3.3 KB

🔥 大家都在搜

wps 写作 pdf 苹果