Files
tps-dashboard/doco/note/doco_P1_完工快照.md
T
simonkoson 1372600d71 doco P3-C2: 讯飞ASR适配层接入 + 修复 doco/programs 忽略规则
- C2: asr_adapter 并入讯飞上传/轮询/解析,复用 extract_audio 分离音频,
  新增 doco asr 命令读 C1 热词;真转写 ep001 出 310 句带时间戳
- 补提交 C1 代码(llm.py / term_extract.py)与累积词典
- .gitignore: 挡 doco/programs 下 png/wav/mp4 及中间帧目录、本地 settings

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-17 10:19:08 +08:00

7.1 KiB

Doco 子项目 · P1 完工快照 · 交接给 P2(OCR 阶段)

起草:Opus 顾问(本对话) 日期:2026-06-15 用户:制片人刘通(《军事科技》栏目 TPS 中台主理人) 上一份:doco_handoff_to_next_chat.md(P1 调试中,bug 未解) 状态:P1 dry-run 已通过自检与人工验收,P1 完工


一、一句话总结

P1(视频双路拆分预处理)的抽帧→空白过滤→去重→关键帧流水线已跑通并通过全部验收,可进入 OCR 阶段。OCR 选型方向已更正为本地部署 DeepSeek-OCR(经 Ollama)


二、P1 做了什么

  • 输入:一期节目视频(黑底白字字幕 + 干净人声)+ A 稿
  • 本阶段产物:frames/(308 张字幕关键帧)+ keyframes 数据;音轨/B 稿是后续阶段
  • 流程:ffmpeg 抽帧(1fps,crop 到下方 20% 全宽)→ 空白帧过滤 → dHash + IoU 去重 → 关键帧
  • demo 视频:《现代防空反导大对决》(26 分钟)

三、本轮修复的 3 个 bug(都已修好、已验收)

交接前的核心卡点是「is_blank_frame() 读的图 ≠ frames/ 里的图」,自检反复中止。逐层挖下去,实际是三个独立 bug:

bug 1 · off-by-one 索引错位(核心)

  • 根因:extract_frames()enumerate() 从 0 开始编号(frame_index 0-based),但下游清理逻辑和自检逻辑都从文件名提取 1-based 编号(frame_0008.png → 8),两套编号差 1。
  • 后果:空白帧因编号错位被错误保留;自检重读图片取到正确像素,却去查 CSV 错误的行 → 报告不一致、中止。
  • 不是"读了不同目录的图"——所有判断函数始终从同一个 frames/ 读图,是编号体系不一致。
  • 修复:改为直接从文件名提取 1-based 编号。commit bc5a30e

bug 2 · 去重计数器恒为 0

  • 根因:decision_stats[...] = decision_stats.get(..., 0) 缺了 + 1,每次迭代没递增。
  • 后果:统计永远显示"筛掉 0 张 IoU + 0 张哈希",看起来像去重没生效。但去重逻辑本身一直是对的,只是计数显示错。
  • 修复:加 + 1。commit d55f029

bug 3 · 2 个失败的单元测试(均与本次修改无关的旧断言问题)

  • test_subtitle_frame:切片比例写错(注释说 1% 实际取了 10%),修改前就在失败。改 arr[:100,:10]arr[:10,:10]
  • test_ratio_ok_but_max_brightness_too_low:亮度阈值从 200→240 后,亮度 220 的像素不再算白像素,旧断言没同步。改断言为 white_ratio == 0.0
  • 修复:commit 82973a7,17/17 全过。

四、验收数据(已核对,数字闭环)

本次 dry-run 全帧去向(1620 帧):

类别 张数
空白帧(blank) 227
IoU 重复(duplicate-iou) 321
哈希重复(duplicate-hash) 764
首帧保留(kept) 1
关键帧(keyframe-hash) 307
合计 1620
  • 最终关键帧 = 1 + 307 = 308 张,与 frames/ 实际文件数一致。
  • 旁证:demo 这期约 300 条字幕,关键帧 308 ≈ 字幕数,基本一对一,说明去重准确(每条字幕保留一张、砍掉重复画面)。
  • 人工验收:制片人手动翻遍 frames/,确认无任何纯黑帧。
  • 单元测试:17/17 通过。

五、遗留小尾巴(不影响完工,有空再收)

  • test_ratio_ok_but_max_brightness_too_low 这个测试名与它现在实际测的行为对不上了(白像素阈值提到 240 后,原本想测的"白像素够但亮度不够"场景已构造不出来,断言被改成了 white_ratio==0)。建议以后让 Cline 给这个测试改名或重构。纯属测试整洁度,不影响流水线正确性。

六、重要更正 · OCR 选型(覆盖 PRD v2 的 Q1 表述)

PRD v2 写的"DeepSeek 有 OCR 模型 + Vision 识图模式(官方 API endpoint)"——这条事实有误,作废。

查证结果(2026-06-15,DeepSeek 官方文档):

  • DeepSeek 官方 API 只有 deepseek-v4-flash / deepseek-v4-pro 两个模型,纯文本,不收图像输入(功能仅:文本对话 / Tool Calls / JSON 输出 / FIM)。Cline 里 DeepSeek 预设没有 image 选项是正常的,不是配置漏项。
  • DeepSeek-OCR(3B,中文文档识别强)是开源模型,只能本地部署(vLLM 或 Ollama),没有现成云端 API,需自备 GPU。
  • 因此制片人手上的 DeepSeek API key 调不了 OCR

新方向(已与制片人确认):本地部署 DeepSeek-OCR,经 Ollama 运行。

  • 理由:制片人有 RTX 4090D 24GB(跑 3B OCR 模型富余);零调用成本、不限量;栏目全年 52 期常态化使用,长期划算;且制片人另有一个离线小机房,只能用本地方案,云端 API 调不通
  • Windows 上优先 Ollama(原生支持、免 WSL),不碰 vLLM(Windows 上一般要 WSL,门槛高)。

候选备选(若本地部署受阻):MiniMax-VL 云端 API、讯飞 OCR。但离线小机房只能本地。


七、下一步(P2 / OCR 阶段)

  1. 本地部署 DeepSeek-OCR(Ollama):在制片人栏目主机上搭起来,确认能识别黑底白字字幕关键帧;之后同样流程部署到离线小机房。
  2. OCR 适配层 ocr_adapter.py:把 308 张关键帧批量送入本地 OCR 服务,产出带 [Nm Ns] 时间戳的 B 稿 txt(格式必须与旧版完全一致,下游 P3 才零侵入)。
  3. 去掉 --dry-run,跑正式 OCR,产出 B 稿 + audio_16k.wav + keyframes.json,P1 整体产物齐活。
  4. 之后才进 P2 的讯飞 ASR 适配、P3 的 Claude 融合层。

八、关键决策(已锁,沿用)

字幕裁切区域 crop=iw:ih*0.2:0:ih*0.8(全宽 × 下方 20%),写死,全年 52 期一致
抽帧密度 1fps
哈希算法 dHash 阈值 5,pHash 阈值 2
IoU 保底阈值 0.95
空白帧双条件 max_brightness >= 240 AND white_pixel_ratio >= 0.005
凭证管理 doco 自管 doco/.env,主仓库根 docs/api_credentials_inventory.md 只记元信息
OCR 提供方 本地 DeepSeek-OCR(经 Ollama) ← 本次更正,原 PRD 的"DeepSeek 云端 Vision API"作废
ASR 提供方 讯飞录音文件转写标准版(P2 才用)
AI 融合层 Claude Sonnet 4.6(P3 才用)
抽帧/抽音轨 subprocess 调系统 ffmpeg,不引入 ffmpeg-python
Git workflow 按宪法直接推 main,不开分支

九、环境信息

  • Windows + Python 3.12.10 + .venv(主项目共享虚拟环境)
  • VS Code + Cline 插件(编程模型已从 Minimax M3 换为 deepseek-v4-pro,响应更快)
  • 仓库根:E:\tps-dashboard\(VS Code 必须打开仓库根,不能打开子目录)
  • 主仓库:simonkoson/tps-dashboard(自部署 git,localhost:3000)
  • ffmpeg:winget 安装,系统 PATH
  • GPU:NVIDIA RTX 4090 D 24GB(本地 OCR 部署用)
  • 另有一台离线小机房(无外网,本地部署的主要落地环境之一)
  • 正确 CLI:doco split --episode-id XXX --input-video XXX --output-dir XXX [--dry-run]

十、本轮 commit(按时间)

commit 内容
bc5a30e extract_frames:frame_index 从 0-based enumerate 改为 1-based 文件名提取(核心 bug)
d55f029 decision_stats 计数加 + 1(去重计数器恒为 0)
82973a7 修复 2 个测试断言(切片比例 + 阈值适配),17/17 通过

P1 至此完工。下一轮从「Ollama 本地部署 DeepSeek-OCR」开始。