版本: v1.5
更新日期: 2026-03-10
状态: 已实现
VAT Web UI 是一个基于 FastAPI 的视频处理管理界面,提供以下核心功能:
- 视频管理:查看、搜索、处理视频,查看处理状态和相关文件。支持多种方式添加视频(平台链接、直链、本地路径、文件上传)
- Playlist 管理:添加 YouTube Playlist,自动同步视频列表,批量处理
- 任务管理:创建处理任务,实时查看进度和日志,取消/重试任务
- Custom Prompts:管理翻译和优化阶段使用的自定义提示词
- 文件浏览:查看、编辑、下载视频处理生成的各类文件
- B站管理:账号状态、合集管理、审核退回自动修复、上传模板配置
| 组件 | 技术 |
|---|---|
| 后端框架 | FastAPI (异步) |
| 前端模板 | Jinja2 + TailwindCSS + Alpine.js |
| 实时通信 | SSE (Server-Sent Events) |
| 任务执行 | 子进程 + CLI (生命周期解耦) |
| 数据存储 | SQLite (web_jobs 表) |
# 方式1:直接运行模块
python -m vat.web.app
# 方式2:使用 uvicorn
uvicorn vat.web.app:app --host 0.0.0.0 --port 8080
# 服务默认运行在 http://localhost:8080启动后访问 http://localhost:8080,顶部导航栏包含:
| 入口 | 说明 |
|---|---|
| 📹 视频 | 视频列表,查看所有已添加的视频 |
| 📂 Playlist | Playlist 管理,添加和同步 YouTube 播放列表 |
| ⚙️ 任务 | 任务管理,查看任务历史和运行状态 |
| 📝 Prompts | Custom Prompt 管理 |
| 👁️ Watch | Watch 自动监控管理,启动/停止/查看监控会话 |
| 📺 B站 | B站账号、合集管理、审核退回修复、上传配置 |
| 🗄️ DB | 数据库只读浏览器,查看表结构和数据 |
vat/web/
├── app.py # FastAPI 应用入口 + 页面路由
├── jobs.py # 任务管理器 (JobManager)
├── routes/
│ ├── videos.py # 视频 API
│ ├── playlists.py # Playlist API
│ ├── tasks.py # 任务执行 API
│ ├── files.py # 文件浏览 API
│ ├── prompts.py # Prompt 管理 API
│ ├── bilibili.py # B站管理 API(账号/合集/退回修复/上传配置)
│ ├── watch.py # Watch 自动监控 API
│ └── database.py # 数据库浏览 API(只读)
└── templates/ # Jinja2 模板
├── base.html # 基础布局(导航栏)
├── index.html # 视频列表
├── video_detail.html # 视频详情
├── playlists.html # Playlist 列表
├── playlist_detail.html # Playlist 详情
├── tasks.html # 任务列表
├── task_new.html # 新建任务
├── task_detail.html # 任务详情
├── prompts.html # Prompt 管理
├── bilibili.html # B站管理
├── watch.html # Watch 管理
└── database.html # 数据库浏览
核心设计:任务通过子进程执行 CLI 命令,与 Web 服务器生命周期完全解耦。
┌─────────────────────────────────────────────────────────┐
│ FastAPI 主进程 │
│ POST /api/tasks/execute │
│ ↓ │
│ JobManager.submit_job() │
│ ↓ │
│ subprocess.Popen("python -m vat process ...") │
│ ↓ │
│ 返回 task_id(立即响应) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 独立子进程 │
│ vat process -v VIDEO_ID -s download,whisper,... │
│ stdout/stderr → job_logs/job_xxx.log │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 前端通过 SSE 实时读取日志文件显示 │
└─────────────────────────────────────────────────────────┘
优点:
- Web 服务重启不影响正在运行的任务
- 复用 CLI 逻辑,确保 Web 操作与命令行完全等价
- 任务状态持久化在 SQLite
重要行为:
-
配置热更新:每次任务执行都会重新加载
config/default.yaml。修改配置后,重新运行任务即可应用新配置,无需重启 Web 服务。 -
阶段跳跃处理(直通模式):
- 连续阶段(如 split,optimize,translate):正常执行,缺少前置输出则报错
- 不连续阶段(如只选 whisper + embed):中间被跳过的阶段自动以"直通模式"执行
- 直通模式实现:系统会临时修改 config 中对应阶段的开关,让各阶段内部自行处理直通逻辑
- 状态标记:直通阶段完成后标记为
SKIPPED而非COMPLETED
例如:选择
whisper,embed时,系统会:- 自动填充中间阶段:
whisper, split, optimize, translate, embed - 设置直通阶段的 config 开关:
asr.split.enable = Falsetranslator.llm.optimize.enable = Falsetranslator.skip_translate = True
- 各阶段正常执行,内部根据开关自动复制输入到输出
- 直通阶段标记为
SKIPPED,用户指定阶段标记为COMPLETED
每个处理阶段的进度通过 ProgressTracker 追踪,日志格式:
[0%] 开始执行步骤: download
[12%] 视频下载完成
[20%] 步骤完成: download
[40%] 步骤完成: whisper
[60%] 步骤完成: split
[80%] 步骤完成: translate
[100%] 步骤完成: embed
前端每 2 秒轮询获取进度并更新进度条。
功能:
- 显示所有已添加的视频
- 每行显示:标题、来源、时长、任务状态、进度、发布日期、创建时间
- 来源类型以彩色标签显示:YouTube(红色)、Bilibili(粉色)、local(绿色)、direct_url(蓝色)
- 任务状态以图标形式显示 7 个阶段的完成情况(✓ 完成 / · 待处理)
- 支持按状态筛选:全部 / 已完成 / 进行中 / 失败(SQL 层面过滤,不加载全量数据)
- 支持搜索:按标题/频道/ID 搜索(SQL LIKE)
- 分页显示,默认每页 50 条
操作:
- 点击行进入视频详情页
- 统计卡片显示:视频总数、已完成、进行中、失败数量
- 支持按 Playlist 过滤
- 支持按阶段状态过滤(DL/WH/SP/OP/TR/EM/UP)
添加视频弹窗(点击「+ 添加视频」按钮):
通过 Tab 切换四种添加方式:
| Tab | 输入 | source_type |
|---|---|---|
| 平台链接(默认) | YouTube / Bilibili 视频 URL | 自动检测 |
| 直链 | HTTP/HTTPS 视频文件直链 | direct_url |
| 服务器路径 | 服务器上的视频文件绝对路径 | local |
| 上传视频 | 拖拽/选择文件上传到服务器 | local(上传后转为服务器路径) |
所有 Tab 共用一个可选的「标题」输入框,不填则自动从文件名/平台获取。上传视频支持 mp4、mkv、webm、avi、mov、flv 格式,上传完成后自动填入服务器路径。
信息展示:
- 视频标题(原文 + 翻译)
- 来源类型、时长、源地址链接
- 处理进度时间线:7 个阶段的状态和完成时间
- 翻译信息:翻译标题、优化标题、简介摘要、推荐标签、推荐分区
- 相关文件列表
阶段时间线:
| 阶段 | 说明 |
|---|---|
| 下载 | 视频下载 + 信息翻译 |
| 语音识别 | Whisper ASR |
| 句子分割 | LLM 智能断句 |
| 提示词优化 | 字幕优化 |
| 翻译 | LLM 翻译 |
| 嵌入字幕 | FFmpeg 硬字幕 |
| 上传 | 上传到 B 站 |
各阶段完成后,使用的模型名会以标签形式显示在阶段名旁边(如 large-v3、gpt-4o-mini、kimi-k2.5、gemini-3-flash-preview)。
操作按钮:
- ▶ (执行):执行该阶段
- ↺ (强制重做):强制重新执行该阶段(忽略缓存)
- 执行下一步:自动执行第一个未完成的阶段
- 选择阶段执行...:跳转到新建任务页面
- 生成 CLI 命令:显示等价的命令行命令
文件操作:
- 查看:在模态框中查看文件内容
- 编辑:编辑文本文件(srt, txt, json, ass)
- 播放:播放视频/音频文件
- 下载:下载文件
视频选择:
- 搜索框:按标题过滤视频
- 复选框列表:选择要处理的视频
- 每个视频显示当前进度(如 "6/7 (85%)")
- 快捷按钮:全选 / 取消全选 / 选择待处理 / 选择可见
阶段选择:
☑ 下载
☑ ASR (语音识别)
├ ☑ Whisper (语音转文字)
└ ☑ Split (智能断句)
☑ 翻译
├ ☑ Optimize (提示词优化)
└ ☑ Translate (翻译)
☑ 嵌入字幕
子阶段可单独选择,支持精细控制处理流程。
其他选项:
- GPU 设置:自动选择 / GPU 0 / GPU 1 / 仅 CPU
- 并发数量:设置同时并行处理的视频数(1-5,默认1=串行)。包含 GPU 步骤(whisper/embed)时建议不超过 2
- 强制重新处理:勾选后忽略已完成状态,强制重新执行
操作按钮:
- 开始执行:提交任务并跳转到任务详情页
- 生成 CLI 命令:仅显示命令,不执行
显示内容:
- 任务 ID、视频数、执行阶段、状态、进度、创建时间
- 状态:completed / running / failed / cancelled
操作:
- + 新建任务:跳转到新建任务页
- 点击任务 ID 进入任务详情页
信息展示:
- 任务 ID、创建时间、状态徽章
- 进度条(实时更新)
- 视频数量、执行阶段
- 处理视频:从数据库获取视频标题并显示为可点击链接
- 单视频:直接显示标题
- 2-3 个视频:逗号分隔显示
- 3 个以上:默认折叠,显示前 2 个 + "等 N 个视频...",点击可展开
- 当前阶段:从日志实时解析正在执行的步骤
- 错误信息(失败时显示)
实时日志:
- 绿色终端风格显示
- 通过 SSE 实时推送日志
- 自动滚动开关:勾选时日志自动滚动到底部
- 支持清空日志显示
操作按钮:
- 取消任务:运行中任务可取消(发送 SIGTERM)
- 重新运行:已完成/失败/取消任务可重新运行
- 删除任务:删除任务记录
显示内容:
- Playlist 标题、频道名、视频数、进度、最后同步时间
操作:
- + 添加 Playlist:输入 YouTube Playlist URL 添加
- 同步:增量同步 Playlist(获取新视频)
- 处理:处理全部待处理视频
- 删除:删除 Playlist(视频记录保留)
信息展示:
- Playlist 标题、进度统计(已完成/待处理/失败/不可用)
- 统计卡片可点击,跳转到首页对应 Playlist + 状态筛选
- 进度条
- Custom Prompt 配置(可为 Playlist 单独指定翻译/优化 Prompt)
- B 站上传配置(主播简称、合集、标题模板、版权类型,覆盖全局设置)
视频列表:
- 复选框选择视频
- 显示:标题、上传日期、时长、状态(已完成/失败/进行中/待处理)
- 按上传日期排序(旧 → 新)
- 分页显示,默认每页 100 条(仅对当前页视频查询进度,避免全量加载)
操作按钮:
- 同步 Playlist:增量同步
- 处理选中:处理选中的视频
- 处理范围:打开范围选择对话框
- 强制重做选中:强制重新处理选中视频
范围处理对话框:
- 按索引范围:指定起始和结束索引
- 仅未处理:选择所有待处理视频
- 最新 N 个:选择最新的 N 个视频
功能:
- 管理翻译和优化阶段使用的 Custom Prompts
- 支持创建、编辑、删除 Prompt
- 设置默认使用的 Prompt
- Playlist 可单独配置专属 Prompt
Prompt 类型:
- 翻译 Prompts:用于 LLM 翻译阶段
- 优化 Prompts:用于字幕优化阶段
账号状态:显示当前登录状态、用户名、UID、等级。
合集管理:查看已创建的 B站新版合集(SEASON),支持:
- 查看:展开合集内视频列表(标题、av号、链接)
- 排序:按标题中的
#数字自动排序合集内视频 - 复制 ID:复制合集 ID 到剪贴板
合集同步:以 Playlist 为单位,将已上传到B站但未入集的视频批量添加到对应合集:
- 自动读取 Playlist 的
upload_config.season_id确定目标合集 - 显示每个 Playlist 的已上传/已同步/待同步数量
- 点击"同步"按钮在后台执行,实时显示进度
- 同步完成后自动对合集按
#数字排序 - 对于没有
bilibili_target_season_id标记的旧视频,同步时自动补充标记
审核退回管理:
- 点击"刷新退回列表"加载被退回的稿件
- 显示退回原因、违规时间段、修改建议
- 可修复标签:有具体违规时间段的稿件可自动修复
- 全片违规标签:无法自动修复
- 点击"自动修复"按钮:自动查找本地视频 → 遮罩违规片段 → 上传替换原稿件
- 视频查找策略(按优先级):source URL 匹配 → bilibili_aid 匹配 → 翻译标题匹配 → 从 B站下载原视频(fallback)
上传模板:配置上传标题/简介的模板,支持 ${变量名} 占位符替换。可用变量包括频道信息(${channel_name})、翻译内容(${translated_title}、${tldr})、模型信息(${whisper_model}、${split_model}、${optimize_model}、${translate_model}、${models_summary})等,完整列表见 vat/uploaders/template.py 中 build_upload_context 的文档注释。
默认上传设置:版权类型、默认分区、标签、合集、封面策略。
在新建任务页(/tasks/new),当阶段仅选择"上传到B站"时,可启用定时上传:
时间模式:
- 每天在指定时刻:选择一个或多个时间点
- 每隔 N 小时:按固定间隔触发
- 高级 (cron):自定义 cron 表达式
每次上传数量:可配置每次触发时上传的视频数(1/2/3/5/10)。
上传模式:
- 后台等待上传(cron 模式):进程等待到 cron 触发时间后上传,需保持进程运行
- B站定时发布(dtime 模式):立即全部上传,通过 B站 API 指定各视频的定时发布时间,无需保持进程运行(发布时间需 >2 小时)
独立的 Watch 自动监控管理页面,用于统一管理所有 watch 会话。
会话列表:
- 显示所有 watch sessions(运行中/已停止/异常)
- 每个 session 显示:监控的 Playlist 列表、状态指示灯、运行时长、累计统计(发现新视频数、提交任务数)
- 新建 Watch:选择 Playlist + 配置参数(间隔、阶段、GPU、并发数)→ 启动
- 停止:发送 SIGTERM 停止运行中的 watch 进程
会话详情(/watch/{session_id}):
- Session 配置参数、启动时间
- 实时状态:上次/下次检查时间、累计统计
- 轮次历史:每轮的检查时间、发现视频数、提交的任务链接、错误信息
- 关联的 Job 列表
Playlist 快捷入口:在 Playlist 详情页提供「开始监控」按钮,可快捷创建该 Playlist 的 watch session。如果该 Playlist 已在被监控,则显示 watch 状态摘要和跳转链接。
内置的 SQLite 数据库只读浏览器,用于开发调试和数据检查。
功能:
- 左侧显示所有数据表及行数
- 选择表后查看表结构(列名、类型、主键、非空、默认值)
- 分页浏览表数据(可配置每页 25/50/100/200 行)
- 全文搜索(跨所有列的 LIKE 匹配)
- 点击列头排序(升序/降序切换)
- 点击行查看详情弹窗(JSON 字段自动格式化展开)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/videos |
列出视频(支持分页、状态过滤) |
| GET | /api/videos/{id} |
获取视频详情 |
| POST | /api/videos |
添加视频(支持 source_type: auto/youtube/local/direct_url,可选 title) |
| POST | /api/videos/upload-file |
上传视频文件到服务器(返回 server_path 供创建 LOCAL 记录) |
| DELETE | /api/videos/{id} |
删除视频 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/playlists |
列出 Playlist |
| GET | /api/playlists/{id} |
获取 Playlist 详情 |
| POST | /api/playlists |
添加 Playlist |
| POST | /api/playlists/{id}/sync |
同步 Playlist |
| DELETE | /api/playlists/{id} |
删除 Playlist |
| GET | /api/playlists/{id}/prompt |
获取 Prompt 配置 |
| PUT | /api/playlists/{id}/prompt |
设置 Prompt 配置 |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/tasks/execute |
执行处理任务 |
| GET | /api/tasks |
列出任务历史 |
| GET | /api/tasks/{id} |
获取任务详情 |
| POST | /api/tasks/{id}/cancel |
取消任务 |
| DELETE | /api/tasks/{id} |
删除任务记录 |
| POST | /api/tasks/{id}/retry |
重新运行任务 |
| GET | /api/tasks/{id}/logs |
SSE 实时日志流 |
| GET | /api/tasks/{id}/log-content |
获取完整日志内容 |
执行任务请求体:
{
"video_ids": ["video_id_1", "video_id_2"],
"steps": ["download", "whisper", "split", "optimize", "translate", "embed", "upload"],
"gpu_device": "auto",
"force": false,
"concurrency": 1,
"generate_cli": false,
"upload_cron": "",
"upload_batch_size": 1,
"upload_mode": "cron"
}concurrency: 并发处理的视频数量,默认 1 表示串行。设置 > 1 时多个视频将并行处理upload_cron: 定时上传的 cron 表达式(仅 upload 阶段使用)upload_batch_size: 每次触发上传的视频数量,默认 1upload_mode: 上传模式,cron(后台等待触发)或dtime(B站定时发布 API)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/files/view/{video_id}/{filename} |
查看文件内容 |
| PUT | /api/files/save/{video_id}/{filename} |
保存文件 |
| GET | /api/files/download/{video_id}/{filename} |
下载文件 |
支持的文件类型:
- 文本:
.srt,.vtt,.txt,.json,.yaml,.md,.ass,.log - 视频:
.mp4,.webm,.mkv(支持 Range 请求) - 音频:
.mp3,.wav,.m4a - 图片:
.jpg,.jpeg,.png,.gif,.webp
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/prompts |
列出所有 Prompts |
| GET | /api/prompts/{type}/{name} |
获取 Prompt 内容 |
| POST | /api/prompts |
创建 Prompt |
| PUT | /api/prompts/{type}/{name} |
更新 Prompt |
| DELETE | /api/prompts/{type}/{name} |
删除 Prompt |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /bilibili/status |
获取登录状态 |
| GET | /bilibili/seasons |
获取合集列表 |
| POST | /bilibili/seasons |
创建合集 |
| GET | /bilibili/rejected |
获取退回稿件列表 |
| POST | /bilibili/fix/{aid} |
启动退回稿件自动修复 |
| GET | /bilibili/fix/{aid}/status |
查询修复任务状态 |
| GET | /bilibili/season/{id}/episodes |
获取合集内视频列表 |
| POST | /bilibili/season/{id}/sort |
触发合集自动排序(按#数字) |
| GET | /bilibili/sync-playlists |
获取可同步的 Playlist 列表及统计 |
| POST | /bilibili/season-sync/{playlist_id} |
以 Playlist 为单位执行合集同步 |
| GET | /bilibili/season-sync/{playlist_id}/status |
查询合集同步任务状态 |
| GET | /bilibili/config |
获取上传配置 |
| PUT | /bilibili/config |
更新上传配置 |
| POST | /bilibili/season/{id}/sync-titles |
同步合集标题(用实际视频标题替换合集中的名称) |
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/watch/start |
启动 watch session(通过 JobManager 提交) |
| GET | /api/watch/sessions |
列出所有 watch sessions |
| GET | /api/watch/sessions/{session_id} |
获取 session 详情 |
| POST | /api/watch/sessions/{session_id}/stop |
停止运行中的 session(发送 SIGTERM) |
| DELETE | /api/watch/sessions/{session_id} |
删除已停止的 session 记录 |
| GET | /api/watch/sessions/{session_id}/rounds |
获取轮次历史 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/database/tables |
列出所有表及其行数和列信息 |
| GET | /api/database/tables/{table_name} |
分页查询表数据(支持搜索、排序、筛选) |
| GET | /api/database/tables/{table_name}/row |
获取单行数据详情(所有字段展开) |
- 访问
/tasks/new - 在搜索框输入视频标题或 ID 查找
- 勾选目标视频
- 选择要执行的阶段(默认全选)
- 点击"开始执行"
- 在任务详情页查看实时进度和日志
- 访问
/playlists,点击"+ 添加 Playlist" - 输入 YouTube Playlist URL,点击添加
- 等待同步完成(自动获取视频列表和信息翻译)
- 进入 Playlist 详情页
- 选择视频(或使用"处理范围"功能)
- 点击"处理选中"
- 在新建任务页确认配置后执行
- 进入视频详情页
- 找到需要重新处理的阶段
- 点击 ↺ 按钮强制重新执行
- 确认后自动创建任务并跳转
- 进入视频详情页
- 在"相关文件"区域找到字幕文件(如
translated.srt) - 点击"编辑"按钮
- 在模态框中修改内容
- 点击"保存"(原文件自动备份为
.bak)
- 访问
/watch,点击「新建 Watch」 - 选择要监控的 Playlist
- 配置参数(轮询间隔、处理阶段、GPU、并发数)
- 点击「启动」
- Watch 进程开始持续运行,自动发现新视频并提交全流程处理任务
- 在 Watch 详情页查看每轮检查的状态、提交的任务
也可以在 Playlist 详情页点击「开始监控」快捷入口来启动。
- 访问
/prompts - 点击"+ 新建 Prompt"
- 选择类型(翻译/优化),输入名称和内容
- 保存后在"当前使用的 Prompt"处选择
- 或在 Playlist 详情页为特定 Playlist 配置专属 Prompt
查看错误信息:
- 进入任务详情页查看错误信息
- 查看实时日志定位具体错误
常见原因:
- 网络问题导致下载失败
- GPU 显存不足
- 视频不可用(已删除/私有)
处理方法:
- 点击"重新运行"重试
- 或进入视频详情页单独执行失败的阶段
可能原因:
- 任务刚启动,还未输出进度信息
- 浏览器 SSE 连接断开
处理方法:
- 刷新页面重新建立连接
- 检查任务是否仍在运行(查看进程状态)
可能原因:
- Playlist URL 无效
- 网络/代理问题
- YouTube 限流(429 错误)
处理方法:
- 检查 URL 是否正确
- 检查代理配置
- 稍后重试
可能原因:
- 文件类型不支持
- 文件不存在(处理中断)
处理方法:
- 使用下载功能获取文件
- 重新执行相关阶段生成文件
# 处理单个视频全流程
python -m vat process -v VIDEO_ID -s download,whisper,split,optimize,translate,embed
# 处理多个视频,指定 GPU
python -m vat process -v VIDEO1 -v VIDEO2 -s download,whisper,split -g cuda:0
# 强制重新处理翻译阶段
python -m vat process -v VIDEO_ID -s translate -f
# 并行处理 3 个视频
python -m vat process -v VIDEO1 -v VIDEO2 -v VIDEO3 -c 3| 状态 | 说明 |
|---|---|
| pending | 任务已创建,等待执行 |
| running | 任务正在执行 |
| completed | 任务成功完成(所有视频均成功) |
| partial_completed | 部分完成(批量任务中部分视频成功、部分失败) |
| failed | 任务执行失败(所有视频均失败) |
| cancelled | 任务被用户取消 |
| Web UI 显示 | CLI 阶段名 | 说明 |
|---|---|---|
| 下载 | download | 视频下载 + 信息翻译 |
| 语音识别 | whisper | Whisper ASR |
| 句子分割 | split | LLM 智能断句 |
| 提示词优化 | optimize | 字幕优化 |
| 翻译 | translate | LLM 翻译 |
| 嵌入字幕 | embed | FFmpeg 硬字幕嵌入 |
| 上传 | upload | 上传到 B 站 |





