项目背景

在视频相关的科研课题中,找到数据只是第一步。真正耗时的工作通常是从长视频中定位画面清晰、动作明确、镜头连续的短片段,并把结果整理成后续实验能够直接使用的数据。

基于目前需求在AI协助下完成了下面的项目,这个项目围绕 Internet Archive 公开资源实现了一套完整处理流程:先采集动漫、动画、短剧等视频的元数据,再自动分析源视频,最终输出 2~15 秒有效片段的起止时间。程序不会批量保存最终视频片段,只保留元数据、原视频链接和时间戳,便于后续按需取用。

从技术路线来看,它不是单纯的爬虫,也不是端到端的模型训练项目,而是一个“数据采集 + 传统计算机视觉 + 本地多模态大模型”的混合系统。

整体架构

整条管线分为两个相对独立的阶段:

  1. 元数据采集:得到结构化的视频数据集和可访问的原视频链接。
  2. 片段筛选:对视频进行镜头切分、画质分析和语义判断,输出符合条件的片段时间范围。

使用到的技术

技术在项目中的作用
Python 3.12编写采集、分析、筛选和导出逻辑
Internet Archive API搜索视频并获取作品元数据、文件列表和下载地址
urllib发起 HTTP 请求、下载视频和调用 Ollama 接口
ThreadPoolExecutor并发获取多个视频的元数据
FFprobe检查视频流、编码、分辨率、帧率和时长
PySceneDetect使用自适应算法检测镜头切换位置
OpenCV视频解码、定点抽帧、图像缩放和视觉指标计算
NumPy完成均值、中位数、标准差和帧间差分计算
Qwen3-VL 4B判断片段是否具有连续场景、清晰主体和有效动作
Ollama在本地部署和调用视觉模型
dHash生成感知哈希,去除内容相似的候选片段
CSV / JSON / JSONL保存数据集、结果、统计信息和断点状态
PowerShell + venv完成 Windows 环境初始化和运行封装
unittest验证分类、切片、时间码、去重和导出逻辑

第一阶段:采集 Internet Archive 元数据

使用官方 API,而不是解析网页

项目使用 Internet Archive 的 Advanced Search API 搜索候选资源,再通过 Metadata API 获取每个条目的完整信息。检索条件主要围绕以下字段构造:

  • mediatype:限制为电影或视频资源;
  • subject:匹配 anime、animation、short film、short drama 等主题;
  • title 和 description:补充召回标题或简介中包含相关词汇的资源;
  • language:优先查找中文相关记录。

相比直接抓取网页,官方 JSON API 的字段更稳定,也更适合科研数据的批量处理。

数据清洗与标准化

Internet Archive 中同一个条目通常包含原始文件、转码文件、缩略图、字幕等多种文件。项目会从文件列表中选择 source=original 的视频;如果存在多个原视频,则优先保留体积最大的一个。

采集结果统一为 21 个字段,主要包括:

  • 标题、作者、语言和描述;
  • 原视频链接和作品详情页链接;
  • 时长、分辨率、帧率、格式和文件大小;
  • 字幕链接、许可证地址和许可证状态;
  • 数据分类、集数信息、唯一标识和采集时间。

描述中的 HTML 标签会被清理;视频与字幕文件名会进行 URL 编码;中文“第十二集”和英文 S01E12、Episode 12 等形式会被正则表达式转换为统一的集数标识。

并发、重试与断点续跑

元数据接口属于网络 I/O,因此项目使用线程池并发请求,提高采集速度。面对 HTTP 429、500、502、503、504 或网络超时,会采用指数退避策略重试。

每获得一条有效记录,程序都会立即追加到 JSONL 检查点,并执行 flush + fsync 强制落盘。即使采集中途关闭,下一次运行也能跳过已经完成的记录。最终 CSV 和 JSON 通过临时文件原子替换生成,避免异常中断留下不完整文件。

第二阶段:寻找有效视频片段

FFprobe 探测视频

Internet Archive 中的视频格式并不统一,可能是 MPEG4、WebM、Matroska、QuickTime 或较早的 MPEG1、MPEG2。视频下载后,程序先调用 FFprobe 检查:

  • 是否存在可用的视频流;
  • 视频编码、宽高和平均帧率;
  • 容器中记录的真实时长。

这一步可以提前排除损坏文件,也为后面的镜头切分提供可靠的媒体信息。

PySceneDetect 划分连续镜头

项目使用 PySceneDetect 的 AdaptiveDetector 检测镜头边界。自适应检测会根据相邻帧的变化寻找转场,相比固定阈值,更能适应亮度和运动差异较大的动画、真人视频。

检测出的镜头会进一步转换为候选片段:

  • 少于 2 秒的镜头直接舍弃;
  • 2~15 秒的镜头直接成为候选;
  • 超过 15 秒的长镜头切成接近 6 秒的小段。

这样既满足最终片段的时长约束,也避免把整段长镜头直接交给模型处理。

OpenCV 与 NumPy 规则粗筛

如果每个候选都调用视觉模型,速度和显存占用都会很高。因此程序先从每个片段等间隔抽取 6 帧,再计算几项成本较低的视觉指标:

指标计算方式目的
亮度灰度图均值排除严重过暗的画面
清晰度拉普拉斯方差排除明显模糊的画面
信息量灰度标准差排除纯色、片头或信息过少的画面
运动量相邻采样帧绝对差均值排除接近静止的画面
时长奖励与 6 秒目标时长的距离优先选择长度适中的片段

规则分数满分为 100 分,其中亮度和清晰度各占 25 分,运动量占 20 分,信息量和时长各占 15 分。严重过暗、模糊、近似纯色或静态的候选会在这一阶段被直接拒绝。

快速版本还会把整段视频按时间划分为若干区域,从每个区域选择最接近 6 秒的候选,默认最多分析 60 个。这样既限制计算量,也能避免候选只集中在视频开头。

Qwen3-VL 语义复核

通过规则筛选后,得分最高的少量候选会进入多模态模型。项目使用 Ollama 在本机运行 qwen3-vl:4b,不调用收费云端 API,也不需要把视频数据上传到第三方服务。

程序把 6 张采样帧压缩为 JPEG 并转成 Base64,通过 Ollama 的 /api/chat 接口提交。提示词要求模型判断:

  • 人物或主要场景在时间上是否连续;
  • 是否存在快速混剪、闪回或明显转场;
  • 主体、动作和画面是否清楚;
  • 是否为静态图、纯文字或大面积遮挡;
  • 是否包含对话、走动、转身、开门、取物、打斗等明确动作。

模型必须返回固定 JSON 结构:

1
2
3
4
5
6
{
"accepted": true,
"confidence": 0.88,
"score": 82,
"reason": "人物动作连续,主体清晰,无明显转场"
}

只有模型明确接受、评分不低于 70 且置信度不低于 0.65 的候选,才会进入最终结果。低置信度或字段相互矛盾的结果不会静默丢弃,而是写入人工复核表。

使用 dHash 去除重复片段

同一视频中经常存在片头重复、静止特写或高度相似的镜头。程序分别计算候选片段首帧、中间帧和尾帧的 dHash,再通过汉明距离比较视觉签名。

相似度过高的片段只保留模型评分更高的一条。快速版本还会在全部视频结果之间进行一次全局去重,降低最终数据集中的视觉重复率。

最终实现效果

元数据采集结果

当前项目已经生成 200 条有效视频元数据:

数据分类数量
动画 animation104
动漫 anime92
短剧 short_drama4
合计200

文件格式覆盖 MPEG4、Matroska、QuickTime、MPEG1、MPEG2 和 WebM,其中 MPEG4 数量最多。每条数据都包含原视频直链,并尽可能保留时长、分辨率、帧率、字幕和许可证信息。

六种格式抽样实验

项目对六种视频格式各抽取一条进行验证,实验结果如下:

指标结果
处理视频6 条
成功选出片段的视频5 条
最终片段10 条
需要人工复核的候选7 条
未得到有效片段的视频1 条

六条视频总时长约 78 分钟,单条视频的镜头数从 7 个到 482 个不等。传统规则先过滤大量低质量候选,再由模型复核排名靠前的片段,证明这套分层策略能够处理不同编码、时长和内容类型的视频。

第一次抽样中,QuickTime 视频没有通过严格筛选。切换到快速管线,将 252 个候选按时间覆盖缩减为 60 个规则候选,并把模型复核数量调整为 5 个后,最终成功得到 1 条有效片段,处理耗时约 167 秒。

最终输出

系统会生成以下结果:

  • selected_clips.csv:最终通过筛选的片段及起止时间;
  • review_required.csv:低置信度候选,供人工确认;
  • failed_videos.csv:下载、解码失败或没有有效片段的视频;
  • checkpoint.jsonl:视频级断点续跑状态;
  • summary.json:镜头数、候选数、模型调用数、耗时等统计。

时间戳统一为 HH:MM:SS.mmm 格式。例如:

1
2
episode_or_part,start_time,end_time,duration
E12-P01,00:03:12.400,00:03:18.400,00:00:06.000

CSV 使用 UTF-8 BOM 编码,可以直接用 Excel 打开。程序处理完一条视频后会删除缓存中的源文件,因此磁盘空间不会随着全量任务持续增长。

工程化设计

为了让长时间运行的科研任务更稳定,项目还实现了几项工程能力:

  • 视频下载支持 HTTP Range 断点续传和指数退避重试;
  • 采集阶段和筛选阶段都有独立的 JSONL 检查点;
  • 每完成一个视频就重新导出结果,降低中断造成的数据损失;
  • 支持按格式过滤和“每种格式一条”的小样本验证;
  • 支持限制规则候选、模型候选和最终片段数量;
  • 提供 Windows PowerShell 初始化与运行脚本;
  • 使用本地 Ollama 模型,便于控制成本和数据流向。

项目现有 29 个单元测试,覆盖元数据分类、集数解析、原视频选择、字幕过滤、片段切分、时间码转换、感知哈希距离、检查点和原子导出等逻辑,当前测试全部通过。

当前局限与后续方向

目前已经验证的是系统的可运行性和跨格式处理能力,还不能把抽样结果直接解释为算法精度。要形成更完整的科研结论,后续仍需要:

  1. 建立人工标注的测试集,计算 Precision、Recall、F1、漏选率和误选率。
  2. 对比纯规则、纯视觉模型和混合管线,完成消融实验。
  3. 分析亮度、模糊度、运动量以及模型阈值对结果的影响。
  4. 固定模型版本、硬件环境和运行参数,保证实验可复现。
  5. 引入音频、字幕或更密集的时序特征,弥补稀疏抽帧可能遗漏瞬时转场的问题。
  6. 增加真实网络、视频解码和 Ollama 服务的集成测试。

总结

这个项目把一个宽泛的“从网络视频中寻找有效素材”问题拆成了多个成本逐渐增加的步骤:官方 API 负责获得数据,PySceneDetect 负责找边界,OpenCV 和 NumPy 负责低成本排除明显无效片段,Qwen3-VL 负责语义层面的严格判断,最后通过感知哈希和人工复核保证结果质量。

这种混合方案的关键不在于堆叠模型,而在于让不同技术处理自己最擅长的问题。规则算法便宜、稳定、可解释,大模型擅长复杂语义判断,两者结合后,既控制了推理成本,也让整个过程更容易调试和复现。