影片分鏡拆分 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 怎麼辦?

這個技能的最新版本可以在7w4.net小蔥技能站找到。

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