# 视频字幕 API：把课程视频变成可检索段落

**交付类型：独立 Python 程序、HTTP API、Agent 客户端与批处理结果。**

视频学习缺少文本检索入口，逐段翻译也容易在长任务中丢失进度。这个工具接收服务端视频路径或客户端上传，以任务 ID 跟踪进度，并输出带时间戳的原文、中文、字幕文件和 Markdown。

## 从输入到交付

```text
视频路径／上传文件
  → 创建异步任务，返回 HTTP 202 与任务 ID
  → faster-whisper 识别音轨
  → 按停顿、句末、长度和时长合并段落
  → 翻译并逐段保存
  → JSON、SRT、VTT、逐段 Markdown
```

API 与批处理使用同一任务及结果存储。原文识别完成后可以先读取结果，翻译完成以 `translation_complete=true` 为准。重试复用已完成的识别阶段和译文，减少重复处理。

## 几个关键工程选择

| 选择 | 原因 |
|---|---|
| 创建任务立即返回 | 长视频处理不占用一个持续等待的 HTTP 请求 |
| SQLite 任务记录与阶段文件 | 服务重启后能识别中断任务，完成的阶段可以继续使用 |
| 单服务进程、复用模型 | 避免多进程同时占用显存或写同一份状态 |
| 规范化路径并检查允许目录 | 明确服务端路径的访问范围 |
| 独立 Agent 客户端 | 调用者只使用 HTTP，不在自己的进程加载语音模型 |
| 逐段保存译文 | 临时网络错误后可重试尚未完成的部分 |

## Agent 接口

| 方法与路径 | 返回或用途 |
|---|---|
| `POST /api/v1/jobs` | 输入服务端文件路径，返回任务 ID |
| `POST /api/v1/jobs/upload` | multipart 上传并创建任务 |
| `GET /api/v1/jobs/{id}` | 状态、阶段进度、错误和下载地址 |
| `GET /api/v1/jobs/{id}/result` | 时间戳、原文片段、中英段落 |
| `POST /api/v1/jobs/{id}/retry` | 复用完成阶段重试或补做翻译 |
| `POST /api/v1/jobs/{id}/cancel` | 取消任务 |

路径提交示例（`lesson.mp4` 位于自行配置的服务端视频目录）：

```json
{
  "video_path": "lesson.mp4",
  "language": "en",
  "translate": true,
  "paragraph_max_chars": 600,
  "paragraph_max_seconds": 45,
  "paragraph_pause_seconds": 1.2
}
```

完整接口结构可下载 [OpenAPI JSON](<../downloads/subtitle-openapi.json>)。

## 已有结果与证据

本次批处理完成 **13 个视频、2216 个中英段落**，每个视频一份 Markdown。批处理使用 faster-whisper base 和本地 Argos en→zh 1.9 翻译模型；通用服务也支持另行配置兼容 Chat Completions 的翻译接口。

[批处理核验摘要](<../evidence/subtitles.json>)保留各文件的处理状态、段落数量、时长与输出文件哈希。公开网站不转载完整课程字幕，原视频和相关资料在[来源记录](<../sources.html#videos>)回查。

单个 30 秒片段的早期 CPU/base 实测得到 4 条原文片段、2 个段落，含模型加载约 5.4 秒。这是特定片段的运行记录，不能外推为所有视频的处理速度。

## 可复用交付

- [下载独立字幕程序](<../downloads/subtitle-service.zip>)
- [安装与调用说明](<../字幕服务复现.md>)
- [查看交付与验证范围](<../evidence.html>)

程序源码包包括核心服务、网页工作台、Agent 客户端和测试，配置与模型由使用者自行准备。此页面是作品展示入口，运行程序后才可以上传视频和调用 API。

## 本次验证的边界

规则分段不等同于语义章节理解。机器识别和翻译可能误译专有名词、代码与数字；有时间戳和原文不代表内容已经人工校对。相同音轨的两个文件已标记重复。字幕 API 的工程测试与某个外部翻译供应商的实际质量测试也分别记录。
