Releases: kizemo/media-to-doc
Release list
v1.3.0 — trust_env 全 provider 隔离 + 子仓 Tauri UI v1.3.0 协同发布
What's New in v1.3.0
🛡️ Defense in depth: LLM provider trust_env 全栈隔离
中国大陆 + 公司 VPN 用户跑 mtd run 时,父 shell 的 HTTP_PROXY 等环境变量被 httpx 默认行为拾取 → ollama / Anthropic / OpenAI-compatible 三个 provider 的 SDK 内部 httpx 走代理 → localhost 调用报 SSL unknown error(实际未连代理)。
修复(b283d64 / 427d963)
OllamaProvider / AnthropicProvider / OpenAICompatProvider 三个 provider 的 _ensure_client 全部显式构造 http_client=httpx.Client(trust_env=False),代码层消除 HTTP_PROXY 污染。配合 W13-C 脚本层子进程 env 过滤(HTTP_PROXY 等 8 个 vars),形成 defense in depth。
子项目 media-to-doc-ui 同步发布 v1.3.0(W14-C + W14-D C)
- 8 commands 等价对齐 MCP 8 工具
- 多课程并发(max_concurrent=3 + LRU 100 + 2s cancel)
- 5 tab SPA(Inbox / Run / Output / Health / Learn)
- NSIS installer + 便携版(setup.exe 1.5MB + portable.exe 6.2MB)
- 9 个 Tauri commands 全部实装
- GitHub Release: https://github.com/kizemo/media-to-doc-ui/releases/tag/v1.3.0
测试
- 604 pytest / 0 跳过(1.2.1 595 → 1.3.0 604,+9)
- 3 Ollama trust_env 透传
- 6 Anthropic + OpenAICompat trust_env 透传
- ruff: All checks passed
- W14-D E2E 端到端: 60s demo 视频 4m08s 跑通 + 8/8 Tauri commands 后端 API 验证
安装
uv pip install --upgrade media_to_doc==1.3.0
uv run mtd --version
# media-to-doc 1.3.0兼容性
- CLI / Python API / MCP server 行为不变
- 产物布局不变(
output/+output_final/分离 + 真视频名 + W12-D) - state.json / pipeline_run.json schema 不变
升级注意
- 重启 Python 进程(让 trust_env=False 生效)
- Tauri UI 用户无需重启 UI(command 内部 hardcode 重新构造 client)
完整变更
v1.2.1 — longdoc W12-D 3 级 fallback + fusion proxy fix
Release Notes — v1.2.1
Patch release — W13-B longdoc W12-D 兼容 + W13-C fusion proxy 隔离。
W13-A 真跑 01.mp4 端到端时撞出的两个 P1 bug,代码侧已修复并通过 595 测试。
🩹 修了什么
1. longdoc 找不到 W12-D 后的源讲义(W13-B)
症状
跑 v1.1.0+ 之后产生的讲义(<final_dir>/<video>.md)走 longdoc 阶段时,日志报
FileNotFoundError,实际自动 fallback 到拼装草稿章节 — 讲义质量隐性降级。
根因
process_long_doc 假设 W3-W11 旧布局:<work>/chapters/raw/<video>.md 是 render 阶段
已拼装好的讲义。W12-D 之后,render 改写到 <final_dir>/<video>.md,
原路径只放中间草稿目录(<video>/chapter_*.md),不再有单文件讲义。
修复
新增 _resolve_source_md(work, video, final_dir) helper,3 级 fallback:
<final_dir>/<video>.md— W12-D 真相位置,render 已拼装好的讲义(优先)<work>/chapters/raw/<video>.md— W3-W11 旧布局,向后兼容<work>/chapters/raw/<video>/chapter_*.md拼装 — W12-D 中间产物应急
process_long_doc 重构:target_dir 提前计算,作为 W12-D 查找位置。
2. merge_lectures ollama 子进程 SSL 错误(W13-C)
症状
公司 VPN 环境下,mtd merge --fusion ollama 实际走 fallback 硬切,LLM 融合
quality 隐性降级;merge_lectures 含 LLM 融合失败 warning 但日志不直观。
根因
_w13a_run_fusion.py 启动子进程时,父 shell 的 HTTP_PROXY 等 8 个 VPN proxy
环境变量泄漏到子进程 env,ollama SDK 的 httpx 走代理后报 SSL unknown error。
修复
子进程 env 显式剔除 8 个 proxy vars:
PROXY_VARS = (
"HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy",
"ALL_PROXY", "all_proxy", "NO_PROXY", "no_proxy",
)✅ 验证
- 595 pytest / 0 跳过 (1.2.0 575 → 1.2.1 595,+20):
- 13 longdoc W12-D 兼容测试(3 路径 + 集成 + fallback + 拼装)
- 7 既有 longdoc 测试不变,3 级 fallback 完全向后兼容
- ruff:All checks passed
- W13-A 真跑 01.mp4 验证:
_w13a_inbox/output_final/01_先精准后放大的打爆策略.md
→ longdoc source 自动选 W12-D 真讲义(+1.4% chars,含 TOC/摘要/要点/关键帧) - W13-C 重跑 fusion 验证:proxy 隔离后 7 H2 LLM 融合产物(此前 10 H2 是 fallback 硬切)
📦 升级方式
uv pip install --upgrade media_to_doc==1.2.1无需迁移脚本,新代码兼容旧产物;旧产物再次跑 mtd resume 会自动用新 3 级 fallback
找到正确的源讲义。
v1.2.0 — LLM-driven chapter fusion
Release Notes — v1.2.0
Minor release — LLM-driven chapter fusion(W12-E)。
按用户 2026-07-21 反馈,W12-D 硬切过于生硬,改 LLM 驱动的内容融合。
🎯 用户反馈与新流程
章节命名,应当根据内容,进行融合,而不是生硬地根据视频确定H1,
有可能一个视频的内容末尾,和另一个音视频开头的部分,应该归属于一个章节。
为了避免上下文超限,建议在融合前,为每个音视频都建立包含章节和简短摘要的简化版,
然后根据简化版,调用大模型优化融合后的章节结构。
3 阶段流程
- 简化版生成 —
chapters_summary()提取 H2 章节 + 前 800 字摘要(避免上下文超限) - LLM 融合规划 — 把所有视频的"章节+摘要"拼成 prompt,LLM 决定全局融合章节结构
- 按规划重组 —
apply_fusion_plan()按 LLM 输出重写 md,模糊匹配章节名,找不到降级引用提示
include 指令(LLM 控制原章节正文范围)
all— 引用全文(默认)first_n:N— 引用前 N 段summary— 仅引用提示,不搬正文(适合重复 / 收尾)
✨ 改动详情
新公开 API(media_to_doc.pipeline.merge_lectures)
chapters_summary(md_text, max_summary_chars=800, video_name="")— 提取简化版apply_fusion_plan(plan, source_mds, merged_name)— 按 LLM 规划重组_build_fusion_prompt(summaries)— 构造 fusion prompt(供调试 / 测试)_parse_fusion_plan(raw)— JSON 容错解析- 3 dataclass:
ChapterSummary/FusionSource/FusionChapter/FusionPlan
merge_lectures 新参数
fusion_provider: Any | None = None— None = 硬切(向后兼容)fusion_model: str = ""— fusion 模式下的 LLM 模型名fallback_on_error: bool = True— LLM 失败时降级硬切
CLI
mtd merge <output_final_dir> --fusion ollama [--fusion-model qwen3:14b]MCP
merge_lectures(output_final_dir, merged_name, no_html, fusion, fusion_model)fusion:"ollama" | "anthropic" | "openai_compatible"
兼容性
- 向后兼容:
fusion_provider=None走 v1.1.0 硬切路径,559 测试不破坏 - 新加 16 个测试:覆盖 fusion 全流程
- 端到端真 LLM fusion 实跑:qwen3:14b,29.5s,7 融合章节(原 14 个)
📊 验证
- 575 pytest 用例 / 0 跳过(1.1.0 559 → 1.2.0 575,+16)
- ruff:All checks passed
- PyPI:https://pypi.org/project/media_to_doc/(latest_version: 1.2.0)
📦 Install
uv pip install --upgrade media_to_doc==1.2.0或从 GitHub Release 下载 wheel:
https://github.com/kizemo/media-to-doc/releases/download/v1.2.0/media_to_doc-1.2.0-py3-none-any.whl
📝 Full Changelog
见 CHANGELOG.md。
v1.1.0 — Multi-video layout + merge
Release Notes — v1.1.0
Minor release — multi-video layout + merge(W12-D)。
按用户 2026-07-21 拍板的新规落地。
🎯 用户新规 3 条
- 中间 vs 最终产物分离:中间产物(ASR/frames/OCR/chapters/drafts/state) →
<video>.parent / output/;最终 md/html →<video>.parent / output_final/ - 真视频名:chapters.video + 最终文件名 = 真视频文件名(去后缀、去末尾空格)
- 多视频合并:新增
merge_lectures,文件名 = 第一个视频名(去除序号),章节重排,图片路径重写
✨ 主要改动
1. 中间 vs 最终产物分离
output/ ← 中间产物(11 stage 调度)
├── chapters/
│ ├── chapters.json
│ └── raw/<video>/chapter_NN.md
├── state.json
└── ... (其他 stage 产物)
output_final/ ← 最终产物(自包含、可整盘分发)
├── <真视频名>.md ← 拼装讲义 markdown
├── <真视频名>.html ← 渲染 HTML(含 v1.0.1 mermaid + tasklist 修复)
└── <真视频名>/
└── images/ ← AI 配图(从 drafts_dir/images/ 复制)
2. 真视频名派生
chapters.derive_video_name(inbox, target_video) — 从 inbox + target_video 派生
真视频文件名(去后缀、去末尾空格)。W10-A 跑出的 output.md 降级问题修复。
3. 多视频合并
# CLI
mtd merge <output_final_dir> [--name "培训综合"] [--no-html]
# MCP 工具
merge_lectures(output_final_dir, merged_name, no_html)
# Python API
from media_to_doc import merge_lectures
result = merge_lectures(Path("output_final"), merged_name="培训综合")合并规则:
- 文件名 = 第一个视频 stem 去除序号(
01_xxx→xxx) - 章节全局重排(
## 第一部分/## 第二部分...)+ H2 降级为 H3 - 图片路径重写到
<merged>/images/<original_stem>_<file>(避免多视频同名冲突) - 自然排序(数字按数值比较)
_cleaned.md优先,_merged后缀跳过自合
4. 兼容性策略
默认新规 + 旧产物只读兼容(gatekeeper / verify 优先 output_final/,
回退 output/chapters/raw/)。无需迁移脚本。
📊 验证
- 559 pytest 用例 / 0 跳过(1.0.1 539 → 1.1.0 559,+20 merge_lectures 测试)
- ruff:All checks passed
- PyPI:https://pypi.org/project/media_to_doc/(latest_version: 1.1.0)
📦 Install
uv pip install --upgrade media_to_doc==1.1.0或从 GitHub Release 下载 wheel:
https://github.com/kizemo/media-to-doc/releases/download/v1.1.0/media_to_doc-1.1.0-py3-none-any.whl
🔄 Migration from 1.0.x
新规默认开启,无需迁移脚本:
- 新跑:
mtd run <inbox>自动用output_final/新布局 - 旧产物:
gatekeeper / verify同时支持新旧路径回退读取,但新跑不会再写旧位置 - 手动迁移(可选):
cp output/chapters/raw/output.md output_final/<真视频名>.md
📝 Full Changelog
见 CHANGELOG.md。
v1.0.1 — Patch: mermaid + GFM tasklist HTML rendering
Release Notes — v1.0.1
Patch release — fix 2 HTML rendering regressions found during W11-C quality review.
🐛 Fixed
mermaid 流程图渲染
问题:cleaned.md 中的 ```mermaid 围栏在 v1.0.0 最终 HTML 里被渲染成
<pre><code class="language-mermaid">…</code></pre> 纯文本,浏览器看不到流程图。
修复:HTML 模板底部加 mermaid@10 CDN script + mermaid.initialize,
BeautifulSoup 后处理把 <pre><code class="language-mermaid"> 改造为
<pre class="mermaid">…</pre>,浏览器端自动识别并渲染。
GFM task list checkbox 渲染
问题:- [ ] xxx / - [x] xxx 在 v1.0.0 最终 HTML 里保持纯文本 [ ] xxx,
无法可视化清单状态。W11-C 风险控制清单(1. [ ] xxx)同样降级。
修复:BeautifulSoup 后处理遍历 <li>,把开头的 [ ] / [x] 替换为
<input type="checkbox" disabled>(checked 视原状态)。同时支持有序列表。
📊 验证
- W11-C 真产物复用:
E:/resource/2026-01-27_年度复训/output_cleaned.md
(107min 中文培训视频 / qwen3:14b LLM 净化)- 1 个 mermaid 流程图 →
<pre class="mermaid">flowchart TD…</pre>✅ - 5 条风险控制项 → 5 个
<input type="checkbox" disabled>✅ - 原文
[ ][x][X]残留:0 ✅
- 1 个 mermaid 流程图 →
- 539 pytest 用例 / 0 跳过(1.0.0 529 → 1.0.1 539,+10)
- ruff:All checks passed
📦 Install
uv pip install --upgrade media_to_doc==1.0.1或从 GitHub Release 下载 wheel:
https://github.com/kizemo/media-to-doc/releases/download/v1.0.1/media_to_doc-1.0.1-py3-none-any.whl
📝 Full Changelog
见 CHANGELOG.md。
v1.0.0 — First stable release
Release Notes — v1.0.0
把本地音视频一键转化为带 AI 配图、可独立分发的 Markdown + HTML 讲义。
Release date: 2026-07-20
Tags: v1.0.0
Python: 3.11 / 3.12 / 3.13 / 3.14
PyPI: https://pypi.org/project/media-to-doc/
License: MIT
Status: 🎉 First stable release
Install
# PyPI 装
uv pip install media_to_doc
# 或装全部功能依赖(~5GB: faster-whisper / scenedetect / rapidocr / diffusers 等)
uv pip install "media_to_doc[all]"
# 验证
mtd --version # media-to-doc 1.0.0TL;DR
media-to-doc 1.0.0 是首个 GA(Generally Available)发布。11 阶段流水线端到端跑通,3 种调用方式(CLI / Python API / MCP server),Loop Engineering 五层闭环全接入,529 测试 0 失败,W10-A 真端到端验证 107 分钟中文培训视频 3h57min 跑完。
What's New
11 阶段流水线(audio → ... → verify)
audio → asr → frames → ocr → asr_correct → chapters → draft → imagegen → render → longdoc → verify
audio:ffmpeg 抽音(wav/mp3/m4a 直接 copy 跳过转码)asr:Faster-Whisper large-v3(CPU fp16 / CUDA fp16)frames:PySceneDetect ContentDetector + pHash 去重ocr:RapidOCR(ONNX 本地推理)asr_correct:OCR × ASR 8s 滑动窗口校对chapters:LLM 切章节 + 标题/摘要/关键点/关键帧引用draft:LLM 按章节切片 + 双 prompt 草稿生成imagegen:SDXL Base + Refiner(可skip让 Claude 自己做配图)render:jinja2 + markdown 拼装讲义(TOC / 锚点 / 内嵌 CSS / dark mode / print stylesheet)longdoc:LLM 净化或规则清理(可skip)verify:4 项机器可验证(产物存在 / 章节完整 / 图像引用 / HTML 结构)
3 种调用方式(W6 / W7 / W9)
| 调用方式 | 入口 | 适用 |
|---|---|---|
| CLI | mtd run / resume / status / list / doctor / config / mcp |
终端用户 + CI |
| Python API | from media_to_doc import run_pipeline, get_run_metrics, ... |
嵌入其它项目,52 个公开符号,PEP 562 lazy import,启动 < 100ms |
| MCP Server | mtd-mcp (stdio JSON-RPC) |
Claude Desktop / Codex / Cline,8 工具(LIST / RUN / RESUME / CHECK / OUT / READ + W8 健康度) |
Loop Engineering 五层闭环(W8)
执行层 → 审核层 → 沉淀层 → 进化层 → 健康度
L1 L2 L3 L4 L5
- L1 执行:
timed_stage(logger, stage)包裹每 stage 写 LE L1 即时记忆 - L2 审核:
gatekeeper_check(work)4 项机器可验证,W11-A 修完后与 verify 一致 - L3 沉淀:
pipeline_run.json含llm_health/gatekeeper_passed/quality/errors - L4 进化:Pattern-Key 自动晋升到
.learnings/ERRORS.md(同 Pattern-Key ≥ 3 次触发) - L5 健康度:
assess_llm_health失败率 > 10% →switch_provider建议,> 20% →reduce_chunk建议
可分发的产物(CLAUDE.md §7)
讲义目录整盘复制 / 上传网盘 / 丢知识库,路径不失效:
output/我的培训/
├── output.md # 拼装讲义(相对路径图片)
├── output.html # 单文件 HTML(含 TOC / 锚点 / CSS)
├── output_cleaned.md # longdoc 净化后(可分发主版本)
├── output_final.html # longdoc 最终 HTML(TOC + dark mode + print)
├── chapters/ # 章节 JSON + 草稿
├── drafts/drafts.json # 配图 manifest
├── pipeline_run.json # LE L3 沉淀(llm_health 等)
└── verify/verify.json # 4 项机器可验证报告
跨 run 健康度查询(W8)
from media_to_doc import get_run_metrics, list_runs
m = get_run_metrics("output/我的培训")
print(m["pipeline_run"]["llm_health"])
# {'chapters_ollama': {'calls': 1, 'failures': 0},
# 'draft_ollama': {'calls': 6, 'failures': 0}}
runs = list_runs(workspace_root="output", limit=10)
print(runs["llm_health_global"])MCP 工具等价:get_run_metrics / list_runs。
Tested
- 529 pytest / 0 跳过:W11-A(W10-C 519 → 529)涵盖 11 stage 单元测试 + LE 闭环 + CLI + MCP server + 一致性回归
- W5 端到端冒烟:1.3GB / 112min 中文培训视频 CPU 模式全跑通,verify.json overall_passed=true
- W10-A 真端到端验收:395MB / 107min 视频 3h57min,11 stage 全部 completed,llm_health 真聚合
chapters_ollama:1 calls + draft_ollama:6 calls,0 failures - W11-A 一致性回归:同一份数据 gatekeeper.ok == verify.overall_passed,
scripts/_w11a_consistency.py防回归工具就位 - ruff check:All checks passed
Bug Fixes Since 0.1.0-dev
W11-A 修的核心 bug(必须在升级说明里强调):
- Gatekeeper vs Verify 不一致:W4 原型时 gatekeeper 写死了
<work>/chapters/raw/<stem>/<stem>.md+<work>/output_final.html路径,而 W3+ render + W4 longdoc 已迁移到新布局<work>/chapters/raw/<stem>.md+<work>/chapters/raw/<stem>_final.html。verify.py 在 W5 (db92ac9) 已用_resolve_drafts_dir处理两布局,但 gatekeeper 没同步。结果:同一份数据,verify PASS 但 gatekeeper FAIL。W11-A (d2b39d3) 修。
升级后用户应该看不到 pipeline_run.json.gatekeeper_passed=false 但 verify/verify.json.overall_passed=true 这种矛盾状态。
其它小修:bddc387 (W10-C) llm_health 自动聚合、db92ac9 (W5) OCR 路径 / num_ctx / transcript 截断 / longdoc-verify 布局兼容。
Breaking Changes (from 0.1.0-dev)
无。0.1.0-dev 是骨架,公开 API 不稳定,直接跳 1.0.0 是合法的。
Upgrade Instructions
全新安装
git clone https://github.com/media-to-doc/media-to-doc.git
cd media-to-doc
uv sync --all-extras
uv run mtd --version
# media-to-doc 1.0.0从 0.1.0-dev 升级
cd media-to-doc
git fetch origin
git checkout release/v1.0
uv sync --all-extras
uv run pytest # 验证 529 全过重跑已中断流水线
旧的 state.json 与 1.0.0 完全兼容。直接 mtd resume <work> 续跑即可:
uv run mtd resume output/我的课程/W10-A 之前跑的产物
如果旧的产物目录里 pipeline_run.json.gatekeeper_passed=false 但 verify/verify.json.overall_passed=true,别担心,W11-A 已修。
新跑流水线就会一致。旧产物的 gatekeeper 历史值不需要改 — pipeline_run.json 是 LE L3 沉淀真相,留着供 LE 学习用。
Known Limitations
v1.0 范围明确不做(留给 v1.1+):
- UI(Tauri 2 + React 18):Phase 2 才引入,1.0 仅 CLI / Python API / MCP
- NSIS 安装器:Phase 3 才引入,1.0 用
uv安装 - 3 次点击跑通:需要 UI(v1.1+),1.0 是 CLI 流程
- 断点续跑 100% 跨 OS:已支持 Windows + macOS + Linux,跨 OS resume 不保证(状态机本地化)
- 多视频并发:每次
mtd run处理一个视频,批量需手动循环 - CUDA 在 Apple Silicon 上的 MPS 加速:要
--config-settings手配,默认 CPU
Documentation
| 文档 | 路径 | 用途 |
|---|---|---|
| README | README.md | 5 分钟快速开始 + 3 种调用方式 |
| Changelog | CHANGELOG.md | 完整变更历史 |
| Installation | docs/installation.md | 各 OS / CUDA / 中国网络 / Claude Desktop |
| MCP Integration | docs/MCP_INTEGRATION.md | Claude Desktop 配置 + 8 工具签名 |
| Project Guide | CLAUDE.md | 项目指引 + 设计约束 + 11 阶段产物布局 |
| Roadmap | ROADMAP.md | v1.0 后的 Phase 2 / 3 规划 |
| PRD | PRD.md | 产品需求 |
| TDD | TDD.md | 技术设计 |
Acknowledgments
- 参考实现:
E:\办公文件\01学习资料\local-ai-workflow(8 次 commit / 110 测试) - Loop Engineering 五层闭环设计参考 aiec.fun 两篇文章
- 14 条 LP-YYYYMMDD-NNN best_practice 条目沉淀到
.learnings/LEARNINGS.md
Full Changelog
See CHANGELOG.md for the complete milestone summary (W0-W11) and per-commit changes.