Vito
[参考脚本地址(点击跳转)](https://github.com/vito01111/media-subtitle-tools/blob/main/video_subtitle_ocr.py)
## 一、为什么要用OCR做字幕识别
对于视频字幕提取,ASR(语音识别)通常是第一选择,但实际使用中会遇到不少问题。一方面,ASR 在嘈杂环境下干扰多,对专业名词、人名、地名的识别准确率低,经常出现误听,后期校对工作量巨大。另一方面,很多视频已有精校翻译,只是网上流传的精校字幕视频往往夹带各种"私货",水印、广告、推广链接、视频压缩严重太模糊等,观看体验很差;这时候,**OCR字幕识别**就成了更实用的方案:直接从精校字幕视频画面中识别文字,既能避开精校字幕的广告污染,又能获得相对准确的原始字幕内容。
懒猫算力舱支持 **PaddleOCR** 和 **DeepSeek OCR** 两种引擎。对于常见的影视剧、综艺节目等简单字幕格式(单行或双行、字体规整、背景对比度高),**PaddleOCR 的识别速度更快**,是批量处理视频字幕的理想选择。接下来我们将基于 PaddleOCR 算力舱 API,搭建一个自动化的字幕提取工具。
### 适用场景与局限性
**适合使用OCR的场景:**
- 视频有硬字幕(烧录在画面中的字幕)
- 字幕区域固定(通常在画面下方)
- 画面清晰,字幕对比度高
- 字体规整,无过度艺术化效果
**不适合的场景:**
- 软字幕(可以关闭的外挂字幕)→ 直接提取字幕文件更快
- 字幕位置不固定(如弹幕、动态字幕)
- 画面模糊、压缩严重
- 艺术字体、手写字体
---
## 二、环境准备
### 2.1 必需工具
- **FFmpeg**:用于视频抽帧(需添加到系统PATH)
- **Python 3.8+**:运行脚本
- **算力舱API地址**: https://ocr-ai.{这里填你的用户名}.heiyu.space/ocr
- 将 `{这里填你的用户名}` 替换为你的实际用户名
### 2.2 Python依赖
```bash
pip install requests pillow
```
### 2.3 验证FFmpeg
```bash
ffmpeg -version
```
如果显示版本信息,说明FFmpeg已正确安装。
---
## 三、OCR字幕提取的处理思路

整个字幕提取流程可以分为五个步骤:
**第一步:视频抽帧**
使用 FFmpeg 按固定时间间隔(比如每5秒)从视频中截取一帧画面。这样既能覆盖完整的字幕内容,又不会产生过多冗余数据,在识别精度和处理速度之间取得平衡。
**第二步:智能裁剪**
由于字幕通常出现在画面下方,我们只需要截取底部 1/4 区域进行识别。这样可以大幅减少图片大小,提升识别速度,同时避免画面上方的无关文字(如台标、角标、弹幕等)干扰识别结果。

**第三步:并发 OCR 识别**
将裁剪后的图片通过多线程方式批量提交到算力舱 PaddleOCR API,充分利用云端算力实现快速处理。相比单线程逐张识别,并发处理可以将总耗时缩短数倍。
**第四步:结果清洗**
过滤掉广告水印、重复内容等噪声,将连续多帧中相同或相似的字幕合并成一条完整记录,并按时间轴生成标准的 SRT 字幕文件。
**第五步:AI 智能校对**
使用长上下文的大模型(如 Claude、Gemini 等)对生成的字幕进行二次校对。在提示词中提供视频的人物信息、背景介绍、专业术语等上下文,帮助大模型理解对话场景,识别并修正典型的 OCR 错误(如形近字误识、标点符号错误、语义不通顺等),进一步提升字幕质量。
这样五步流程就完整了。通过OCR提取+AI校对的组合,可以获得质量较高的字幕文件,既避免了精校字幕的广告污染,又能保证较高的准确率。
### 流程参数速查表
| 步骤 | 操作 | 关键参数 | 说明 |
|------|------|----------|------|
| 1 | 视频抽帧 | 间隔5秒 | 使用FFmpeg,平衡精度与速度 |
| 2 | 智能裁剪 | 底部1/4 | 只保留字幕区域,提升速度 |
| 3 | OCR识别 | 8线程并发 | 调用算力舱API,快速处理 |
| 4 | 结果清洗 | 相似度0.8 | 去重、合并、生成SRT |
| 5 | AI校对 | 长文本模型 | 修正错别字、补充标点 |
---
## 四、算力舱API调用方式
### 4.1 API配置
算力舱的调用方式非常简洁:
```python
# API配置
OCR_API_URL = "https://ocr-ai.{这里填你的用户名}.heiyu.space/ocr"
OCR_REQUEST_BODY = {
"max_size": 1920,
"overlap": 100,
"memory_limit_mb": 1024,
"det": True,
"rec": True,
"cls": True,
}
```
### 4.2 调用示例
```python
# 调用方式
def ocr_image(image_path: str) -> str:
with open(image_path, "rb") as fh:
files = {"file": (os.path.basename(image_path), fh, "image/png")}
data = {"request": json.dumps(OCR_REQUEST_BODY, ensure_ascii=False)}
resp = requests.post(
OCR_API_URL,
files=files,
data=data,
headers={"accept": "application/json"},
proxies={"http": None, "https": None},
timeout=300,
)
return resp.text.strip()
```
### 4.3 核心要点
- 使用 `multipart/form-data` 方式上传图片文件
- 请求参数通过 `request` 字段以 JSON 字符串形式传递
- 返回结果是包含 `results` 数组的 JSON,每个元素有 `text` 字段
### 4.4 关键参数说明
- `max_size`: 图片最大尺寸,默认1920(像素)
- `overlap`: 图片分块时的重叠区域,默认100(像素)
- `memory_limit_mb`: 内存限制,默认1024(MB)
- `det`: 是否检测文字区域,建议true
- `rec`: 是否识别文字内容,建议true
- `cls`: 是否进行文字方向分类,建议true
---
## 五、AI辅助开发
### 5.1 生成脚本的提示词
基于以上流程,可以让AI直接使用以下提示词开发OCR识别脚本:
```markdown
请帮我写一个Python脚本,实现视频字幕OCR提取功能,需求如下:
1. 功能需求:
- 使用FFmpeg从视频中按固定间隔(默认5秒)抽帧
- 只截取画面下方1/4区域(字幕常见位置)
- 调用算力舱PaddleOCR API进行文字识别
- 多线程并发处理提升速度
- 清洗识别结果:去除广告、水印、重复内容
- 合并相似字幕,生成标准SRT格式文件
2. 算力舱API调用方式:
- 接口地址:https://ocr-ai.{这里填你的用户名}.heiyu.space/ocr
- 请求方式:POST multipart/form-data
- 参数:
* file: 图片文件(PNG格式)
* request: JSON字符串,包含 {"max_size": 1920, "det": true, "rec": true, "cls": true}
- 返回:JSON格式,results数组中每个元素包含text字段
3. 技术要点:
- FFmpeg命令:使用 fps=1/5 控制抽帧间隔,crop=iw:ih/4:0:3*ih/4 裁剪下方1/4
- 并发控制:使用ThreadPoolExecutor,默认8个线程
- 噪声过滤:
* 正则匹配过滤网址、广告关键词
* 统计高频文本生成动态黑名单(出现次数>总帧数5%)
* 要求字幕必须包含中文字符
- 字幕合并:使用difflib.SequenceMatcher计算相似度(阈值0.8),相似字幕合并时间轴
- 环境变量配置:支持通过环境变量调整抽帧间隔、并发数、过滤阈值等
4. 异常处理与重试机制:
- OCR API调用失败时自动重试(默认最多3次)
- 每次重试间隔递增(1秒、2秒、3秒)
- 记录详细错误信息:HTTP状态码、响应内容、异常类型
- 区分处理不同错误类型:
* 400/422错误:记录请求参数,不重试(客户端错误)
* 500/502/503错误:自动重试(服务端临时故障)
* 超时错误:自动重试并增加超时时间
* 网络错误:自动重试
- 统计失败率:显示成功/失败/重试次数
- 部分失败时继续处理:即使部分帧OCR失败,也生成可用字幕
5. 时间轴精确计算:
- 从帧文件名提取序号(如 frame_0017.png → 第17帧)
- 时间戳 = (帧序号 - 1) × 抽帧间隔
- 确保第一帧从0秒开始,而非从抽帧间隔开始
- 字幕结束时间 = 下一条字幕开始时间(或当前时间+间隔)
6. 输出要求:
- 生成 _ocr.srt 文件
- SRT格式:序号、时间轴(hh:mm:ss,ms --> hh:mm:ss,ms)、字幕文本
- 显示实时进度:已处理帧数/总帧数、百分比、预计剩余时间
- 输出统计信息:
* 抽帧耗时、OCR耗时、总耗时
* OCR成功率:成功/失败/重试次数
* 字幕数量:原始识别数、过滤后数量、最终合并数
7. 用户体验:
- 如果当前目录有多个MP4文件,提供交互式选择
- 支持命令行参数指定视频文件
- 自动清理临时抽帧文件
- Windows系统自动设置UTF-8编码
- 显示彩色进度条和状态图标(✅ ⚠️ ❌ 🔄)
- 失败时提供诊断建议(检查网络、API密钥、图片格式等)
```
### 5.2 字幕校对提示词
#### 通用OCR字幕校对提示词
```markdown
你是一个专业的字幕校对助手。我会提供一份通过OCR识别的视频字幕文件(SRT格式),需要你进行智能校对和修正。
## 第一步:分析视频背景信息
在开始校对之前,请先通读字幕内容,分析并总结以下信息:
1. **视频类型**:电影解说、教学视频、综艺节目、新闻访谈、游戏实况等
2. **主题领域**:科技、历史、娱乐、教育、体育等
3. **关键人物**:视频中出现的重要人名、角色名
4. **专业术语**:领域特定的词汇(如技术名词、医学术语、法律用语等)
5. **语言风格**:正式/口语化、是否有网络用语、方言俚语等
6. **时代背景**:现代、历史题材、未来科幻等
请先输出你的分析结果,格式如下:
【视频背景分析】
- 视频类型:
- 主题领域:
- 关键人物:
- 专业术语:
- 语言风格:
- 其他特征:
## 第二步:识别并修正典型OCR错误
### 1. 形近字误识
常见错误模式:
- 数字与汉字混淆:0/O、1/l、2/Z、5/S、8/B
- 偏旁部首错误:子/孑、未/末、己/已、戊/戌
- 笔画相似:副/幅、华/花、刀/力、拓/拆
- 根据上下文语义判断正确用字
### 2. 数字和符号干扰
- 删除混入的股市数字、时间戳、坐标信息
- 删除无意义的符号串(如"△▲■●◆"等)
- 保留有意义的数字(如年份、统计数据、编号)
### 3. 水印和噪声过滤
- 识别并删除视频水印文字(通常会重复出现)
- 删除台标、角标文字
- 删除"NEWS"、"LIVE"等画面标识
- 保留解说者的自我介绍和频道名称(通常只在开头出现一次)
### 4. 标点符号补充
- 补充缺失的逗号、句号、问号、感叹号
- 修正错误的标点(如中英文标点混用)
- 对话部分使用引号或冒号标识
- 保持每条字幕1-2句话的长度
### 5. 专有名词校正
- 人名、地名、机构名:确保拼写准确
- 影视作品名:使用书名号《》
- 品牌、产品名:保持官方标准写法
- 外来语音译:统一译法(如"WiFi"不写成"wife")
### 6. 语义通顺性检查
- 根据上下文修正语句不通顺的地方
- 补充缺失的主语、谓语、宾语
- 修正时态、语态错误
- 保持原有的语言风格(口语化/书面化)
- 对于俚语、网络用语,如果符合语境则保留
### 7. 时间轴完整性
- 保持SRT格式不变(序号、时间轴、字幕文本、空行)
- 不要修改时间戳
- 如果某条字幕完全是噪声或重复水印,可以删除整条
- 删除后重新编号,保持序号连续
## 第三步:输出修正结果
输出格式要求:
1. 完整的修正后SRT文件内容
2. 在文件末尾添加校对说明(以"# "开头的注释)
校对说明应包括:
- 主要修正的错误类型和数量
- 删除的水印/噪声内容
- 无法确定的疑问项(标注行号)
- 建议人工复核的部分
## 修正示例
**修正前:**
8
00:00:50,000 --> 00:00:55,000
子 其会长东出近些年开疆拓,兼并了系列有影响的帮派
9
00:00:55,000 --> 00:01:00,000
13,245.68△133.243,011.93▲12.27个2,096.219.7 电影刚开始,会长卷入到系列诉讼中
**修正后:**
8
00:00:50,000 --> 00:00:55,000
石东出会长近些年开疆拓土,兼并了一系列有影响力的帮派。
9
00:00:55,000 --> 00:01:00,000
电影刚开始,会长卷入到一系列诉讼中。
## 注意事项
1. **保持原意**:修正错误但不改变原始表达意思
2. **尊重风格**:不要将口语化内容改成书面语
3. **谨慎删除**:只删除明确的噪声,有疑问的保留
4. **标注疑问**:无法确定的地方在注释中说明
5. **完整输出**:输出完整的SRT文件,不要省略任何部分
---
现在请开始校对以下字幕内容:
[在此处粘贴SRT文件内容]
```
---
## 六、参数调优建议
### 6.1 抽帧间隔调整
- **5秒**(默认):适合大部分场景,速度快
- **3秒**:字幕切换频繁时使用
- **2秒**:追求高精度,但处理时间翻倍
**调整方法**:修改脚本中的 `FRAME_INTERVAL` 参数或环境变量
### 6.2 裁剪区域调整
- **底部1/4**(默认):适合标准字幕位置
- **底部1/3**:字幕位置偏上时使用
- **自定义区域**:双语字幕或特殊布局
**调整方法**:修改FFmpeg的 `crop` 参数,格式为 `crop=宽:高:x:y`
### 6.3 相似度阈值调整
- **0.8**(默认):平衡去重和保留
- **0.9**:字幕变化频繁,减少误合并
- **0.7**:字幕重复多,加强去重
**调整方法**:修改脚本中的 `SIMILARITY_THRESHOLD` 参数
### 6.4 并发线程数
- **8线程**(默认):适合大部分情况
**调整方法**:修改脚本中的 `MAX_WORKERS` 参数或环境变量
---
## 七、脚本速度实测
脚本源码:
30分钟视频大约需要108秒的提取时间,其中抽帧是在本地进行的,默认固定间隔(默认5秒),如果觉得字幕偏移太大可以改成3秒或两秒。
**注意**:提取后一定要用"通用OCR字幕校对提示词"再做一轮校对,不然字幕OCR识别错误会很严重。

---
## 八、常见问题排查
### 8.1 识别效果差
**问题表现**:
- 字幕缺失:部分字幕没有被识别出来
- 识别错误多:大量形近字误识、乱码
- 广告水印多:过滤不干净
**解决方案**:
- **字幕缺失** → 减小抽帧间隔(5秒→3秒)
- **识别错误多** → 检查画面清晰度,调整裁剪区域
- **广告水印多** → 调整黑名单阈值(5%→3%)
### 8.2 时间轴错位
**问题表现**:
- 整体偏移:所有字幕时间都不对
- 局部错位:部分字幕时间不准
**解决方案**:
- **整体偏移** → 检查第一帧时间计算(应从0秒开始)
- **局部错位** → 减小抽帧间隔提高精度
### 8.3 API调用失败
**问题表现**:
- 超时错误:请求超过300秒
- 连接失败:无法连接到算力舱
- 返回错误:API返回4xx/5xx错误
**解决方案**:
- **超时** → 增加timeout参数(300→600)
- **连接失败** → 确保打开懒猫微服和算力舱,检查算力舱网络连通性,确认API地址正确
- **返回错误** → 查看响应内容,检查图片格式和参数配置
### 8.4 处理速度慢
**问题表现**:
- 抽帧慢:FFmpeg处理时间长
- OCR慢:API调用耗时长
- 整体慢:总处理时间超出预期
**解决方案**:
- **抽帧慢** → 检查FFmpeg是否正确安装,视频编码是否支持,抽帧是在本地电脑进行的
- **OCR慢** → 增加并发线程数(8→16)
- **整体慢** → 增大抽帧间隔(5秒→10秒)或降低图片分辨率
评论
0暂无评论