Skip to content

Repository files navigation

视频转录 API (Video Transcript API)

基于 Python 3.11+ 的异步视频转录服务,支持多平台下载、双引擎转录、智能文本处理和企业级功能集成。

Python FastAPI License

开发契机和玩法分享:LLM 吞噬一切,我用 AI 长出来的那些工具

转录结果页面


核心特性

  • 多平台支持:YouTube、Bilibili、抖音、小红书、微信视频号(经 MediaResolverAPI)、小宇宙播客、Apple Podcast,工厂模式自动匹配下载器
  • 双引擎转录:CapsWriter-Offline(通用转录)+ FunASR(说话人识别)
  • 智能文本处理:LLM 自动校对 ASR 错误、专有名词纠错、按说话人采样+置信度降级的说话人推断、内容总结
  • 处理深度可控processing_options 开关按任务控制是否校对/总结,分层缓存产物只增不减,重复请求自动复用已有层
  • 诚实状态模型:校对(full/partial/none/disabled)与总结(generated/skipped_short/failed/pending/disabled)状态全链路透传,不再用占位字符串掩盖失败
  • 企业级功能:SQLite + 文件系统双层缓存、多用户管理、审计日志(含 LLM token 用量统计)、多渠道通知(企业微信 + 飞书)、任务历史浏览器
  • 风控系统:敏感词检测、多策略文本脱敏、风险模型自动切换

外部依赖


快速开始

环境要求

  • Python 3.11+
  • FFmpeg
  • 转录服务器(CapsWriter / FunASR 二选一或同时部署)

本地安装

# 克隆仓库
git clone <repository-url>
cd video-transcript-api

# 安装依赖(使用 uv)
curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync

# 配置服务
cp config/config.example.jsonc config/config.jsonc
# 编辑 config.jsonc,填写 api.auth_token、tikhub.api_key 等
# 可选:抖音/小红书/视频号改走 MediaResolverAPI 集中解析,设
#   downloaders.use_media_resolver=true 并配置 media_resolver 段
#   (使用指南:docs/guides/media_resolver.md)

# 启动
uv run python main.py --start

可在启动前执行无副作用配置预检;该命令不会连接外部服务、迁移数据库或启动线程:

uv run python main.py --check-config --config config/config.jsonc

Docker 部署

# 准备配置
cp config/config.example.jsonc config/config.jsonc

# 本地构建并启动(使用固定的 dev 标签,不用于生产部署)
cd docker/
docker compose up -d --build

Docker 镜像ghcr.io/zj1123581321/video-transcript-api

镜像内置 ffmpeg、BBDown、yt-dlp,无需额外安装。

生产部署禁止使用 latest。构建脚本会拒绝包含已跟踪或未跟踪修改的脏工作区,只从干净提交以 12 位 Git SHA 生成唯一 tag;部署脚本拉取该 tag 后按同一镜像仓库解析并固定 registry digest。候选镜像会先运行 --check-config,失败时不重启当前服务,启动后健康检查失败则恢复上一个 digest:

./docker/push_to_ghcr.sh
# 在 docker/deploy_targets.json 指定的 n305:/opt/media/VideoTranscriptAPI 上执行:
./docker/pull_and_deploy.sh ghcr.io/zj1123581321/video-transcript-api:<git-sha>

本仓库只提供部署能力;脚本不会自行 SSH 或自动上线。服务器首次运行会从 docker/docker-compose.deploy.yml 生成根目录 docker-compose.yml,配置文件位于 <deploy-dir>/config/config.jsonc,成功使用的 digest 记录在 <deploy-dir>/.deploy-image。同一项目目录的部署由 .deploy.lock 串行化;所有 Compose 操作固定使用部署根目录作为 project directory,并与候选预检加载同一份根目录 .env。重启前还会确认现有 Compose 文件确实把服务渲染为候选 digest。旧 Compose 不兼容时会先备份为 docker-compose.yml.pre-digest.bak,再迁移到仓库模板;候选失败回滚时会恢复原 Compose,并叠加仅覆盖镜像的配置把旧版本固定到记录的 digest。首次切换硬化脚本时,旧容器即使由 tag 启动也会先按原仓库解析为可回滚 digest;若旧镜像还没有 Docker HEALTHCHECK,回滚验证会改用容器内 /livez 探测。候选镜像启动失败、健康检查失败、启动后脚本被中断或成功 digest 状态文件无法原子提交时,脚本都会恢复旧 digest 并确认旧版本重新健康后才退出。

注意:CapsWriter / FunASR 需单独部署,配置中的服务地址不能用 localhost,需改为宿主机 IP 或 host.docker.internal


基本用法

提交转录任务

curl -X POST "http://localhost:8000/api/transcribe" \
  -H "Authorization: Bearer your-auth-token" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.youtube.com/watch?v=xxx",
    "use_speaker_recognition": true
  }'

只转录不校对/不总结

通过 processing_options 按任务控制处理深度,calibratesummarizeinfer_speaker_names 均默认 true(等价历史行为):

curl -X POST "http://localhost:8000/api/transcribe" \
  -H "Authorization: Bearer your-auth-token" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.youtube.com/watch?v=xxx",
    "processing_options": {
      "calibrate": false,
      "summarize": false,
      "infer_speaker_names": false
    }
  }'

三个开关全部为 false 时不会调用 LLM。分层缓存产物只增不减:后续若对同一视频提交 calibrate: trueinfer_speaker_names: true 的请求,只会补跑缺失且有效性校验未通过的层,已存在的转录不会重新下载。完整语义见 处理深度开关功能文档

查询任务状态

curl -X GET "http://localhost:8000/api/task/{task_id}" \
  -H "Authorization: Bearer your-auth-token"

Web 界面

  • 提交任务GET /add_task_by_web
  • 查看结果GET /view/{view_token} — 不可猜测的公开只读分享 capability;写操作仍需认证
  • 任务历史GET /static/history.html — 支持按日期、平台、频道、关键词搜索,已读追踪,摘要预览
  • 导出文件GET /export/{view_token}/{type}(支持 calibratedsummarynotestranscript

浏览器访问令牌与公开阅读边界

首页、任务历史页和转录结果页共用同一个浏览器访问令牌。令牌以 vta_bearer_token 为 canonical 键保存,并由统一的 Bearer 鉴权模块读取。读取时 canonical 永远优先;迁移尚未封存时,才按 api_keyvta_api_key_persistvta_api_key 的固定顺序兜底。迁移 API 不会在普通读取时自动调用;在浏览器存储逐键 写入/删除均成功的正常路径中,成功写入 canonical 或显式清除会写入迁移标记并清理旧 别名,清除/更换会同步其他打开的标签页,旧凭据不会复活。逐键存储失败、memory fallback 或跨标签 clear 异常属于 personal 风险下接受不修的 P2/P3 边界,真实语义见 鉴权 SPEC实现评审分诊。浏览器存储 不可用时仅在当前标签页内存中封存令牌,刷新页面后需要重新输入。

  • 结果页 /view/{view_token} 及其 GET 导出链接是不可猜测的公开只读 capability, 拿到链接即可阅读对应结果;这条公开阅读路径不会替代写操作鉴权。
  • 提交转录、查询私有任务/历史,以及转录页的重新校对、重新总结、生成详细笔记等 写操作仍通过 Authorization: Bearer <访问令牌> 保护。已有令牌时这些操作直接使用 它并直接提交;令牌缺失时先显示输入框,POST 或轮询首次收到 401 时可再次提示并 最多重放一次,因此“缺令牌 + 401”组合可能出现第二个弹窗(按上述评审记录为 P2)。 403/404/409 和不确定的 POST 网络错误不会自动重试。
  • 首页在“高级设置”中填写令牌;历史页的“清除鉴权”会撤销私有请求并清空当前页的 私有数据;转录结果页提供“设置/更换访问令牌”和“清除访问令牌”。上述同步与旧别名 清理承诺仅适用于存储操作全部成功的正常路径;逐键失败、memory fallback 和跨标签 clear 异常按 personal P2/P3 分诊接受不修。访问令牌只应输入到可信浏览器,不要把它 放进 URL、分享链接或日志。

PWA 缓存刷新注意事项

Service Worker 对鉴权脚本采用 network-first,并在每次静态资产版本升级时预缓存 auth-storage.jstranscript-protected-action.js;API 和 /view/ 导航不会写入 缓存。部署包含前端鉴权变更时必须随 sw.js 一起递增缓存版本,随后重新打开页面等待 Service Worker 激活。若已安装的 PWA 仍显示旧页面,请在浏览器的 Service Worker 面板执行“更新/重新加载”后再重试;不要用清除站点数据代替刷新(那会同时删除本地 访问令牌和其他页面偏好)。

API 端点一览

端点 方法 说明
/api/transcribe POST 提交转录任务(支持 processing_options 处理深度开关)
/api/task/{task_id} GET 查询任务状态
/api/recalibrate POST 重新校对(唯一强制重做例外,忽略分层缓存保护;总结缺失时仍会自动补跑,但单独重跑总结请用 /api/resummarize
/api/resummarize POST 只重新生成总结(跳过下载、转录、校对和章节,复用已有校对文本)
/api/generate_notes POST 按已有章节异步生成详细笔记(只新增 notes 缓存层,不改写校对、总结或章节)
/api/audit/stats GET 调用统计,含 LLM token 用量聚合(按阶段汇总 prompt/completion/total tokens)
/api/audit/calls GET 调用记录
/api/audit/history GET audit.db 独立终态任务历史(状态仅支持 successfailedall;支持过滤、分页、关键词搜索),含处理状态与 content_expired
/api/audit/filter-options GET 获取过滤选项(webhook/平台/频道列表)
/api/audit/summary GET 任务摘要预览(前 300 字),基于诚实状态模型返回 summary_status
/api/users/profile GET 当前用户信息
/view/{view_token} GET 结果查看页
/view/{view_token}?raw=calibrated GET 纯文本导出
/view/{view_token}?page=calibrated GET HTML 页面导出
/view/{view_token}?raw=notes GET 详细笔记纯文本导出(生成后可用)
/view/{view_token}?page=notes GET 详细笔记 HTML 页面导出(生成后可用)
/export/{view_token}/{type} GET 文件下载

更多 API 细节请参考 功能文档


项目结构

video-transcript-api/
├── src/video_transcript_api/
│   ├── api/              # FastAPI 服务、路由、依赖注入
│   ├── downloaders/      # 多平台下载器(工厂模式)
│   ├── transcriber/      # 转录引擎(CapsWriter + FunASR)
│   ├── llm/              # LLM 处理引擎(协调器-处理器-核心组件)
│   ├── cache/            # 缓存系统(SQLite + 文件系统)
│   └── utils/            # 工具模块(日志、通知、风控、用户管理等)
├── tests/                # 测试套件
├── docs/                 # 详细文档
├── config/               # 配置文件
├── docker/               # Docker 部署文件
└── main.py               # 入口文件

文档

详细文档位于 docs/ 目录:


测试

uv run python scripts/run_tests.py     # 运行所有测试
uv run pytest tests/unit/              # 单元测试
uv run pytest tests/integration/       # 集成测试

开源协议

基于 PolyForm Noncommercial License 1.0.0 开源。允许任何非商业用途的使用、学习、修改和分发;禁止一切商业用途(包括企业内部用于盈利业务、对外售卖或商业集成)。学术、教育、公益、政府等非营利机构的使用视为许可范围内。详见 LICENSE

About

基于 Python 3.11+ FastAPI 的异步音视频转录服务,支持 YouTube、小宇宙、Bilibili、视频号等多平台解析,本地部署可实现说话人区分转录,调用 LLM 完成文本智能校对与内容总结,配套网页端查看 / 导出功能,支持企业微信消息推送

Topics

Resources

Stars

210 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages