开源 OCR 工具从视频中提取内嵌硬编码字幕,支持中文识别、自动去重清洗

拿到一个视频文件,没有外挂字幕文件,也没有封闭字幕(Closed Caption),但画面上有中文字幕。你需要把这些字幕文字提取出来做翻译、做笔记、或者转成文本文件。

传统的做法是一边看视频一边手动打字,效率极低。如果视频长 30 分钟,打字至少需要 1-2 小时。本文介绍一种自动化的方案:使用 PaddleOCR 对视频逐帧 OCR 识别,再通过去重和清洗得到干净的字幕文本。整个流程在本地运行,无需上传视频文件到任何服务器。

整体思路

视频字幕提取的核心流程分为 5 步:

  1. 环境准备 — 安装 Python、ffmpeg 和 PaddleOCR 依赖
  2. 检测字幕区域 — 自动识别画面上字幕出现的位置(排除固定水印)
  3. 逐帧 OCR — 按时间间隔抽取视频帧,对字幕区域进行文字识别
  4. 清洗去重 — 去除重复行、水印文字和 OCR 伪影
  5. 标点修正 — 将半角标点转为全角,完成最终校对

第一步:安装依赖

本工具依赖 Python 3.9+、ffmpeg 和 PaddleOCR。以下是各系统的安装方法。

macOS 安装

# 安装 ffmpeg
brew install ffmpeg

# 安装 Python 依赖
pip install paddlepaddle paddleocr Pillow numpy

# 验证安装
python3 -c "from paddleocr import PaddleOCR; from PIL import Image; print('OK')"

Windows 安装

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')"

Linux 安装

# 安装 ffmpeg
sudo apt install ffmpeg

# 安装 Python 依赖
pip install paddlepaddle paddleocr Pillow numpy

# 验证
python3 -c "from paddleocr import PaddleOCR; print('OK')"
💡 PaddleOCR 首次运行时会自动下载 OCR 模型(约 200MB),耗时 1-3 分钟,属正常现象。

第二步:检测字幕区域

在正式开始 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 重新检测。

第三步:执行 OCR 提取

确定字幕区域后,脚本按设定间隔抽取视频帧,对裁剪区域进行 PaddleOCR 识别。

方式 A:使用自动检测的裁剪区域(推荐)

从第一步生成的 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

方式 B:全帧模式(字幕位置不固定时)

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 秒(可选)
💡 60 秒以内的短视频,脚本会自动使用全帧模式。长视频建议用裁剪模式大幅提升处理速度。

第四步:清洗输出结果

OCR 识别后的文本通常包含重复行、水印文字、以及识别错误的字符。清洗脚本自动处理这些问题:

python3 scripts/clean_output.py \
  --input result.txt \
  --output result_clean.txt \
  --auto-filter

清洗步骤包括:

  • 去重 — 连续多帧中重复出现的文字只保留一次
  • 自动过滤水印 — 通过字符相似度聚类识别出高频出现的固定文字(如水印、标题),将其移除
  • 滑动窗口去重 — 消除同一帧多个文本框交替出现导致的重复(如 A, B, A, B → A, B)
⚠️ 如果视频中有弹幕,可以加 --position-filter 按 y 坐标位置聚类过滤弹幕文本。

第五步:标点修正与最终整理

清洗后的文本基本可读,但 OCR 输出的标点通常是半角(英文字符)。最后一步是人工或手动修正:

  • 双引号 — 将英文直引号 " 替换为中文左引号 " 和右引号 "(交替使用)
  • 单引号 — 英文单引号 ' → 中文单引号 ' / '
  • 其他标点,.?(数字和代码中的保留原样)
  • 形近字修正 — "己"/"已"、"末"/"未"等 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 参数
  • 确认视频画质不要太低(至少 480p)

处理速度太慢?

  • 增大抽帧间隔:--interval 1.0(牺牲精度换速度)
  • 缩小裁剪区域:只框选字幕出现的那一小块画面
  • 限制处理时长:--duration 300(只处理前 5 分钟)

水印太多怎么办?

清洗时降低过滤阈值:--freq-threshold 0.2(默认 0.3,越低越敏感、越容易滤除水印)。

Windows 上报 DLL load failed?

需要安装 Visual C++ Redistributable 2015+:

winget install Microsoft.VCRedist.2015+.x64

与其他方案的对比

方案优点缺点
手动打字100% 准确耗时极长,30 分钟视频约需 1-2 小时
Whisper 语音转写准确率高的语音识别需要语音清晰,无法提取画面上的文字(如 PPT 字幕)
PaddleOCR 视频提取提取画面上任何可见文字需要安装环境,处理时间较长
在线 API 服务无需本地安装费用高,视频需上传至第三方服务器

📌 本教程介绍的方法是纯本地方案,视频无需上传到任何服务器,适合处理包含敏感内容的视频文件。如果你需要帮助安装配置,可以参照文中各系统的安装步骤操作。