VideoToNo · 视频笔记生成
通过本机运行的 VideoToNo 服务,把视频变成带时间轴的 Markdown 笔记:优先读取平台字幕(B 站 AI 字幕深度适配,支持多分 P 合并),没有字幕时用本地 faster-whisper 离线转写,最后由已配置的大模型生成笔记。
先选路线
| 你要什么 | 走哪条 | 需要 API Key |
|---|---|---|
| 带时间轴的转录原料,笔记结构与风格你自己定 | 转录路线 --transcript-only | 不需要 |
| 一份现成的成品笔记(用户只要"给我笔记",或视频很长希望后台跑完) | 笔记路线 --style | 需要(本机按接口地址保存过即可省略) |
你自己就有模型可以写笔记时,优先走转录路线:本机只负责取字幕或离线转写,写作由你完成,不用向用户索要 Key,也不会被套进固定的笔记模板。
第 0 步:服务不在就让它自己起来
脚本先扫 127.0.0.1 的 8000-8019;端口全不通时它不会让你去启动软件,而是自己后台拉起一个无头服务(不开浏览器、不进托盘、不占桌面),等它健康再往下走。它按这个顺序找"服务怎么启动":
- 本次命令带的
--server-cmd "<便携版 exe 路径>"(也接受python launcher.py这类命令) - 环境变量
VIDEOTONOTES_SERVER_CMD - 上一次
--server-cmd给过的路径(记在%LOCALAPPDATA%\VideoToNo\skill-server-cmd.txt) - 技能脚本仍在 VideoToNo 仓库里时,直接用当前 Python 起
launcher.py
四条都没有 → 脚本退出并说清缺什么。这时向用户要一次 exe 的位置("VideoToNo 那个程序放在哪个目录?"),带上 --server-cmd 重跑;给过这一次就不用再问。
无头实例闲置 15 分钟且没有在建任务时自己退出(要常驻就让它带 --idle-exit 0);日志在 exe 同级目录的 workspace/_app.log。第一次拉起会多花几秒(打包版还要先解压自身),那不是卡死。
想手动确认服务在不在,健康检查照旧可用:
bashcurl -s --max-time 2 http://127.0.0.1:8000/api/health # 期望返回 {"status":"ok","service":"VideoToNo",...}
服务已在运行时(用户自己双击了 exe,或跑的是界面版),脚本直接复用它,不会起第二个。
推荐方式:用附带脚本一条命令完成
bash# 转录路线(默认推荐,零配置) python "<本技能目录>/scripts/video_note.py" "<视频链接或本地文件路径>" --transcript-only --wait 1800 # 笔记路线(一键成品) python "<本技能目录>/scripts/video_note.py" "<视频链接或本地文件路径>" --style detailed --wait 1800
脚本会自动:探测服务端口(不通就后台拉起)→(本地文件先上传)→ 提交任务 → 轮询进度(实时打印运行日志)→ 输出完整 Markdown。
--transcript-only:只做到转录为止,不调用大模型;此模式默认复用同链接已有的转录(秒回),加--no-reuse才强制重新转写--style:detailed(翔实+点评,默认)/faithful(忠实复原)/concise(精简摘要)--wait:最长等待秒数,默认 1800;长视频(>30 分钟)建议加大--out <path.md>:把结果写入文件(不加则打印到 stdout)--server-cmd "<便携版 exe 路径>":本机服务没在跑时用它后台拉起,给一次会记住;也可写python launcher.py这类命令- 找不到启动命令、API Key 未配置、任务失败时都会给出明确的中文提示,按提示向用户询问即可
需要用户提供的信息
-
API Key:只有笔记路线需要,而且大概率不用你拿。本机为某个接口地址保存过 Key(网页端「保存到本机」或 MCP 的
save_llm_config)时直接省略即可;只存过一个地址时脚本会自动沿用该通道,存了多个则不会猜。任务失败点名"该接口地址没有可复用的 Key"时,先问用户能不能改走--transcript-only(全程不调用大模型、不需要 Key,整理成稿由你这边完成)。用户坚持要成品笔记再问供应商(deepseek/openai/qwen/glm/moonshot/custom)与 Key,并按下面这种形式传,custom 另加--base-url/--custom-model:bash# 推荐:Key 从标准输入进来,不落 shell 历史也不进进程命令行 printf '%s\n' "<用户给的 Key>" | python scripts/video_note.py "<链接>" --provider deepseek --api-key - # 或者用环境变量(同一条命令里赋值同样会留在历史里,长期会话请设为环境变量) VIDEOTONOTES_LLM_API_KEY=... python scripts/video_note.py "<链接>" --provider deepseek不要把 Key 写成
--api-key sk-xxx:命令行参数会留在 shell 历史、进程列表和 agent 的工具调用日志里,同用户的任何进程都能读到。脚本已把"看到的凭据一律换成掩码"作为兜底(自己发的告警、服务端回显的 4xx 详情都会洗),但兜底不等于源头干净。已保存的 Key 只在目标地址一致时复用,不会被发给别的网关。 -
本地文件上传上限 2GB;大视频(默认 ≥300MB)未要求截图时服务端会自动只保留音频。
手动走 API(需要自定义流程时)
-
健康检查:
GET /api/health -
提交任务:
bash# 转录路线:请求体里没有任何大模型字段 curl -s -X POST http://127.0.0.1:8000/api/transcribe \ -H "Content-Type: application/json" \ -d '{"video_url": "https://www.bilibili.com/video/BVxxxx", "whisper_model": "base"}' # B 站多 P 视频可加 "bilibili_pages": [2, 3] 只转写指定分 P(缺省跟随链接 ?p=,没有则全部) # 笔记路线 curl -s -X POST http://127.0.0.1:8000/api/summarize \ -H "Content-Type: application/json" \ -d '{ "video_url": "https://www.bilibili.com/video/BVxxxx", "summary_style": "detailed", "llm_config": {"model_type": "deepseek", "api_key": "sk-..."} }' # 都返回 {"task_id": "..."};本地文件改为先 POST /api/upload 拿 upload_task_id上面的
"api_key": "sk-..."只是字段示意。真发请求时这条 curl 命令同样会留在 shell 历史里:能省略就省略(后端按 Base URL 复用本机已保存的 Key),必须带时用-d "{...\"api_key\": \"$VIDEOTONOTES_LLM_API_KEY\"...}"这类形式,别把 Key 写成字面量。 -
轮询:
GET /api/task/{task_id},直到status变为completed/failed/cancelled(logs数组是实时运行日志)。转录任务的result里没有markdown,result.output是"transcript" -
取结果:
- 笔记路线:
result.markdown是完整笔记 - 转录路线:
GET /api/task/{task_id}/transcript?output_format=markdown拿整篇[MM:SS-MM:SS] 正文,output_format=json拿分段数组(时间为秒)。该端点默认json,MCP 的get_transcript默认markdown,两边都建议显式传 - 两条路的
result.output_directory都是产物目录(notes.md/transcript.json/transcript.md);超长内容建议直接读该目录下的transcript.json自行切片,不必整篇塞进上下文
- 笔记路线:
-
取消运行中的任务:
POST /api/task/{task_id}/cancel(秒级生效)
注意事项
- 服务只监听本机回环地址,外部机器无法访问;这是设计使然(隐私边界)
- 默认同时只处理 1 个任务,不要并行提交多个
- 任务产物保留在 workspace 下,重复提交同一在线链接会自动复用已有转录(更快、更省 token)
- 已经走完转写的历史任务都能用
/api/task/{id}/transcript取转录,包括后来生成笔记失败的——不必重跑


