fix(cover): extract cover from source asset when no backend preview exists #1459

Merged
xiaoxia merged 3 commits from fix/cover-extract-from-source-asset into develop 2026-08-22 23:15:34 +08:00
Owner

问题

前端预览已改为纯 Canvas/WebCodecs 浏览器内渲染,不产生后端 GenerationTask 或渲染视频。封面 API 的步骤 A-D 全部依赖后端产物(cover_url / cover_candidates),全部落空后返回 400。

此外,原代码在进入 A-D 之前还有一道早期 rendered_storage_key 400 闸门,即使有素材也无法进入兜底抽帧逻辑。

改动

  1. 移除 ai_frame/ai_regenerate 对 rendered_storage_key 的强制要求:找不到渲染视频不立即 400,继续进入封面查找管道。
  2. 步骤 E1:有渲染视频 URL 但 cover_url 未持久化(历史数据)时,直接对渲染视频抽一帧。
  3. 步骤 E2(核心修复):无后端预览时,从 asset_ids 中选取第一个视频素材,直接对源素材 URL 调 MediaKit 抽帧,转存到 OSS covers/ 路径。
  4. 新增 _persist_cover_frame 工具函数:下载 MediaKit 临时帧图并上传 OSS。
  5. 最终 400 文案改为准确的:"封面生成失败:未找到可抽帧的视频素材..."
  6. 清理 staging 测试 plan ec4071eb 中已 404 的陈旧 rendered_storage_key

测试

  • 新增 2 个单测:源素材抽帧成功 / 仅图片素材跳过并 400
  • 更新 1 个已有 400 测试(模拟 MediaKit 返回 None)
  • 全量 cover 单测 24 passed
## 问题 前端预览已改为纯 Canvas/WebCodecs 浏览器内渲染,不产生后端 GenerationTask 或渲染视频。封面 API 的步骤 A-D 全部依赖后端产物(cover_url / cover_candidates),全部落空后返回 400。 此外,原代码在进入 A-D 之前还有一道早期 `rendered_storage_key` 400 闸门,即使有素材也无法进入兜底抽帧逻辑。 ## 改动 1. **移除 ai_frame/ai_regenerate 对 rendered_storage_key 的强制要求**:找不到渲染视频不立即 400,继续进入封面查找管道。 2. **步骤 E1**:有渲染视频 URL 但 cover_url 未持久化(历史数据)时,直接对渲染视频抽一帧。 3. **步骤 E2(核心修复)**:无后端预览时,从 `asset_ids` 中选取第一个视频素材,直接对源素材 URL 调 MediaKit 抽帧,转存到 OSS covers/ 路径。 4. 新增 `_persist_cover_frame` 工具函数:下载 MediaKit 临时帧图并上传 OSS。 5. 最终 400 文案改为准确的:"封面生成失败:未找到可抽帧的视频素材..." 6. 清理 staging 测试 plan `ec4071eb` 中已 404 的陈旧 `rendered_storage_key`。 ## 测试 - 新增 2 个单测:源素材抽帧成功 / 仅图片素材跳过并 400 - 更新 1 个已有 400 测试(模拟 MediaKit 返回 None) - 全量 cover 单测 24 passed
xiaoxia added 1 commit 2026-08-22 22:48:17 +08:00
fix(cover): extract cover from source asset when no backend preview exists
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 40s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 45s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m37s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m47s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m51s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m16s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m40s
AI Code Review / AI Code Review (pull_request) Successful in 2m37s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m50s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m40s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
035e589dfc
The frontend now renders preview entirely in-browser via Canvas/WebCodecs,
so there is no backend GenerationTask or rendered video for the cover
pipeline to read. Steps A-D all rely on backend-rendered artifacts.

- Remove early 400 gate on missing rendered_storage_key for ai_frame
- Add step E1: extract a frame from rendered video URL when available
  but cover_url was not persisted (legacy data)
- Add step E2: when no backend preview exists, pick the first video
  asset from asset_ids and ask MediaKit to extract a frame directly
- Add _persist_cover_frame helper to download MediaKit frame and
  re-upload to OSS covers/ path for a stable public URL
- Update final 400 message to reflect the real cause
- Add 2 unit tests covering source-asset extraction and non-video skip
- Clean stale rendered_storage_key on test plan ec4071eb

🚀 预览环境已部署

项目 详情
PR号 #1459
预览链接 https://pr-1459.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1459 | | 预览链接 | [https://pr-1459.preview.xiaoxiajianji.com](https://pr-1459.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
auto-approve-bot added 1 commit 2026-08-22 22:52:03 +08:00
style: auto-format with black + isort + prettier [skip ci-format-check]
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 49s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m26s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 32s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m42s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m46s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m47s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m43s
AI Code Review / AI Code Review (pull_request) Failing after 2m52s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m28s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m43s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m21s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m51s
CI/CD Pipeline / CI Gate (pull_request) Successful in 8s
76df0de8a4
auto-approve-bot approved these changes 2026-08-22 23:00:30 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-22 23:00:30 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia added 1 commit 2026-08-22 23:06:09 +08:00
fix(cover): address AI review - temp file cleanup + per-asset error handling
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 47s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 32s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m37s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m46s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m6s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m13s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m28s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m39s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m57s
AI Code Review / AI Code Review (pull_request) Successful in 4m19s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m42s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m18s
CI/CD Pipeline / CI Gate (pull_request) Successful in 8s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 55s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m24s
93540f904c
- _persist_cover_frame: use try/finally to ensure temp file is always cleaned up
- Step E2: move try/except inside loop so single asset failure doesn't block others
Collaborator

代码审查结果 - PR #1459

⚠️ 问题(3个需要修改)

  1. apps/api/app/api/routes/generation_cover.py 第386行:存在资源耗尽风险,for aid in body.asset_ids 循环未对迭代次数做限制。如果用户传入包含大量ID的数组,会导致频繁的数据库查询和外部API调用,可能造成服务响应缓慢甚至拒绝服务。
  2. apps/api/app/api/routes/generation_cover.py 第92行:逻辑错误,数据一致性风险。当 storage.upload_file 成功但 storage.get_url 返回 None 时,代码回退返回了原始的 frame_url。这会导致OSS中已存储的文件无法被引用,同时返回的临时URL可能很快失效,造成封面丢失。
  3. apps/api/app/api/routes/generation_cover.py 第74行:逻辑错误。当下载的图片内容为空(not resp.content)时,直接返回原始 frame_url 是不合理的,这说明上游服务返回了异常数据,应视为失败处理,否则可能将无效链接存入数据库。

💡 建议(2个可选)

  1. apps/api/app/api/routes/generation_cover.py 第70-73行:建议将 import tempfile, import uuid 等库的导入语句移至文件顶部。虽然在函数内导入可以避免循环依赖或减少启动开销,但在频繁调用的热路径函数中,重复导入会带来微小的性能损耗。
  2. apps/api/app/api/routes/generation_cover.py 第386行:建议在步骤 E2 的循环中增加对 mk_client.is_available 的检查。虽然循环外已检查,但如果循环耗时较长,期间服务状态可能发生变化,双重检查更稳健。

逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-08-22 15:10:28 | 模型:

## 代码审查结果 - PR #1459 ### ⚠️ 问题(3个需要修改) 1. **apps/api/app/api/routes/generation_cover.py 第386行**:存在资源耗尽风险,`for aid in body.asset_ids` 循环未对迭代次数做限制。如果用户传入包含大量ID的数组,会导致频繁的数据库查询和外部API调用,可能造成服务响应缓慢甚至拒绝服务。 2. **apps/api/app/api/routes/generation_cover.py 第92行**:逻辑错误,数据一致性风险。当 `storage.upload_file` 成功但 `storage.get_url` 返回 `None` 时,代码回退返回了原始的 `frame_url`。这会导致OSS中已存储的文件无法被引用,同时返回的临时URL可能很快失效,造成封面丢失。 3. **apps/api/app/api/routes/generation_cover.py 第74行**:逻辑错误。当下载的图片内容为空(`not resp.content`)时,直接返回原始 `frame_url` 是不合理的,这说明上游服务返回了异常数据,应视为失败处理,否则可能将无效链接存入数据库。 ### 💡 建议(2个可选) 1. **apps/api/app/api/routes/generation_cover.py 第70-73行**:建议将 `import tempfile`, `import uuid` 等库的导入语句移至文件顶部。虽然在函数内导入可以避免循环依赖或减少启动开销,但在频繁调用的热路径函数中,重复导入会带来微小的性能损耗。 2. **apps/api/app/api/routes/generation_cover.py 第386行**:建议在步骤 E2 的循环中增加对 `mk_client.is_available` 的检查。虽然循环外已检查,但如果循环耗时较长,期间服务状态可能发生变化,双重检查更稳健。 --- ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-22 15:10:28 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia merged commit a11178eb13 into develop 2026-08-22 23:15:34 +08:00

🗑️ 预览环境已清理

PR #1459 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1459 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.