From 4a6839319ae74b74611130227e507b860f672593 Mon Sep 17 00:00:00 2001 From: whale-fall-code <1690628247@qq.com> Date: Mon, 28 Sep 2026 16:09:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cos.yaml | 16 + README.md | 215 ++ config/2026-08.lnk | Bin 0 -> 840 bytes config/__init__.py | 0 config/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 155 bytes .../__pycache__/config_utils.cpython-311.pyc | Bin 0 -> 8566 bytes config/config.json | 113 + config/config_utils.py | 131 ++ coscli-linux-amd64 | Bin 0 -> 14100549 bytes main.py | 628 +++++ pyproject.toml | 31 + requirements.txt | 23 + run_worker.py | 394 ++++ scripts/apply_update.sh | 167 ++ scripts/benchmark.sh | 108 + scripts/build_bundle.sh | 48 + scripts/deploy.sh | 75 + scripts/diag.sh | 152 ++ scripts/make_portable.sh | 127 ++ scripts/monitor.sh | 33 + scripts/pack.sh | 84 + scripts/set_ffmpeg.sh | 26 + scripts/setup_server.sh | 244 ++ scripts/stop.sh | 52 + scripts/启动.sh | 164 ++ scripts/守护重启.sh | 121 + tool/Ocr/__init__.py | 0 tool/Ocr/tencentcloud_ocr.py | 372 +++ tool/VideoProcessing/__init__.py | 0 tool/VideoProcessing/multithread_algo.py | 480 ++++ tool/__init__.py | 0 tool/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 153 bytes tool/__pycache__/job_cos.cpython-311.pyc | Bin 0 -> 56633 bytes tool/getsrt.py | 2024 +++++++++++++++++ tool/job_cos.py | 814 +++++++ tool/log/__init__.py | 0 tool/log/log_manager.py | 218 ++ tool/merge.py | 885 +++++++ tool/process.py | 471 ++++ tool/whisper_manager.py | 227 ++ tools/_dl.py | 36 + tools/analyze_ocr_result.py | 100 + tools/bench_ocr_endpoints.py | 463 ++++ tools/check_srt.py | 117 + tools/compare_jsonl.py | 157 ++ tools/daily_stats.py | 99 + tools/download_srt.py | 96 + tools/extract_errors.py | 69 + tools/fleet_monitor.py | 316 +++ tools/gen_test_srt.py | 47 + tools/hourly_stats.py | 174 ++ tools/patch_config.py | 142 ++ tools/release_machine.py | 41 + tools/rerun_srt.py | 99 + tools/seed_jobs.py | 89 + tools/split_txt.py | 30 + tools/stats_jsonl.py | 73 + tools/test_ocr.py | 117 + tools/throughput_jsonl.py | 159 ++ tools/upload_composites.py | 91 + tools/upload_daily.py | 35 + tools/upload_data_standalone.py | 207 ++ tools/video_bench.py | 150 ++ tools/回溯过滤.py | 128 ++ tools/导出成功xlsx.py | 74 + tools/拆分超长.py | 92 + tools/查合成图尺寸.py | 93 + tools/查端点存活.py | 147 ++ tools/检查srt质量.py | 111 + tools/看OCR分布.py | 92 + 常用命令.txt | 57 + 71 files changed, 12144 insertions(+) create mode 100644 .cos.yaml create mode 100644 README.md create mode 100644 config/2026-08.lnk create mode 100644 config/__init__.py create mode 100644 config/__pycache__/__init__.cpython-311.pyc create mode 100644 config/__pycache__/config_utils.cpython-311.pyc create mode 100644 config/config.json create mode 100644 config/config_utils.py create mode 100644 coscli-linux-amd64 create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100644 run_worker.py create mode 100644 scripts/apply_update.sh create mode 100644 scripts/benchmark.sh create mode 100644 scripts/build_bundle.sh create mode 100644 scripts/deploy.sh create mode 100644 scripts/diag.sh create mode 100644 scripts/make_portable.sh create mode 100644 scripts/monitor.sh create mode 100644 scripts/pack.sh create mode 100644 scripts/set_ffmpeg.sh create mode 100644 scripts/setup_server.sh create mode 100644 scripts/stop.sh create mode 100644 scripts/启动.sh create mode 100644 scripts/守护重启.sh create mode 100644 tool/Ocr/__init__.py create mode 100644 tool/Ocr/tencentcloud_ocr.py create mode 100644 tool/VideoProcessing/__init__.py create mode 100644 tool/VideoProcessing/multithread_algo.py create mode 100644 tool/__init__.py create mode 100644 tool/__pycache__/__init__.cpython-311.pyc create mode 100644 tool/__pycache__/job_cos.cpython-311.pyc create mode 100644 tool/getsrt.py create mode 100644 tool/job_cos.py create mode 100644 tool/log/__init__.py create mode 100644 tool/log/log_manager.py create mode 100644 tool/merge.py create mode 100644 tool/process.py create mode 100644 tool/whisper_manager.py create mode 100644 tools/_dl.py create mode 100644 tools/analyze_ocr_result.py create mode 100644 tools/bench_ocr_endpoints.py create mode 100644 tools/check_srt.py create mode 100644 tools/compare_jsonl.py create mode 100644 tools/daily_stats.py create mode 100644 tools/download_srt.py create mode 100644 tools/extract_errors.py create mode 100644 tools/fleet_monitor.py create mode 100644 tools/gen_test_srt.py create mode 100644 tools/hourly_stats.py create mode 100644 tools/patch_config.py create mode 100644 tools/release_machine.py create mode 100644 tools/rerun_srt.py create mode 100644 tools/seed_jobs.py create mode 100644 tools/split_txt.py create mode 100644 tools/stats_jsonl.py create mode 100644 tools/test_ocr.py create mode 100644 tools/throughput_jsonl.py create mode 100644 tools/upload_composites.py create mode 100644 tools/upload_daily.py create mode 100644 tools/upload_data_standalone.py create mode 100644 tools/video_bench.py create mode 100644 tools/回溯过滤.py create mode 100644 tools/导出成功xlsx.py create mode 100644 tools/拆分超长.py create mode 100644 tools/查合成图尺寸.py create mode 100644 tools/查端点存活.py create mode 100644 tools/检查srt质量.py create mode 100644 tools/看OCR分布.py create mode 100644 常用命令.txt diff --git a/.cos.yaml b/.cos.yaml new file mode 100644 index 0000000..a94c6f1 --- /dev/null +++ b/.cos.yaml @@ -0,0 +1,16 @@ +cos: + base: + secretid: + secretkey: + sessiontoken: + protocol: https + mode: "" + cvmrolename: "" + closeautoswitchhost: "" + disableencryption: "" + buckets: + - name: + alias: + region: "" + endpoint: + ofs: false diff --git a/README.md b/README.md new file mode 100644 index 0000000..d750efb --- /dev/null +++ b/README.md @@ -0,0 +1,215 @@ +# OCR Data - 视频字幕提取与识别系统 + +## 项目简介 + +本项目是一个自动化视频字幕提取系统,通过视频抽帧、OCR 文字识别、音频语音识别等技术,从视频中提取硬字幕并生成 SRT 字幕文件。支持多线程批量处理,并与腾讯云 COS 对象存储集成(上传/下载)。 + +OCR 主力来自内部 OCR 服务(Tencent Youtu,封装为 `tencentcloud_ocr_api`);Whisper 仅做辅助校验(识别首尾音频过滤片头片尾台标、与 OCR 文本做拼音匹配),不是字幕文字的主要来源,因此 Whisper 模型大小对最终字幕质量影响有限。 + +## 核心功能 + +- **视频抽帧**:用 FFmpeg `fps` 滤镜单次顺序解码,按固定频率抽帧(默认每秒 3 帧) +- **字幕区域检测**:通过 OCR 自动定位字幕区域,识别/过滤水印 +- **图片拼接优化**:将多帧字幕区域裁剪后拼接为大图,大幅减少 OCR 调用次数 +- **并发 OCR**:getsrt 阶段对拼接图/单独帧并发调用 OCR(`subtitle.ocr_workers` 控制并发数) +- **音频辅助校验**:用 Whisper 提取首尾音频文字,与 OCR 结果做拼音匹配 +- **SRT 字幕生成**:合并、去重(处理多种 OCR 差异变体),生成标准 SRT +- **批量处理**:`ThreadPoolExecutor` 多视频并发;日志/计时按线程隔离 +- **运行统计**:每个视频的起止时间、各阶段耗时、图片处理数量写入 `数据.jsonl` + +## 项目结构 + +``` +ocr_data/ +├── main.py # 主入口,批量任务调度 +├── rerun_srt.py # 复用已有OCR数据重生成SRT(调试getsrt用,不重抽帧) +├── requirements.txt # Python 依赖 +├── coscli.exe / coscli-linux-amd64 # 腾讯云 COS CLI 工具 +├── config/ +│ ├── config.json # 配置文件(OCR密钥、抽帧参数、模型、并发等) +│ └── config_utils.py # 配置管理器(单例) +├── tool/ +│ ├── process.py # 单视频处理流程 +│ ├── merge.py # 图片拼接、字幕区域检测、音频文字提取 +│ ├── getsrt.py # OCR解析、字幕定位、去重、SRT生成(含并发OCR) +│ ├── whisper_manager.py # Whisper 管理器(线程安全单例) +│ ├── Ocr/tencentcloud_ocr.py # OCR API 封装(内部Youtu服务) +│ ├── VideoProcessing/multithread_algo.py # FFmpeg 抽帧 +│ └── log/log_manager.py # 统一日志管理器(每视频状态线程本地) +└── video/ # 视频文件存放目录 +``` + +## 处理流程 + +``` +1. 从 COS 下载视频(可选) + ↓ +2. FFmpeg 抽帧(每秒 3 帧,fps=3.0 精确) + ↓ +3. OCR 检测字幕区域 & 水印过滤 + ↓ +4. 字幕区域裁剪 & 多帧拼接为大图 + ↓ +5. 对拼接图/单独帧并发调用 OCR + ↓ +6. Whisper 提取首尾音频文字(辅助校验) + ↓ +7. 字幕定位 & 文本质量评估 & 相似帧合并去重 + ↓ +8. 生成 SRT 字幕文件 + ↓ +9. 上传结果到 COS & 记录元数据/运行统计 +``` + +## 环境要求 + +- Python 3.10+ +- FFmpeg(`ffmpeg` + `ffprobe`,**抽帧和音频都依赖**,需加入 PATH) +- coscli(COS 命令行工具,配置 `coscli_path`) +- CUDA(可选,Whisper GPU 加速) + +## 安装依赖 + +```bash +pip install -r requirements.txt +``` + +Linux 上若 `numpy`/`scikit-learn`/`av` 卡在源码编译(PyAV 编译需系统 ffmpeg 开发库),强制用预编译 wheel: + +```bash +pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --only-binary=av,numpy,scikit-learn +``` + +首次运行会从 HuggingFace 下载 Whisper 模型;国内建议先设镜像: + +```bash +export HF_ENDPOINT=https://hf-mirror.com +``` + +## 配置说明 + +编辑 `config/config.json`: + +```json +{ + "tencentcloud": { + "ocr": { "secret_id": "...", "secret_key": "...", "endpoints": ["http://IP1:PORT", "http://IP2:PORT"] }, + "cos": { "secret_id": "...", "secret_key": "...", "region": "ap-chongqing", "bucket": "..." } + }, + "audio": { "model_size": "small" }, + "splitframe": { + "interval_seconds": 0.33, + "download": true, + "upload_path": "cos://your-bucket/path", + "delete_video": false, + "coscli_path": "./coscli-linux-amd64", + "cosconfig_path": ".cos.yaml" + }, + "subtitle": { + "min_confidence": 50, + "similarity_threshold": 0.7, + "ocr_workers": 10 + } +} +``` + +### 配置项说明 + +| 配置项 | 说明 | +|--------|------| +| `tencentcloud.ocr.{secret_id,secret_key}` | OCR 服务凭证 | +| `tencentcloud.ocr.endpoints` | OCR 服务 IP 列表(多个时按 QPS 加权分发,失败自动摘除重试);不填回退到内置单端点 | +| `tencentcloud.cos.{secret_id,secret_key,region,bucket}` | COS 凭证与桶信息 | +| `audio.model_size` | Whisper 模型:`tiny`/`base`/`small`/`medium`/`large-v3`,默认 `small` | +| `splitframe.interval_seconds` | 抽帧间隔,`0.33` 表示每秒 3 帧 | +| `splitframe.download` | 是否从 COS 下载视频 | +| `splitframe.delete_video` | 处理完是否删除本地视频 | +| `splitframe.coscli_path` / `cosconfig_path` | coscli 路径 / COS 配置文件 | +| `subtitle.min_confidence` | OCR 最低置信度阈值 | +| `subtitle.similarity_threshold` | 文本相似度阈值 | +| `subtitle.ocr_workers` | getsrt 阶段 OCR 并发线程数(默认 10) | + +## 使用方法 + +### 批量处理 + +```bash +python main.py --source-list ./text2 --max-workers 10 +``` + +### 命令行参数 + +| 参数 | 默认值 | 说明 | +|------|--------|------| +| `--source-list` | `./text2` | 任务 txt 文件所在目录 | +| `--max-workers` | 自动(按本机CPU核数) | 最大并发数;不填/传0则自动选(若本机IP在 `tencentcloud.ocr.endpoints` 里,判定为OCR共置机,自动打对折让资源;再按可用磁盘÷每视频预估占用(`dispatch.est_disk_gb_per_video`,默认2G)收紧一次,两者取小;最后还有个硬上限30,超高核数机器也不会自动选出离谱的并发数) | +| `--mem-guard-gb` | `2.0` | 可用内存低于此值(GB)时暂停启动新视频,防 OOM;设 `0` 关闭 | +| `--disk-guard-gb` | `10.0` | 本地磁盘可用空间低于此值(GB)时暂停启动新视频,给下载/抽帧/合成图预留空间,防止磁盘写满导致级联失败;设 `0` 关闭 | + +启动时会打印一行机器资源(CPU 核数 / 可用内存 / 可用磁盘 / 负载)与当前并发设置,并对不合理的参数(内存/磁盘阈值过高、并发数过大/过小)给出告警,便于跑前判断。内存保护仅在 Linux 生效(读 `/proc/meminfo` 的 `MemAvailable`);磁盘保护跨平台(`shutil.disk_usage`)。机器无 swap 时内存保护尤其重要——可用内存触底会被暂停而非被 OOM 杀进程。 + +### 任务列表格式 + +在 `--source-list` 目录下创建 `.txt` 文件,**每行一个完整的 COS 路径**(上传目标目录由该路径自动推导,无需 `--cos-target`): + +``` +cos://bucket/0004/data/XXX/XXX_p1/XXX_p1.mp4 +cos://bucket/0004/data/XXX/XXX_p2/XXX_p2.mp4 +``` + +每个 txt 处理完会被删除;主循环持续监控目录直到没有 txt。**跨运行续传/去重**通过读取 `数据.jsonl` 的 `video_cos_path` 实现(不依赖 `./success/`)。 + +### 压测 OCR 端点 / 多 IP 负载均衡 + +OCR 服务有多个 IP 时,先压测每个 IP 的实际 QPS,运行时按 QPS 加权把请求分发到不同 IP: + +```bash +# 1) 在 config.json 的 tencentcloud.ocr.endpoints 填上所有 IP +# 2) 压测各端点 QPS,结果写入 config/ocr_weights.json +python bench_ocr_endpoints.py [样例图片] --requests 60 --concurrency 10 +# 3) 之后正常跑 main.py,OCR 请求会按权重自动分发;某端点连续失败会被冷却摘除并换端点重试 +``` + +不跑压测时,所有端点等权轮询;压测产出的 `config/ocr_weights.json` 存在则按 QPS 加权(错误率>50% 的端点权重置 0,不参与分发)。 + +### 调试 SRT 逻辑 + +```bash +python tools/rerun_srt.py ./split//composite +``` + +复用已有 `ocr_result.jsonl` 重生成 SRT,不重新调用 OCR,用于快速迭代 `getsrt.py` 的去重/合并/时间轴逻辑。注意它**不重新抽帧**,无法验证抽帧相关改动。composite 目录现在处理完就随 `split_dir` 一起删了(不再上传/保留到 `./composite/`),所以这条命令只在处理还没走完清理那一步之前有效——比如直接 `import tool.process` 调用 `process_single_video()` 单独调试时(这条路径不经过 `main.py`/`run_worker.py` 的清理逻辑)。 + +## 输出说明 + +`