hl-api-changelog/changelogs/2026-07/13_fix_grassland_guide_mp4_progressive_gate.md
2026-07-13 22:31:33 +08:00

5.6 KiB

草原指南视频上传校验与服务端时长

日期2026-07-13

后端 IssueHL #4949

后端 PRHL #4961HL #4962HL #4964

测试合并:HL #4963HL #4965,均按 devdev-v3 进入 TEST

当前状态TEST 已部署并通过真实 4K 上传确认;尚未合入 main、尚未部署正式环境

1. 本文件只说明视频上传链路

删除功能、登录鉴权、产品绑定等接口分别由各自 changelog 说明,不与本次上传校验混写。

本次仅影响素材库顶级分类 grassland_guide 下的 MP4 视频:

  • 视频仍由前端直传 OSS,字节不经过 Resource/User Java 服务。
  • 播放仍使用详情接口返回的 OSS MP4 地址,不接入 CDN、VOD、直播或 HLS。
  • 不转码、不降低 4K 清晰度、不提供清晰度切换。
  • 后端自动读取视频时长;管理端不得提供可编辑时长输入框。

2. 获取上传凭证

POST /admin/material/upload/token

{
  "categoryCode": "grassland_guide",
  "materialName": "呼伦贝尔草原上的风为什么特别大?",
  "filename": "hulunbuir-wind-4k.mp4",
  "fileSize": 412400073,
  "md5": "32位文件MD5",
  "contentType": "video/mp4"
}

前端注意:

  • 草原指南视频不提交 durationSeconds;即使提交,后端也会忽略。
  • 几百 MB 视频按响应中的 uploadMode=STS_MULTIPART 分片直传 OSS。
  • 不调用旧的 /admin/material/chunk/** 完成草原指南视频上传。
  • 若响应为秒传,后端也会重新核对文件类型、大小、OSS Content-Type 和媒体结构。

3. 确认上传

POST /admin/material/upload/confirm

{
  "materialId": "2076195939797688322",
  "description": "草原指南视频",
  "tagIds": []
}

后端确认时只读取 OSS 对象元数据、MP4 顶层 box 和 moov,不下载 mdat 视频内容,并校验:

  • OSS 对象存在,实际大小与申请一致,Content-Typevideo/mp4
  • MP4 满足 ftyp < moov < mdat,可进行 faststart 渐进播放。
  • 恰好包含一条 H.264 视频轨和一条 AAC-LC 音频轨。
  • moov 自动计算并保存 durationSeconds

确认成功后,素材返回:

{
  "durationSeconds": 312,
  "mediaStatus": "OSS_MP4_READY_V1",
  "storageProvider": "OSS",
  "ossUrl": "https://<bucket-domain>/<object-key>"
}

durationSecondsmediaStatusstorageProviderossUrl 都是只读字段。mediaStatus 成功值只返回 OSS_MP4_READY_V1,前端不要增加其他成功状态分支。

4. 错误处理

业务码 含义 前端处理
250015 OSS 元数据或 Range 探测暂时不可用,或并发状态发生变化 保留当前 materialId,允许稍后重复调用确认接口
250016 文件不是支持的 faststart H.264 + AAC-LC MP4 展示后端原因,要求管理员重新选择处理后的文件上传

同一上传人对已确认的草原指南视频重复调用确认接口会幂等返回;普通素材的确认行为不变。

5. 使用门禁与历史兼容

  • 新建草原指南内容时,videoMaterialId 必须绑定 OSS_MP4_READY_V1 视频素材。
  • 编辑时只有替换 videoMaterialId 才校验新素材;未替换的历史视频不追溯阻断。
  • 单个或批量移动素材分类不执行媒体门禁,也不会自动把普通历史视频标记为 OSS_MP4_READY_V1
  • 图片素材、普通分类视频和其他模块的上传行为不变。

6. 播放验收边界

该校验只证明文件具备基础渐进播放结构,不承诺所有微信版本、所有 Android/iOS 设备都能流畅解码 4K 原片,也不把后端结构校验描述为“已解决音画同步”。

上线前必须用真实原片和无损 faststart 重排文件,在目标微信 Android/iOS 真机完成播放、拖动、暂停恢复和音画同步 A/B 验收。

7. 前端联调清单

  • 后端 OpenAPI 与真实请求确认:上传凭证不需要草原指南视频 durationSeconds
  • 412400073 字节真实 4K 文件使用 STS_MULTIPART 直传 OSS。
  • 管理端时长只读展示确认接口返回值。
  • 原始 moov 位于文件尾部的视频确认返回 250016
  • 无损 faststart 重排后的真实 4K 原片确认成功并返回 OSS_MP4_READY_V1durationSeconds=83 和自动封面。
  • 首次确认因 fat JAR 类加载问题失败后,使用同一个 materialId=2076658080942116865 重试成功,未重复上传 412 MB 文件。
  • 新建草原指南已实测只接受 OSS_MP4_READY_V1 视频;历史原素材不变时仍可维护。
  • 微信 Android/iOS 真机完成原片与重排文件的 A/B 验收。

8. TEST 真实验证记录

  • User 部署任务:1a2a42dadev-v3,8081/8181 双实例滚动成功;Nacos test 命名空间两实例均为 healthy=trueenabled=true
  • 素材:2076658080942116865,文件大小 412400073,存储方 OSS,媒体状态 OSS_MP4_READY_V1,服务端时长 83 秒,自动封面存在。
  • fat JAR 回归:通过 Spring Boot PropertiesLauncher 直接加载最终候选 JAR,并解析同一真实 4K moov,返回 durationSeconds=83 / OSS_MP4_READY_V1
  • OSS Range请求 bytes=0-1023 返回 HTTP 206、1024 字节和 Content-Range
  • 仍未据此宣称真机音画同步通过;默认 Bucket 域名的微信 Android/iOS 真机播放、拖动、暂停恢复与音画同步必须由前端单独验收。