Skip to content

Esonhugh/video_extractor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

video-extractor (v2t)

视频教程转 Markdown 文本教程工具。专为 Apple Silicon Mac 优化,利用 mlx-whisper GPU 加速转录 + macOS 原生 Vision OCR 提取屏幕内容。

功能特性

  • 语音转录 — mlx-whisper 在 Apple Silicon 上 GPU 加速,支持 tiny/base/small/medium/large-v3 模型
  • 屏幕 OCR — Apple Vision Framework(Live Text 同款引擎),无需额外依赖
  • 六策略智能抽帧
    • 终端输出稳定点检测(快速滚动结束后抓帧)
    • 语音停顿期密采 + OCR diff 去重
    • 键盘敲击结束检测(打字完成 = 命令输入完毕)
    • 窗口切换检测(标题栏变化 = 切换应用)
    • 两遍法(粗采感知哈希 → 变化密集区精采)
    • LLM 智能命令提取(ollama 可选,回退正则)
  • 三层 OCR 过滤管道
    • UI 噪声剥离(任务栏时间/天气/搜索框/菜单栏)
    • 质量门控(二进制装饰、OCR 乱码、过短帧丢弃)
    • 滚动感知去重(同一页面不同滚动位置合并为最清晰帧)
  • 课程标题帧检测 — 自动识别课程标题页(OSCP/WEB-300/EXP-312 等)
  • 终端命令提取 — 正则 + LLM 双引擎,从 OCR 文本中提取可执行命令

设计原理

为什么需要 v2t

安全/编程课程视频(OSCP、WEB-300、EXP-312 等)知识密度极高,但视频格式不便检索和复习。v2t 自动提取三类核心信息:语音讲解 → 理解思路,屏幕内容 → 查看输出,终端命令 → 可直接复制执行。

架构决策

决策 选择 原因
转录引擎 mlx-whisper Apple Silicon Metal 加速,比 PyTorch Whisper 快 3-5x
OCR 引擎 Apple Vision 零额外依赖、Live Text 同款、系统内置
管线模式 Phase 串行 + 纯函数 可独立测试/替换每个 Phase,数据流清晰
命令提取 LLM + regex 双引擎 LLM 处理复杂交互工具 prompt,regex 高速兜底
数据格式 list/dict,无自定义类 最大互操作性,任何工具可读写中间结果
降级策略 每 Phase 自行降级 单点失败不中断管线(ollama 挂→用 regex)

系统要求

依赖 说明 安装方式
macOS 需要 Apple Vision Framework 系统自带
Apple Silicon M1/M2/M3/M4,mlx-whisper 依赖 Metal GPU 硬件要求
Python >= 3.11 运行时 brew install python@3.11
uv Python 包管理与脚本运行器 curl -LsSf https://astral.sh/uv/install.sh | sh
ffmpeg / ffprobe 音视频处理(抽帧、提取音频) brew install ffmpeg
ollama(可选) 本地 LLM 命令提取 brew install ollama + ollama pull qwen2.5:7b

Python 依赖

pyproject.toml 中声明,uv 自动管理:

包名 用途
mlx-whisper Apple Silicon GPU 加速的 Whisper 语音转录
pyobjc-framework-Vision Python 绑定 macOS Vision Framework(OCR)
Pillow 图像处理(感知哈希计算)

安装

# 1. 安装 uv(如果还没有)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. 安装 ffmpeg
brew install ffmpeg

# 3. 克隆仓库
git clone <repo-url> && cd video-extractor

# 4. 安装 Python 依赖(uv 自动解析 pyproject.toml,创建虚拟环境)
uv sync

# 5.(可选)安装 ollama 用于 LLM 命令提取
brew install ollama
ollama pull qwen2.5:7b

使用

基本用法

# 处理单个视频(输出同名 .md)
uv run video-extractor input.mp4

# 指定输出路径
uv run video-extractor input.mp4 -o output.md

# 也可以直接运行脚本
uv run scripts/extract.py input.mp4 -o output.md

进阶选项

# 使用更大的模型获得更好的转录质量
uv run video-extractor input.mp4 -m large-v3

# 指定语言(中文)
uv run video-extractor input.mp4 -l zh

# 调整场景检测灵敏度(0-1,越高越敏感,抽帧越多)
uv run video-extractor input.mp4 -s 0.5

# 批量处理目录下所有 MP4
uv run video-extractor ./videos/ -o ./output/

CLI 参数

参数 说明 默认值
input MP4 文件或包含 MP4 的目录 (必填)
-o, --output 输出 Markdown 文件路径 与输入同名 .md
-m, --model Whisper 模型大小 small
-l, --language 语言代码 en
-s, --scene 场景检测灵敏度 0-1 0.3

Whisper 模型选择

模型 速度 质量 VRAM 适用场景
tiny ~30x 实时 一般 ~1GB 快速预览、确认管线正常
base ~20x 实时 尚可 ~1GB 简单英文内容
small ~10x 实时 ~2GB 默认推荐,平衡速度与质量
medium ~5x 实时 很好 ~5GB 口音重或专业术语多
large-v3 ~2x 实时 最佳 ~10GB 最高精度需求

处理流程

MP4 输入
  │
  ├─ Phase 1: 音频提取 + mlx-whisper 转录
  │   ├─ ffmpeg 提取 16kHz 单声道 WAV
  │   ├─ mlx-whisper GPU 转录(含词级时间戳)
  │   └─ 输出: [{start, end, text}, ...] 带时间戳的文本段落
  │
  ├─ Phase 2: 六策略智能抽帧
  │   ├─ 策略 A: 场景变化检测(ffmpeg scene filter)
  │   ├─ 策略 B: 语音停顿点(transcript gap > 1.5s)
  │   ├─ 策略 C: 键盘敲击结束(音频波形分析)
  │   ├─ 策略 D: 窗口切换(标题栏 OCR diff)
  │   ├─ 策略 E: 两遍法(粗采哈希→密集区精采)
  │   ├─ 策略 F: 停顿区均匀密采
  │   ├─ 合并: ±1s 内去重取中点
  │   └─ 输出: [{file, timestamp, path}, ...] 关键帧列表
  │
  ├─ Phase 3: Apple Vision OCR + 三层过滤
  │   ├─ Vision OCR: 每帧图片 → 文本
  │   ├─ Stage 1: UI 噪声剥离(正则全行匹配删除)
  │   ├─ Stage 2: 质量门控(乱码/过短/装饰帧丢弃)
  │   ├─ Stage 3: 滚动感知去重(相似帧分组→选最优)
  │   └─ 输出: [{file, timestamp, path, ocr_text}, ...]
  │
  ├─ Phase 4: 终端命令提取
  │   ├─ 首选: ollama LLM 提取(JSON 格式返回)
  │   ├─ 回退: 正则引擎(shell prompt 模式匹配)
  │   ├─ 后处理: 清洗 + 可信度过滤
  │   └─ 输出: [{timestamp, command}, ...]
  │
  ├─ Phase 4.5: 课程标题帧检测
  │   ├─ 匹配已知课程关键词(WEB-300、PEN-200 等)
  │   └─ 输出: {course, topic}
  │
  └─ Phase 5: 组装输出 Markdown
      ├─ 所有事件按时间轴排序
      ├─ Whisper 幻觉去重(连续相同 speech 合并)
      ├─ 命令汇总 Cheatsheet
      └─ 时间轴: 转录 + OCR 折叠块 + 命令代码块

输出格式

生成的 Markdown 包含:

# 视频标题

**Course:** 课程系列名
**Topic:** 课程主题

## Commands Cheatsheet
(提取的终端命令汇总,去重后)

## Full Timeline
### [00:00:00]
**[00:00:05]** 语音转录文本...

<details><summary>[00:01:23] Screen Content</summary>
(OCR 提取的屏幕内容,已去噪去重)
</details>

```bash
# [00:01:25]
nmap -sV 192.168.1.1

## 外部 CLI 工具依赖说明

| 工具 | 用途 | 调用场景 |
|------|------|----------|
| `ffprobe` | 获取视频时长和元信息 | Phase 1/2 |
| `ffmpeg` | 提取音频 WAV、关键帧截图 | Phase 1/2 |
| `ollama` | 本地 LLM 推理(命令提取) | Phase 4(可选,不安装自动回退 regex) |

### ffmpeg 使用详情

```bash
# Phase 1: 提取音频为 WAV(16kHz 单声道,Whisper 要求)
ffmpeg -i input.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 audio.wav

# Phase 2: 粗采帧(每2秒一帧,用于感知哈希)
ffmpeg -i input.mp4 -vf "fps=0.5" -q:v 2 frame_%04d.png

# Phase 2: 精确时间戳抽帧(关键帧)
ffmpeg -ss <timestamp> -i input.mp4 -frames:v 1 -q:v 2 output.png

项目结构

video-extractor/
├── pyproject.toml          # 项目配置 & Python 依赖声明
├── uv.lock                 # uv 锁定依赖版本
├── CLAUDE.md               # AI 助手项目指南(代码风格/约束/命令)
├── README.md               # 本文件
├── scripts/
│   ├── extract.py          # CLI 入口脚本
│   └── v2t/                # 核心处理包
│       ├── __init__.py     # 公开 API: process_video, main
│       ├── pipeline.py     # Phase 编排 + argparse
│       ├── utils.py        # 共享常量 + 工具函数
│       ├── transcribe.py   # Phase 1: 转录
│       ├── keyframes.py    # Phase 2: 抽帧
│       ├── ocr.py          # Phase 3: OCR + 过滤
│       ├── commands/       # Phase 4: 命令提取
│       ├── title.py        # Phase 4.5: 标题检测
│       └── markdown.py     # Phase 5: 输出组装
├── skills/                 # Claude Code / Ducc 技能定义
│   └── v2t/
│       ├── SKILL.md        # v2t 技能描述
│       └── references/
│           └── code-modification-guide.md  # 代码修改指南
└── commands/               # Claude Code / Ducc 自定义命令

开发指南

环境设置

# 克隆并安装
git clone <repo-url> && cd video-extractor
uv sync

# 验证环境
uv run scripts/extract.py --help

常用开发命令

# 运行处理(始终用 uv run)
uv run scripts/extract.py input.mp4 -o output.md

# 语法检查
uv run python -c "import ast; ast.parse(open('scripts/v2t/ocr.py').read()); print('OK')"

# 模块导入验证
uv run python -c "from scripts.v2t import process_video; print('import OK')"

# 测试 OCR 过滤逻辑
uv run python -c "
from scripts.v2t.ocr import _strip_ui_noise, _passes_quality_gate
text = '5:24 PM\n75°F\nCloudy\nroot@kali:~# whoami'
cleaned = _strip_ui_noise(text)
print(cleaned)
print('Pass:', _passes_quality_gate(cleaned))
"

修改代码前必读

详细的代码修改指南见 skills/v2t/references/code-modification-guide.md

核心约束:

  • 不加新依赖 — 仅 mlx-whisperpyobjc-framework-VisionPillow
  • 不改数据结构 — Phase 间 dict key 是隐式 API
  • 不改 CLI 接口 — 保持向后兼容
  • uv run — 所有 Python 执行通过 uv,避免环境问题

License

MIT

About

视频教程转 Markdown 文本教程工具。专为 Apple Silicon Mac 优化,利用 mlx-whisper GPU 加速转录 + macOS 原生 Vision OCR 提取屏幕内容,让你的 AI 读懂视频教程

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages