开源 OCR 工具从视频中提取内嵌硬编码字幕,支持中文识别、自动去重清洗
拿到一个视频文件,没有外挂字幕文件,也没有封闭字幕(Closed Caption),但画面上有中文字幕。你需要把这些字幕文字提取出来做翻译、做笔记、或者转成文本文件。
传统的做法是一边看视频一边手动打字,效率极低。如果视频长 30 分钟,打字至少需要 1-2 小时。本文介绍一种自动化的方案:使用 PaddleOCR 对视频逐帧 OCR 识别,再通过去重和清洗得到干净的字幕文本。整个流程在本地运行,无需上传视频文件到任何服务器。
视频字幕提取的核心流程分为 5 步:
本工具依赖 Python 3.9+、ffmpeg 和 PaddleOCR。以下是各系统的安装方法。
# 安装 ffmpeg
brew install ffmpeg
# 安装 Python 依赖
pip install paddlepaddle paddleocr Pillow numpy
# 验证安装
python3 -c "from paddleocr import PaddleOCR; from PIL import Image; print('OK')"
Windows 下推荐使用 Miniconda 创建独立环境,注意版本需要锁定 paddlepaddle==2.6.2(3.x 版本在 Windows 上有兼容问题)。
# 安装 ffmpeg(通过 winget)
winget install Gyan.FFmpeg
# 创建 conda 环境
conda create -n ocr python=3.10 -y
conda activate ocr
# 安装 PaddleOCR(版本锁定)
pip install "paddlepaddle==2.6.2" "paddleocr==2.9.1" Pillow "numpy<2"
# 验证
python -c "from paddleocr import PaddleOCR; print('OK')"
# 安装 ffmpeg
sudo apt install ffmpeg
# 安装 Python 依赖
pip install paddlepaddle paddleocr Pillow numpy
# 验证
python3 -c "from paddleocr import PaddleOCR; print('OK')"
在正式开始 OCR 识别之前,需要先告诉系统"字幕在画面上的什么位置"。这一步是自动完成的——脚本会抽取 5 帧样例,逐帧 OCR,按文字在画面上的 y 坐标做聚类分析,自动区分动态变化的字幕文本和固定不变的水印/Logo。
# 假设视频文件名为 video.mp4
python3 scripts/detect_subtitle_region.py \
--video "video.mp4" \
--output-dir "./region_detect"
运行后 region_detect/ 目录下会生成:
region_detect.json — 检测结果 JSON,包含候选区域的裁剪参数region_candidates.png — 标注图,展示候选区域(水印会标灰处理)samples/ — 抽取的 5 帧样例图片检测结果有三种情况:
| 情况 | 说明 | 处理方式 |
|---|---|---|
| 自动检测到 1 个区域 | 只有一个候选字幕区 | 直接用该区域的裁剪参数 |
| 检测到多个候选 | 可能有多个字幕行(如双语字幕) | 选择其中一个作为裁剪区域 |
| 未检测到区域 | 视频画面没有明显字幕 | 回退全帧模式(处理整张画面) |
--sample-count 10 重新检测。确定字幕区域后,脚本按设定间隔抽取视频帧,对裁剪区域进行 PaddleOCR 识别。
从第一步生成的 region_detect.json 中获取 crop 参数(格式为 x y width height),传入提取脚本:
python3 scripts/extract_subtitles.py \
--video "video.mp4" \
--crop 0 480 1080 200 \
--interval 0.5 \
--lang ch \
--progress-every-n 10 \
--output result.txt
python3 scripts/extract_subtitles.py \
--video "video.mp4" \
--no-crop \
--interval 0.5 \
--lang ch \
--output result.txt
参数说明:
--interval 0.5 — 每 0.5 秒抽一帧(值越小帧率越高、识别越准但越慢)--lang ch — 中文识别(可选 en 英文、ch 中文)--progress-every-n 10 — 每处理 10 帧输出一次进度--duration 60 — 只处理前 60 秒(可选)OCR 识别后的文本通常包含重复行、水印文字、以及识别错误的字符。清洗脚本自动处理这些问题:
python3 scripts/clean_output.py \
--input result.txt \
--output result_clean.txt \
--auto-filter
清洗步骤包括:
--position-filter 按 y 坐标位置聚类过滤弹幕文本。清洗后的文本基本可读,但 OCR 输出的标点通常是半角(英文字符)。最后一步是人工或手动修正:
" 替换为中文左引号 " 和右引号 "(交替使用)' → 中文单引号 ' / ', → ,、. → 。、? → ?(数字和代码中的保留原样)修正完成后写入最终文件 result_final.txt,逐段通读确保通顺。
以下是一个综合示例,涵盖全流程命令:
# 1. 检测字幕区域
python3 scripts/detect_subtitle_region.py \
--video "lecture.mp4" \
--output-dir ./region_detect
# 2. 假设检测到 crop 参数为 0 540 1080 160,开始 OCR 提取
# 每 0.5 秒一帧,每 10 帧输出一次进度
python3 scripts/extract_subtitles.py \
--video "lecture.mp4" \
--crop 0 540 1080 160 \
--interval 0.5 \
--lang ch \
--progress-every-n 10 \
--output result.txt
# 3. 清洗
python3 scripts/clean_output.py \
--input result.txt \
--output result_clean.txt \
--auto-filter
# 4. 查看初步结果
cat result_clean.txt
尝试以下方法提高精度:
--interval 0.3(帧率越高,越可能捕捉到完整字幕)--crop 参数--interval 1.0(牺牲精度换速度)--duration 300(只处理前 5 分钟)清洗时降低过滤阈值:--freq-threshold 0.2(默认 0.3,越低越敏感、越容易滤除水印)。
需要安装 Visual C++ Redistributable 2015+:
winget install Microsoft.VCRedist.2015+.x64
| 方案 | 优点 | 缺点 |
|---|---|---|
| 手动打字 | 100% 准确 | 耗时极长,30 分钟视频约需 1-2 小时 |
| Whisper 语音转写 | 准确率高的语音识别 | 需要语音清晰,无法提取画面上的文字(如 PPT 字幕) |
| PaddleOCR 视频提取 | 提取画面上任何可见文字 | 需要安装环境,处理时间较长 |
| 在线 API 服务 | 无需本地安装 | 费用高,视频需上传至第三方服务器 |
📌 本教程介绍的方法是纯本地方案,视频无需上传到任何服务器,适合处理包含敏感内容的视频文件。如果你需要帮助安装配置,可以参照文中各系统的安装步骤操作。