fix(media): 修正转码媒资 id 解析与存量分集补登记

This commit is contained in:
Zhou Weidong committed 2026-10-22 14:59:16 +08:00
1 parent a35b02dd18
commit 5ef5dd8eaf
11 files changed
+427 -31

No files matched your search

@@ -0,0 +1,28 @@
# 转码媒资 ID 精度与存量兜底修复
## 取证
- 示例分集 `2113150431755636737` 的 `video_asset_id` 为
`2113150398670966786`,与 `media_asset.id` 完全一致。
- JS `Number('2113150398670966786')` 序列化为 `2113150398670966800`,
超出安全整数后发生精度丢失,导致手动转码查询了错误 ID。
## 修复
1. 聚合响应的 episodeId/mediaAssetId/taskId 使用字符串。
2. 手动转码仍由后端 Long 接收精确路径 ID。
3. 媒资不存在时通过 content 模块的端口按候选 ID 查找分集:
- 分集 id;
- video_asset_id;
- transcode_task.id。
4. 找到分集后按 video_url/source_url/objectKey 反查媒资;
文件存在但媒资缺失时补登记并回填分集 video_asset_id。
5. 无可用视频时保持明确空态/错误语义。
## 验证
- 超 2^53 ID 字符串契约。
- 聚合无媒资空态。
- video_url 反查命中。
- 文件存在时补登记。
- `mvn -pl fruitshorts-module-media,fruitshorts-transcode-worker test`。
+89
View File
@@ -25460,3 +25460,92 @@ $ mvn -pl fruitshorts-module-media,fruitshorts-transcode-worker test
解读:P2 查询测试、worker 入队/失败回写测试和新增宽高比 smoke 全部通过。
未启停服务、未执行数据库变更、未改前端/App/specs 或 P2 接口字段。
## 2026-10-22 转码媒资 ID 精度与存量兜底
- 分支:`feature/transcode-media-id-fix`
- 基线:`develop` / `origin/develop` = `a35b02d`
### 现场取证
数据库只读查询确认:
```text
drama_episode.id = 2113150431755636737
drama_episode.video_asset_id = 2113150398670966786
media_asset.id = 2113150398670966786
transcode_task.media_asset_id= 2113150398670966786
```
JS 精度复现:
```text
raw: 2113150398670966786
Number(raw): 2113150398670966800
serialized: 2113150398670966800
same: false
```
解读:错误来自前端 Number 转换后的 Snowflake ID 精度丢失;后端兜底仍需覆盖
存量分集 video_asset_id 为空或误传分集/任务 ID 的情况。
### TDD 红测
```text
$ mvn -pl fruitshorts-transcode-worker -am \
-Dtest=MediaServiceTranscodePipelineTest \
-Dsurefire.failIfNoSpecifiedTests=false test
[ERROR] 找不到符号: 类 EpisodeVideoSourcePort
[INFO] BUILD FAILURE
$ mvn -pl fruitshorts-admin-api -am \
-Dtest=EpisodeTranscodeAdminServiceTest,EpisodeTranscodeContractTest \
-Dsurefire.failIfNoSpecifiedTests=false test
[ERROR] String 无法转换为 Long
[ERROR] 找不到符号: 方法 mediaAssetExists(Long)
[INFO] BUILD FAILURE
```
解读:红测先锁定字符串契约和跨域分集来源端口,生产代码尚未实现。
### 实现
- `EpisodeVideoSourcePort` 由 content 域 `EpisodeService` 实现,可按分集 id 或
`video_asset_id` 找到分集来源,并回填 `video_asset_id`。
- 手动转码先按 media_asset.id 锁定;未命中时通过端口找到分集,
按 video_url → source_url/objectKey 反查媒资。
- 仍缺失但本地文件真实存在时自动补登记 `media_asset`,再调用原转码入队。
- 聚合接口先按 video_url 解析媒资,失败才校验 `video_asset_id`;
episodeId/mediaAssetId/taskId 均显式转字符串。
- 无媒资空态返回 `NO_MEDIA_ASSET` 和可读 errorMsg。
### 定向测试
```text
$ mvn -pl fruitshorts-transcode-worker -am \
-Dtest=MediaServiceTranscodePipelineTest \
-Dsurefire.failIfNoSpecifiedTests=false test
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
$ mvn -pl fruitshorts-admin-api -am \
-Dtest=EpisodeTranscodeAdminServiceTest,EpisodeTranscodeContractTest \
-Dsurefire.failIfNoSpecifiedTests=false test
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
### 最终门禁
```text
$ mvn -pl fruitshorts-module-media,fruitshorts-transcode-worker test
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] Tests run: 37, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
$ mvn -pl fruitshorts-admin-api -am test
[INFO] Tests run: 53, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
解读:精度字符串、空态、video_url 反查命中、文件存在补登记及原有转码链全部通过。