在线视频培训纪要生成
把任意网站的在线视频培训课程,转换成一份排版合规、结构清晰的 Word 培训纪要。
四阶段流程:获取视频流 → 提取内容(字幕优先,无字幕转写)→ 整理纪要稿 → 生成 docx 并自验。
[课程页 URL] → 阶段1 取流(m3u8+密钥+分片,或 mp4 直链)
→ 阶段2 内容提取(transcript_secN.json,[mm:ss] text 同构格式)
→ 阶段3 整理(final_draft.md)
→ 阶段4 生成 docx(patch + 自验通过后交付)
阶段 1:视频获取
1.1 通用原则
- 优先复用浏览器自动化(browser-skill / bsk):登录态、动态 token、加密参数都在用户浏览器里。
- 动态取值,禁止硬编码:认证 token、密钥 URL 必须从当前页面运行时读取(如页面上下文执行 JS,从
axios.defaults.headers.common.Authorization提取)——硬编码上次会话的 token 必导致 403。 - 成对调用:多数平台取 m3u8 前须先请求一次 token 接口,再立刻请求 m3u8,两者间隔过长会失效;每节的 token→m3u8 必须紧接着完成。
- 先摸清课程结构:调课程信息接口(或解析页面 DOM)拿到课程名、讲师、发布时间、学时、各节名称与 resourceId/attachmentId,直接用于纪要的"课程基本信息"表。
- 数据只存页面 window 变量有丢失风险:session stop 或页面刷新都会清空——必须先回传完所有 window 变量再停会话(误停则重新取数,auth_tk 必须重新动态读取)。
1.2 标准取流步骤(HLS 加密流)
在浏览器会话内执行(全部通过 bsk evaluate,不写本地请求):
① 读认证头:AUTH = axios.defaults.headers.common.Authorization 中的 token
② 逐节循环:先 GET token 接口 → 再 fetch m3u8(带 AUTH 作为 auth_tk)
③ 取密钥:从 m3u8 的 EXT-X-KEY URI fetch 密钥字节,转 hex 记录
④ 分段回传:m3u8 文本按 ~18000 字符切片存入 window.__xfer 数组
⑤ 本地重组:循环 bsk evaluate window.__xfer[i] 取回,按 "节|块号|文本" 重组写入 secN.m3u8
⑥ 密钥落盘:key_all.bin 写入密钥 hex 的字节
⑦ 本地化:把 m3u8 中 EXT-X-KEY 的 URI 替换为本地 file:// 密钥路径,生成 secN_local.m3u8
1.3 分片下载与解密(脚本 scripts/extract_hls.py)
- 逐分片下载 → AES-128-CBC 解密(密钥=key_all.bin,IV 取 m3u8 的 IV,无 IV 用分片序号派生)→ 校验首字节 0x47(TS 同步字节)→ 拼接 → ffmpeg 提音频:
-vn -ac 1 -ar 16000 -b:a 64k(16kHz 单声道是 whisper 标准输入) - ffmpeg 位置:运行时按优先级探测
--ffmpeg 参数 > 系统临时目录 > shutil.which;未安装时按 compatibility 指引安装(macOS: brew install ffmpeg) - 解密失败排查:解密后首字节不是 0x47,几乎都是密钥不对——密钥可能按节分发或有时效,回 1.2 第③步重新取,逐节核对 key URL
1.4 降级路径
| 情形 | 处理 |
|---|---|
| m3u8 无加密(无 EXT-X-KEY) | 跳过解密,直接下载分片拼接 |
| 平台是 mp4 直链 | 直接下载,跳过 1.2/1.3 |
| bsk 不可用/扩展未连接 | 查 references/bsk故障处理速查.md;必要时请用户配合打开课程页 |
| 需要登录而用户未登录 | 暂停并请用户登录后继续,不要尝试绕过 |
| DRM(Widevine/FairPlay)硬加密 | 不处理,如实告知用户改用录屏+转写方案 |
阶段 2:内容提取(字幕优先)
判断顺序:先探测字幕,有则走快车道,没有才转写。 字幕文本比转写准确得多且省时一个数量级。详细操作见 references/字幕提取指南.md(探测清单、WebVTT/JSON 处理、字幕与转写的混合策略)。
字幕载体探测优先级:① HLS 内嵌字幕轨(m3u8 中 #EXT-X-MEDIA:TYPE=SUBTITLES)→ ② 平台字幕接口(Network 面板过滤 caption/subtitle/vtt)→ ③ 播放器 DOM(渲染型字幕须边播边采集,仅作兜底)。
字幕处理要点:滚动字幕去重(相邻 cue 重叠按时间戳合并);统一转成 [mm:ss] text 格式——与转写产物同构,后续阶段不感知来源;字幕同样可能有水印/广告行,按 2.3 清洗。
2.2 语音转写慢车道(无字幕时)
脚本 scripts/transcribe.py(mlx-whisper,Apple Silicon 约 30~40 倍速)。前提:模型 mlx-community/whisper-large-v3-turbo 已在本地 HF 缓存;转写用 HF_HUB_OFFLINE=1 离线模式避免代理干扰。本机无 mlx 时降级:faster-whisper(CPU)→ macOS Speech 框架(pyobjc)→ 都不可用则如实告知用户,询问是否改用在线 API(注意数据保密)。
initial_prompt 是质量关键:把课程主题、专业术语、法规名称、常见缩写拼成提示词传入,可显著减少同音字错误;每次整理完一节,把新发现的错词追加进提示词再转下一节。
2.3 转写稿清洗规则
- 片头片尾水印/广告幻觉:whisper 对静音/音乐段会产生幻觉文本,多为训练语料中流传的平台水印(社区已知例子如"请不吝点赞 订阅 转发 打赏支持明镜与点点栏目"、"优优独播剧场——YoYo Television Series Exclusive",以及各类"点赞订阅""字幕由 AI 生成"式文案)。按行过滤:命中已知水印模式(随实际处理课程持续积累)或单行内同一词重复 ≥8 次的行删除;第一行和最后 3 行单独人工审视
- 同音错别字校正:whisper 对专业术语必错。建立课程专属校正表(阶段 3 整理时同步维护,整理稿附注中注明已校正)。通用错词模式(按此思路结合课程领域扩展):专业专名(多音/生僻词被写成同音常用字,如行业术语、机构名、人名地名);英文缩写与音译(如技术名词被拆成汉字);数字与文号(反复对照上下文核实,不确定的保持原文并标注)
导出:[mm:ss] text 每行一条,文件名 transcript_secN.txt。
阶段 3:整理纪要稿
输入:transcript_secN.txt + 课程元信息。输出:final_draft.md。
3.1 通读与结构提炼
- 先完整通读全部转写稿再动笔——按 10 分钟左右区间采样阅读长稿,过滤单字重复幻觉行;按授课顺序组织章节,忠实反映授课脉络,不要自行重组
- 结构映射:
#大标题 →##章(第X章/课程基本信息/附注)→###节(一、二、)→####小节 - 数字与事实保真:法规名称用全称(首次出现附发文机关与文号)、金额/比例/时限/条款号逐一核对;讲师口头补充的"实务注意点"是纪要精华,必须保留
- 口语句转书面语:删填充词、长口语拆短句,但不改变讲师的原意与立场
- 篇幅参考:转写字数的 30%~40% 为合理区间——过短丢内容,过长是照抄口语句
3.2 固定结构与质量自检
# 《课程名称》培训纪要
## 课程基本信息
(表格:课程名称/讲师/课程来源/课程总时长与分节时长/整理依据/整理单位〔按用户落款填写〕)
## 第一章 …(按授课结构)
## 附注
(校正说明 + 免责:具体表述以正式文本为准;字幕来源写"依据课程视频字幕整理")
〔落款三行按用户实际要求:单位全称/部门整理/日期——build_html.py 按通用规则识别(末尾日期行+其前连续短行),不限定机构名〕
质量自检:每节 ≥3 分钟的内容都有对应章节;法规全称文号齐全;数字逐一核对;无水印残留;校正表与实际校正一致。
阶段 4:生成 docx 并自验
4.1 排版规范
唯一权威文件:references/排版规范-定稿范本v3.1.md(v3.2),生成前完整阅读。 核心要点:
- GB/T 9704-2012 公文风格:大标题方正小标宋二号居中(段前 13.2/段后 26.4 磅/行距 1.4 倍/缩进四项全零显式),一级标题黑体、二级标题楷体(均首行缩进 2 字符),正文仿宋三号两端对齐(1.5 倍行距、段后 2.4 磅)
- 缩进必须 firstLine 与 firstLineChars 双写(归零同样四项显式)
- 课程基本信息表三件套:
tblLayout=fixed+tblGrid=[2156,6444]+ 每格 tcW 显式交替(25.1%/74.9%)——只写 tblGrid 会被编辑器 autofit 重算回均分 50/50 - 表头黑体 16 磅、数据行仿宋 16 磅;表格内文字不缩进且水平居中;落款三行右对齐顶格;页脚"— N —";全文禁止真分页标记
4.2 生成步骤(脚本在 scripts/,勿重写)
① python3 scripts/build_html.py final_draft.md 输出.html # md→定稿排版 HTML
② ~/.venv-html-to-docx/bin/python -m html_to_docx convert 输出.html -o 纪要.docx
(venv 不存在时先跑插件 setup-html-to-docx.sh;首次需外网)
③ python3 scripts/patch_fanben.py 纪要.docx # XML 修补 + QA
(自动:Normal 408、H1 段级直设含缩进四项全零、H2/H3、附注、表格归零居中、
fontTable、真分页清零、首表列宽三件套;QA 输出全过才算完)
④ 按 references/排版规范-定稿范本v3.1.md 第八节自验清单核对
4.3 自验清单(不过不交付)
XML 层(patch 自动输出):真分页=0;br page=0、段内 sectPr=0;Normal line=408、H1 小标宋;表格缩进归零且居中;H1 段级直设 1/1(264/528/336/四项全零/居中);首表列宽 2156/6444(fixed+tblGrid+tcW 三件套)。
编辑器层(editor_sdk doc_get_paragraph_property 抽查):大标题 center/1.4/13.2/26.4/pt=0 且 chars=0.0/heading1;一级二级标题 1.5/10/0/2.0 字符;正文 1.5/2.4/both;落款 right/pt=0/0。
编辑器回写复查:文档经编辑器打开保存过(用户预览、人工微调)后,交付前 XML 复核首表三件套未被重算;被重算则重跑 patch_fanben.py。
常见错误与规避(历史教训)
| 坑 | 后果 | 规避 |
|---|---|---|
| 硬编码上一次会话的 token | 整批请求 403 | 认证值从页面运行时动态读取 |
| 先 session stop 再回传 window 数据 | 数据丢失重走全流程 | 先回传完再停会话 |
| ffmpeg 未安装或不在 PATH | FileNotFoundError | compatibility 有安装指引;脚本 shutil.which 自动探测 |
| 转写未清水印幻觉 / 不传 initial_prompt | 出现广告文本 / 同音字暴增 | 2.3 规则过滤 / 构造术语提示词 |
| patch 后不做编辑器层自验 | 用户又要人工调整 | 执行 4.3 全清单 |
| 大标题缩进只归零不写全 | 编辑器回显"缩进 2 字符" | 归零四项显式(patch 5c 已强制) |
| 表格列宽只写 tblGrid | 编辑器保存后重算回 50/50 | 列宽三件套(patch 已固化) |
| 修改代码在写 zip 之后执行 | 修改不落盘 | 改动 items 必须在写块之前 |
与其他技能的协作
- browser-skill(bsk):阶段 1 全部页面操作经它执行;故障先查
references/bsk故障处理速查.md - tencent-local-office-edit:编辑器层自验与人工微调保存
- html-to-docx 转换器来自 tencent-docx 插件(环境由 setup-html-to-docx.sh 准备)
技能资源清单
在线视频培训纪要生成(GUI 显示名,注册于 _skillhub_meta.json 的 name 字段;
SKILL.md 的 name 保持英文标识 training-video-minutes 以通过打包校验)
├── SKILL.md ← 本文件(四阶段流程 + 规避清单)
├── _skillhub_meta.json ← GUI 显示名注册
├── scripts/
│ ├── extract_hls.py ← 阶段1:分片下载+AES解密+提音
│ ├── transcribe.py ← 阶段2:mlx-whisper 转写
│ ├── build_html.py ← 阶段4:md→定稿 HTML
│ └── patch_fanben.py ← 阶段4:docx XML 排版修补 + QA
├── references/
│ ├── 排版规范-定稿范本v3.1.md ← 阶段4 唯一排版权威(含自验清单)
│ ├── 字幕提取指南.md ← 阶段2 快车道详细操作
│ └── bsk故障处理速查.md ← 阶段1 守护进程故障修复
└── assets/
└── 模板骨架.html ← 定稿排版 HTML 骨架