pull-film

自动分析视频的镜头语言、构图、色彩和音频,生成专业的 HTML 可视化报告。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pull-film" with this command: npx skills add benzema216/dreamina-claude-skills/benzema216-dreamina-claude-skills-pull-film

一键视频拉片分析

自动分析视频的镜头语言、构图、色彩和音频,生成专业的 HTML 可视化报告。

触发条件

当用户请求以下内容时触发:

  • "帮我分析/拉片这个视频"

  • "分析视频的镜头语言"

  • "/pull-film <视频路径或URL>"

输入要求

  • 视频来源:本地文件路径(.mp4/.mkv/.avi/.mov)或在线 URL(YouTube/Bilibili 等)

  • 可选参数:--language <zh/en/ja> 音频语言、--output <目录> 输出目录、--no-audio 跳过音频、--max-scenes <数量> 限制镜头数

依赖

工具 用途 安装

ffmpeg/ffprobe 视频处理、抽帧 brew install ffmpeg

Python3 + PIL 色彩分析 pip3 install Pillow

scenedetect 镜头切分 pip3 install "scenedetect[opencv]"

yt-dlp 在线视频下载(可选) pip3 install yt-dlp

whisper 音频转录(可选) pip3 install openai-whisper

执行流程

第 1 步:环境检查

检查 ffmpeg、python3、scenedetect 是否已安装,缺少则提示用户安装。

第 2 步:处理视频输入

本地视频 — 用 ffprobe 获取元信息(时长、分辨率、帧率、编码)

在线视频 — 用 yt-dlp 下载后再处理:

yt-dlp -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"
--merge-output-format mp4 -o "<输出目录>/source_video.mp4" "<URL>"

第 3 步:创建输出目录结构

mkdir -p "<输出目录>"/{frames,data,audio}

第 4 步:镜头切分

使用 ffmpeg 的场景检测或 PySceneDetect:

方法 A - 使用 ffmpeg 场景检测:

ffmpeg -i "<视频>" -filter:v "select='gt(scene,0.3)',showinfo" -f null - 2>&1 | grep showinfo

方法 B - 使用 PySceneDetect(更准确):

python3 << 'EOF' from scenedetect import detect, AdaptiveDetector import json

scenes = detect("<视频路径>", AdaptiveDetector()) result = [] for i, (start, end) in enumerate(scenes, 1): result.append({ "id": i, "start_time": start.get_seconds(), "end_time": end.get_seconds(), "start_frame": start.get_frames(), "end_frame": end.get_frames() }) print(json.dumps(result, indent=2)) EOF

将结果保存到 <输出目录>/data/scenes.json

第 5 步:提取关键帧

对每个镜头提取 3 帧(开头、中间、结尾):

对于每个镜头

ffmpeg -ss <start_time> -i "<视频>" -vframes 1 -q:v 2 "<输出目录>/frames/scene_<ID>start.jpg" ffmpeg -ss <mid_time> -i "<视频>" -vframes 1 -q:v 2 "<输出目录>/frames/scene<ID>mid.jpg" ffmpeg -ss <end_time-0.1> -i "<视频>" -vframes 1 -q:v 2 "<输出目录>/frames/scene<ID>_end.jpg"

第 6 步:镜头分析(使用 Claude Vision)

对每个镜头的关键帧,使用 Read 工具读取图片,然后分析:

分析内容:

景别 (Shot Scale)

  • 特写:面部或物体细节填满画面

  • 近景:人物胸部以上

  • 中景:人物膝盖或腰部以上

  • 全景:完整人物或场景主体

  • 远景:广阔环境,人物占比小

运动 (Camera Movement)

  • 固定:机位不动

  • 推:向主体靠近

  • 拉:远离主体

  • 摇:水平转动

  • 移:横向或纵向移动

  • 跟:跟随运动物体

  • 升降:垂直升降

  • 手持:有明显晃动

角度 (Camera Angle)

  • 平视:与被摄对象平行

  • 仰视:从下往上拍

  • 俯视:从上往下拍

  • 荷兰角:画面倾斜

构图 (Composition)

  • 三分法、对称、引导线、框中框、对角线、中心构图

色彩情绪

  • 色温:冷色调/暖色调/中性

  • 整体氛围

第 7 步:色彩分析

使用 Python 提取主色调:

python3 << 'EOF' import json from PIL import Image from collections import Counter import colorsys

def analyze_colors(image_path, n_colors=5): img = Image.open(image_path).convert('RGB') img = img.resize((100, 100)) # 缩小加速 pixels = list(img.getdata())

# 简化颜色(量化)
def quantize(color):
    return tuple(c // 32 * 32 for c in color)

quantized = [quantize(p) for p in pixels]
counter = Counter(quantized)
top_colors = counter.most_common(n_colors)

# 转为 HEX
hex_colors = ['#{:02x}{:02x}{:02x}'.format(*c[0]) for c in top_colors]

# 分析色温
avg_r = sum(p[0] for p in pixels) / len(pixels)
avg_b = sum(p[2] for p in pixels) / len(pixels)
temperature = "暖色调" if avg_r > avg_b * 1.1 else ("冷色调" if avg_b > avg_r * 1.1 else "中性")

return {"dominant": hex_colors, "temperature": temperature}

result = analyze_colors("<图片路径>") print(json.dumps(result)) EOF

第 8 步:音频分析(可选)

如果没有 --no-audio :

提取音频

ffmpeg -i "<视频>" -vn -acodec pcm_s16le -ar 16000 -ac 1 "<输出目录>/audio/audio.wav"

使用 Whisper 转录(如果已安装)

python3 << 'EOF' import whisper import json

model = whisper.load_model("base") result = model.transcribe("<输出目录>/audio/audio.wav", language="<语言>")

output = { "language": result.get("language", "unknown"), "segments": [{"start": s["start"], "end": s["end"], "text": s["text"]} for s in result["segments"]], "full_text": result["text"] } print(json.dumps(output, ensure_ascii=False, indent=2)) EOF

将转录结果保存到 <输出目录>/data/transcript.json

第 9 步:生成 HTML 报告

创建一个包含以下内容的 HTML 报告:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>视频拉片报告 - [标题]</title> <script src="https://cdn.jsdelivr.net/npm/chart.js">&#x3C;/script> <style> /* 现代化样式 */ * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: system-ui, sans-serif; background: #f5f5f5; } .container { max-width: 1400px; margin: 0 auto; padding: 20px; } header { background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 40px; border-radius: 12px; text-align: center; } .section { background: white; border-radius: 12px; padding: 25px; margin: 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .scene-card { border: 1px solid #eee; border-radius: 10px; margin: 15px 0; overflow: hidden; } .scene-header { background: #f8f9fa; padding: 15px; display: flex; justify-content: space-between; } .keyframes { display: flex; gap: 10px; } .keyframes img { width: 200px; height: 112px; object-fit: cover; border-radius: 6px; } .color-swatch { width: 30px; height: 30px; border-radius: 6px; display: inline-block; } </style> </head> <body> <div class="container"> <header> <h1>🎬 [视频标题]</h1> <p>时长: [时长] | 分辨率: [宽x高] | 镜头数: [数量]</p> </header>

    &#x3C;div class="section">
        &#x3C;h2>📊 统计概览&#x3C;/h2>
        &#x3C;canvas id="scaleChart">&#x3C;/canvas>
        &#x3C;canvas id="durationChart">&#x3C;/canvas>
    &#x3C;/div>

    &#x3C;div class="section">
        &#x3C;h2>🎞️ 拉片表&#x3C;/h2>
        &#x3C;!-- 每个镜头的卡片 -->
        &#x3C;div class="scene-card">
            &#x3C;div class="scene-header">
                &#x3C;span>镜头 #1&#x3C;/span>
                &#x3C;span>0.00s - 3.50s&#x3C;/span>
            &#x3C;/div>
            &#x3C;div class="scene-content">
                &#x3C;div class="keyframes">
                    &#x3C;img src="frames/scene_001_start.jpg">
                    &#x3C;img src="frames/scene_001_mid.jpg">
                    &#x3C;img src="frames/scene_001_end.jpg">
                &#x3C;/div>
                &#x3C;div class="analysis">
                    &#x3C;p>&#x3C;strong>景别:&#x3C;/strong> 中景&#x3C;/p>
                    &#x3C;p>&#x3C;strong>运动:&#x3C;/strong> 固定&#x3C;/p>
                    &#x3C;p>&#x3C;strong>角度:&#x3C;/strong> 平视&#x3C;/p>
                    &#x3C;p>&#x3C;strong>构图:&#x3C;/strong> 三分法&#x3C;/p>
                    &#x3C;p>&#x3C;strong>色温:&#x3C;/strong> 暖色调&#x3C;/p>
                    &#x3C;p>&#x3C;strong>主色调:&#x3C;/strong> &#x3C;span class="color-swatch" style="background:#xxx">&#x3C;/span>&#x3C;/p>
                    &#x3C;p>&#x3C;strong>对白:&#x3C;/strong> "..."&#x3C;/p>
                &#x3C;/div>
            &#x3C;/div>
        &#x3C;/div>
    &#x3C;/div>

    &#x3C;div class="section">
        &#x3C;h2>📝 完整对白&#x3C;/h2>
        &#x3C;pre>[转录文本]&#x3C;/pre>
    &#x3C;/div>
&#x3C;/div>

&#x3C;script>
    // Chart.js 图表代码
&#x3C;/script>

</body> </html>

将报告保存到 <输出目录>/report.html

第 10 步:输出结果

完成后告知用户:

  • 报告路径:<输出目录>/report.html

  • 镜头数量

  • 总时长

  • 是否包含音频转录

输出格式

<输出目录>/ ├── report.html # 主报告(浏览器打开) ├── frames/ # 关键帧截图 │ ├── scene_001_start.jpg │ ├── scene_001_mid.jpg │ └── ... ├── data/ │ ├── scenes.json # 镜头数据 │ ├── analysis.json # 分析结果 │ └── transcript.json # 对白转录 └── audio/ └── audio.wav # 提取的音轨

示例

用户输入:

/pull-film ./movie.mp4

用户输入:

/pull-film https://www.youtube.com/watch?v=xxxxx --language zh

用户输入:

帮我分析一下这个视频的镜头语言 ./trailer.mp4

注意事项

  • 对于长视频(>10分钟),建议使用 --max-scenes 限制分析数量

  • Claude Vision 分析需要逐个读取关键帧图片

  • Whisper 转录在首次使用时会下载模型(约 150MB)

  • 在线视频下载依赖 yt-dlp,某些平台可能有限制

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

storyboard-generator

No summary provided by upstream source.

Repository SourceNeeds Review
General

storyboard-creator

No summary provided by upstream source.

Repository SourceNeeds Review
General

music-analyze

No summary provided by upstream source.

Repository SourceNeeds Review
General

music-emotion

No summary provided by upstream source.

Repository SourceNeeds Review