让 Claude——或任何大语言模型——真正观看一段视频。
大多数 AI 工具并不能真正“看”视频。把 YouTube 链接粘贴到 ChatGPT 里,它读取的是文字转录稿,而不是画面。Claude 根本不接受视频文件。即便是原生支持读取视频的 Gemini,也必须把视频上传到 Google,并以固定间隔(默认每秒 1 帧)采样画面,因此快速剪辑的画面会被漏掉。
claude-real-video 的做法不同,而且是本地运行:指向一个 URL 或文件,它会提取真正重要的帧(每个场景切换点,而非固定配额),丢弃近乎重复的画面,转录音频,然后交给你一个任何大语言模型都能读取的干净文件夹——全程在你自己的机器上运行,没有任何内容被上传。
crv "https://www.youtube.com/watch?v=..." # → crv-out/frames/*.jpg + crv-out/transcript.txt + crv-out/MANIFEST.txt
然后把帧画面加上 MANIFEST.txt 文件一起丢进 Claude / ChatGPT / Gemini,就可以随意提问了。
为什么不直接采样帧呢?
大多数“让大语言模型看视频”的脚本(以及 Gemini 自身的处理流程)都是以固定间隔抓取帧——例如每秒一帧。这种方式对静态录屏会过度采样,而对快速剪辑的视频则采样不足。claude-real-video 更智能:
| 固定间隔采样 | claude-real-video | |
|---|---|---|
| 帧选择 | 每 N 秒一次 | 场景变化检测 + 密度下限 |
| 重复镜头(A-B-A 剪辑) | 每次都重复发送 | 滑动窗口去重,每个镜头只发送一次 |
| 静态幻灯片(10 分钟) | 约 600 张近乎相同的帧 | 压缩为 1 帧(去重后) |
| 快速剪辑视频 | 会漏掉采样间隔之间的帧 | 捕捉到每一次画面变化 |
| 音频 | 通常被忽略 | Whisper 转录,带语言检测 |
| 视频去向 | 通常上传到云端 | 留在你的机器上 |
| 输入 | 通常仅限本地文件 | URL(yt-dlp)或本地文件 |
你喂给模型的帧更少、更有意义——上下文更便宜,理解效果更好。
安装
pip install claude-real-video # core (frames + dedup) pip install "claude-real-video[whisper]" # + audio transcription
系统要求:ffmpeg
ffmpeg / ffprobe 用于帧提取和音频处理,无法通过 pip 安装。请一次性安装好:
| 操作系统 | 命令 |
|---|---|
| macOS | brew install ffmpeg |
| Linux | sudo apt install ffmpeg(或使用你的发行版对应的包管理器) |
| Windows | winget install Gyan.FFmpeg — 或 choco install ffmpeg — 或下载一个构建版本,将其 bin\ 文件夹添加到你的 PATH 环境变量中 |
确认它已在你的 PATH 中:
ffmpeg -version
转录功能使用 whisper CLI(通过 [whisper] 附加组件安装,或执行 pip install openai-whisper)。Whisper 也依赖 ffmpeg。
适用于 macOS、Windows 和 Linux——需要 Python 3.10 及以上版本。
使用方法
# A YouTube / Instagram / TikTok / ... link crv "https://www.instagram.com/reel/XXXX/" # A local file, English transcript, output to ./out crv lecture.mp4 -o out --lang en # Frames only, no transcription crv clip.mp4 --no-transcribe # A login-gated video (your own / authorised use): pass a Netscape cookie file crv "https://..." --cookies cookies.txt
python -m claude_real_video ... 也可作为 crv 的别名使用。
选项
| 标志 | 默认值 | 含义 |
|---|---|---|
| -o, --out | crv-out | 输出目录 |
| --scene | 0.30 | 场景切换敏感度(数值越低,提取的帧数越多) |
| --fps-floor | 1.0 | 每 N 秒至少提取一帧 |
| --max-frames | 150 | 总帧数的硬性上限 |
| --lang | auto | Whisper 语言(en, zh, auto, ...) |
| --dedup-threshold | 8 | 判定为新帧所需变化的像素百分比;数值越高,帧数越少 |
| --dedup-window | 4 | 与最近保留的 N 帧进行比较——模型已看过的镜头在切出后不会再次出现(1 表示仅与连续帧比较) |
| --report | off | 将丢弃的帧保存在 ./dropped 目录中,并生成 report.html 文件,可视化展示每一次保留/丢弃决策 |
| --no-transcribe | off | 跳过音频 |
| --keep-audio | off | 同时保存完整音轨(audio.m4a),以便音频模型能够听到 |
| --cookies | – | 用于登录受限源的 Netscape cookie 文件 |
从 Python 中使用
from claude_real_video import process r = process("https://youtu.be/...", "out", lang="en") print(r.frame_count, r.)
工作原理
- 获取——使用 yt-dlp 获取 URL(可选 cookie),或复制本地文件。
- 提取——通过一次按时间顺序的 ffmpeg 选择通道,捕获每次场景切换,并满足密度下限(每 --fps-floor 秒至少一帧),从而同时覆盖快速剪辑和慢速录屏。
- 去重——基于实际像素差异(缩放后的 RGB,而非感知哈希——哈希在纯色和等亮度色调变化时会失效),与最近保留的 --dedup-window 帧构成的滑动窗口进行比较,因此 A-B-A 切出不会重新发送模型已看过的镜头。--report 会生成 report.html,显示每次保留/丢弃决策及其差异百分比,便于调参。
- 文本——如果视频已有字幕(本地文件旁的 .srt/.vtt 侧挂文件,或内嵌字幕轨道),则直接使用这些字幕作为转录文本——比重新转录更快、更准确。仅当没有字幕时,才会回退到使用 Whisper 处理音频(若无音频则干净地跳过)。
- 音频(可选,--keep-audio)——保存完整的原始音轨(audio.m4a:包含音乐、语音和音效,尽可能无损复制)。转录文本只包含文字;音频文件则让具备听觉能力的模型(如 Gemini、GPT-4o 等)能够真正听到音乐和语调。
- 清单——MANIFEST.txt 为模型汇总所有信息。
因此,模型可以“看”(关键帧)、“读”(文字转录),并在使用 `--keep-audio` 参数时“听”(完整音轨)视频。文字转录是任何模型都能读取的纯文本;该工具不会将字幕烧录到视频中——烧录是一种呈现方式的选择,并非让视频具备 AI 可读性的必要条件。
注意事项
- 仅下载您拥有合法权限的内容。`--cookies` 选项用于您个人的授权访问——切勿在代码仓库中提交凭证信息。
- 重新运行会覆盖输出目录。
许可证
关于
让 Claude(或任何大语言模型)真正“观看”视频——从 URL 或本地文件获取场景感知、去重后的帧画面与文字转录。本地运行,采用 MIT 许可证。
Let Claude — or any LLM — actually watch a video.
Most AI tools don't really see a video. Paste a YouTube link into ChatGPT and it reads the transcript, not the picture. Claude won't take a video file at all. Even Gemini, which can read video natively, has to send it up to Google and samples frames at a fixed interval (1 fps by default), so fast cuts slip past.
claude-real-video does it differently, and locally: point it at a URL or a file, and it pulls the frames that actually matter (every scene change, not a fixed quota), throws away the near-duplicates, transcribes the audio, and hands you a clean folder any LLM can read — on your own machine, nothing uploaded.
crv "https://www.youtube.com/watch?v=..." # → crv-out/frames/*.jpg + crv-out/transcript.txt + crv-out/MANIFEST.txt
Then drop the frames + MANIFEST.txt into Claude / ChatGPT / Gemini and ask away.
Why not just sample frames?
Most "let an LLM watch a video" scripts (and Gemini's own pipeline) grab frames at a fixed interval — e.g. one per second. That over-samples a static screencast and under-samples a fast-cut reel. claude-real-video is smarter:
| fixed-interval sampling | claude-real-video | |
|---|---|---|
| Frame selection | every N seconds | scene-change detection + density floor |
| Repeated shots (A-B-A cuts) | sent again every time | sliding-window dedup sends each shot once |
| Static slide (10 min) | ~600 near-identical frames | collapses to 1 (dedup) |
| Fast-cut reel | misses frames between samples | catches each visual change |
| Audio | often ignored | Whisper transcript w/ language detect |
| Where the video goes | often uploaded to a cloud | stays on your machine |
| Input | usually local file only | URL (yt-dlp) or local file |
You feed the model fewer, more meaningful frames — cheaper context, better understanding.
Install
pip install claude-real-video # core (frames + dedup) pip install "claude-real-video[whisper]" # + audio transcription
System requirement: ffmpeg
ffmpeg / ffprobe are used for frame extraction and audio, and aren't pip-installable. Install them once:
| OS | command |
|---|---|
| macOS | brew install ffmpeg |
| Linux | sudo apt install ffmpeg (or your distro's package manager) |
| Windows | winget install Gyan.FFmpeg — or choco install ffmpeg — or download a build and add its bin\ folder to your PATH |
Verify it's on your PATH:
ffmpeg -version
Transcription uses the whisper CLI (installed by the [whisper] extra, or pip install openai-whisper). Whisper also relies on ffmpeg.
Works on macOS, Windows, and Linux — Python 3.10+.
Usage
# A YouTube / Instagram / TikTok / ... link crv "https://www.instagram.com/reel/XXXX/" # A local file, English transcript, output to ./out crv lecture.mp4 -o out --lang en # Frames only, no transcription crv clip.mp4 --no-transcribe # A login-gated video (your own / authorised use): pass a Netscape cookie file crv "https://..." --cookies cookies.txt
python -m claude_real_video ... works as an alias for crv too.
Options
| flag | default | meaning |
|---|---|---|
-o, --out | crv-out | output directory |
--scene | 0.30 | scene-change sensitivity (lower = more frames) |
--fps-floor | 1.0 | at least one frame every N seconds |
--max-frames | 150 | hard cap on total frames |
--lang | auto | Whisper language (en, zh, auto, ...) |
--dedup-threshold | 8 | % of pixels that must change for a frame to count as new; higher = fewer frames |
--dedup-window | 4 | compare against the last N kept frames — a shot the model already saw doesn't come back after a cutaway (1 = consecutive-only) |
--report | off | keep dropped frames in ./dropped + write report.html visualising every keep/drop decision |
--no-transcribe | off | skip audio |
--keep-audio | off | also save the full soundtrack (audio.m4a) so audio models can hear it |
--cookies | – | Netscape cookie file for login-gated sources |
Use it from Python
from claude_real_video import process r = process("https://youtu.be/...", "out", lang="en") print(r.frame_count, r.)
How it works
- Fetch —
yt-dlpfor URLs (optional cookies), or copy a local file. - Extract — one chronological
ffmpeg selectpass grabs every scene change plus a density floor (at least one frame every--fps-floorseconds), so fast cuts and slow screencasts are both covered. - Dedup — real pixel difference (downscaled RGB, not a perceptual hash — hashes go blind on flat colours and equal-luma hue changes) against a sliding window of the last
--dedup-windowkept frames, so an A-B-A cutaway doesn't re-send a shot the model has already seen.--reportwritesreport.htmlshowing every keep/drop decision with its diff %, for tuning. - Text — if the video already has subtitles (a sidecar
.srt/.vttnext to a local file, or an embedded subtitle track), those are used as the transcript — faster and more accurate than re-transcribing. Only when there are no subtitles does it fall back to Whisper on the audio (skipped cleanly if there's no audio). - Audio (optional,
--keep-audio) — save the full original soundtrack (audio.m4a: music + speech + effects, copied losslessly when possible). The transcript only has the words; the audio file lets a model that can listen (Gemini, GPT-4o, …) actually hear the music and tone. - Manifest —
MANIFEST.txtsummarises everything for the model.
So the model can see (key frames), read (transcript) and — with --keep-audio — hear (full soundtrack) the video. The transcript is plain text any model can read; the tool doesn't burn subtitles into the video — burning is a presentation choice, not something needed to make a video AI-readable.
Notes
- Only download content you have the right to. The
--cookiesoption is for your own, authorised access — don't ship credentials in a repo. - Re-running overwrites the output directory.
License
About
Let Claude (or any LLM) actually watch a video — scene-aware, deduplicated frames + transcript, from a URL or local file. Runs locally, MIT.