feat(kb-workflow): 切换为 Whisper 语音识别

- 将步骤5从 OCR 改为 Whisper 语音识别
- 更新 kb-whisper 支持自动音频转换
- 默认使用中文语言 (zh) 和 base 模型
- 更新输出格式为 {platform}_{id}.txt/.srt/.json
- 添加 FunASR 作为备用方案
This commit is contained in:
2026-02-13 09:04:27 +08:00
parent 9102a973cd
commit 29dd236bb9
7 changed files with 844 additions and 155 deletions
+11 -12
View File
@@ -108,28 +108,28 @@ python3 /path/to/bilibili_content.py --id "[ID]" --type subtitle --output [subti
3. 解析输出 JSON,提取 video_filename 和 subtitle_filename(如有)
### 步骤 5: OCR 处理(禁止跳过)
### 步骤 5: 语音识别转文字(禁止跳过)
> ⚠️ **重要**:此步骤为耗时步骤,视频按帧截取和 OCR 识别需要较长时间。
> - **严禁跳过**:即使等待时间较长,也必须等待 OCR 完成
> - **定时汇报**:每2-3分钟向用户汇报进度(处理帧数/预计剩余时间)
> ⚠️ **重要**:此步骤为耗时步骤,使用 Whisper 进行语音识别。
> - **严禁跳过**:即使等待时间较长,也必须等待识别完成
> - **定时汇报**:每2-3分钟向用户汇报进度
> - **超时时间**:30分钟
> - **耐心等待**:不要中途启动其他步骤,必须串行执行
如果步骤4没有获取到字幕,需要从视频截帧 OCR:
如果步骤4没有获取到字幕,需要使用 Whisper 进行语音识别:
1. 获取目录路径:
```bash
python3 kb_workflow.py --content
```
2. 启动子代理调用 kb-ocr-processor(传入完整路径):
2. 启动子代理调用 kb-whisper(传入完整路径):
```bash
# 必须传入 --output 完整路径
python3 /path/to/ocr_processor.py --video [video_path] --output [content_dir]/ocr.json --merge
python3 /path/to/whisper.py --input [video_path] --model base --output [content_dir]
```
3. 等待 OCR 完成(定时汇报进度)
3. 等待 Whisper 完成(定时汇报进度)
4. 解析输出 JSON,生成 content 文件供步骤6使用
@@ -173,7 +173,7 @@ python3 kb_workflow.py --archive-file "[分析报告文件路径]"
| 3 | kb-bilibili-metadata | `--id "BVxxx" --type video` | `{p}_{id}.meta.json` |
| 3 | kb-zhihu-metadata | `--id "xxx" --type question` | `{p}_{id}.meta.json` |
| 4 | kb-bilibili-content | `--id "BVxxx" --type video` | `{p}_{id}.{ext}` |
| 5 | kb-ocr-processor | `--video xxx.flv --output ocr.json` | `ocr.json`, `ocr.txt` |
| 5 | kb-whisper | `--input xxx.mp4 --model base` | `{p}_{id}.json`, `{p}_{id}.txt` |
| 6 | kb-deep-analyzer | `--metadata x.meta.json --content x.json --output x.md` | `{p}_{id}.md` |
## 目录结构
@@ -189,9 +189,8 @@ python3 kb_workflow.py --archive-file "[分析报告文件路径]"
├── content/
│ ├── downloads/
│ │ └── {platform}_{id}.mp4
│ ├── subtitles/
│ │ └── {platform}_{id}.srt
│ └── {platform}_{id}.txt
│ ├── {platform}_{id}.txt # Whisper 识别的文本
│ └── {platform}_{id}.json # Whisper 完整结果
└── analyzed/
└── {platform}_{id}.md
```
-5
View File
@@ -67,7 +67,6 @@ def ensure_directories(base_path: Path = None) -> Dict[str, Path]:
"metadata": base_path / "metadata",
"content": base_path / "content",
"content_downloads": base_path / "content" / "downloads",
"content_subtitles": base_path / "content" / "subtitles",
"analyzed": base_path / "analyzed",
"archive": base_path / "archive",
"archive_subscriptions": base_path / "archive" / "subscriptions",
@@ -250,7 +249,6 @@ def main():
parser.add_argument('--metadata', action='store_true', help='获取元数据目录')
parser.add_argument('--content', action='store_true', help='获取内容目录')
parser.add_argument('--content_downloads', action='store_true', help='获取主内容下载目录')
parser.add_argument('--content_subtitles', action='store_true', help='获取字幕目录')
parser.add_argument('--analyzed', action='store_true', help='获取深度分析目录')
parser.add_argument('--archive_dir', action='store_true', help='获取归档目录')
parser.add_argument('--archive_subscriptions', action='store_true', help='获取订阅信息目录')
@@ -280,9 +278,6 @@ def main():
elif args.content_downloads:
print(json.dumps({"path": str(dirs["content_downloads"])}, ensure_ascii=False, indent=2))
elif args.content_subtitles:
print(json.dumps({"path": str(dirs["content_subtitles"])}, ensure_ascii=False, indent=2))
elif args.analyzed:
print(json.dumps({"path": str(dirs["analyzed"])}, ensure_ascii=False, indent=2))