41 lines
1.9 KiB
Markdown
41 lines
1.9 KiB
Markdown
# 后台转码链路打通
|
||
|
||
## 现状取证
|
||
|
||
- 上传完成时 `MediaService.complete` 已为视频调用 `TranscodeService.enqueue`。
|
||
- 分集创建/替换视频地址时 `EpisodeService` 已调用
|
||
`EpisodeTranscodeBindingService.bind`,会复用并绑定同一媒体的未完成任务。
|
||
- 转码失败原因已写入 `transcode_task.error_msg`,最终状态写入 `status`。
|
||
- 缺口是后台手动触发/重转接口,以及对应幂等和链路测试。
|
||
|
||
## 实现
|
||
|
||
1. 保留上传完成和改片自动入队逻辑,补测试锁定行为。
|
||
2. `TranscodeService` 增加手动触发:
|
||
- QUEUED/RUNNING 直接返回现有任务;
|
||
- FAILED 重置原任务为 QUEUED;
|
||
- SUCCESS 才创建新任务,紧接着重复触发会复用新 QUEUED 任务。
|
||
3. 新增 `POST /admin/media/{id}/transcode`,校验媒资存在,复用 `episode:upload`。
|
||
4. 返回任务 id 与状态,便于后台提示。
|
||
|
||
实现时对同一媒资行使用 `FOR UPDATE`,让重复请求在事务内串行判定;
|
||
平台不存在的媒资保持 `DATA_NOT_FOUND`,不产生任务或 500。
|
||
|
||
## TDD 测试矩阵
|
||
|
||
| 场景 | 断言 |
|
||
| --- | --- |
|
||
| 视频上传完成 | `MediaService.complete` 调用一次 `enqueue(assetId, 0, 0, sourceUrl)` |
|
||
| 图片上传完成 | 不创建转码任务 |
|
||
| 手动触发成功媒资 | 新建一个 QUEUED 任务,重复调用复用同一任务 |
|
||
| 手动触发进行中媒资 | 直接返回 QUEUED/RUNNING 任务,不新增记录 |
|
||
| 手动触发失败媒资 | 原任务重置为 QUEUED,保留任务 id |
|
||
| 媒资不存在 | 返回既有 `DATA_NOT_FOUND`,控制器不产生 500 |
|
||
| worker 最终失败 | 任务状态 FAILED,`error_msg` 保留 ffmpeg 原因 |
|
||
|
||
## 验证
|
||
|
||
- 先提交失败测试,再提交实现。
|
||
- `mvn -pl fruitshorts-module-media,fruitshorts-transcode-worker test`
|
||
- 不启停任何服务,不执行数据库变更,不改 Web/Flutter/specs/API 文档。
|