fix(cover): 封面标题叠加 — 选标题后用 ffmpeg drawtext 在封面图上叠加文字 #1375
Reference in New Issue
Block a user
Delete Branch "fix/cover-title-overlay"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
根因
封面帧在预览视频渲染时(Step 3)就被抽帧保存为 cover_url,但用户是在渲染之后才选标题(Step 4)。所以 cover_url 天然没标题。
修复方案
轻量方案:在封面 API 返回 cover_url 前,检查 plan.config["title"]["text"] 是否有标题。如果有:
叠加失败时降级使用原 cover_url。
改动
apps/api/app/api/routes/generation_cover.py— 新增_overlay_title_on_cover_image()+_escape_drawtext_text()+ 路由中检查标题并叠加tests/unit/test_cover_title_overlay.py— 12 个新测试测试结果
🚀 预览环境已部署
代码审查结果 - PR #1375
⚠️ 问题(2个需要修改)
apps/api/app/api/routes/generation_cover.py
_overlay_title_on_cover_image函数:存在服务端请求伪造(SSRF)安全风险。requests.get(cover_image_url)下载图片,未对cover_image_url进行域名或协议白名单校验。如果该 URL 来源不可信(如用户可控的plan.config),攻击者可利用此接口探测内网服务或读取本地文件(如file:///etc/passwd)。cover_image_url的合法性,仅允许访问可信的 CDN 或 OSS 域名。apps/api/app/api/routes/generation_cover.py
_overlay_title_on_cover_image函数:存在阻塞异步事件循环的性能问题。app/api/routes下,通常运行在 FastAPI 异步环境中。代码中使用了同步的requests.get和subprocess.run,且设置了长达 30 秒的超时。httpx)或通过asyncio.to_thread/loop.run_in_executor将阻塞调用移至线程池中执行。💡 建议(2个可选)
apps/api/app/api/routes/generation_cover.py 第 86 行:十六进制颜色格式处理可能存在逻辑缺陷。
font_color.replace("#", "0x")处理颜色。如果输入是简写格式(如#fff),结果为0xfff,FFmpeg 的drawtext滤镜通常要求完整的 6 位十六进制(0xffffff),否则可能无法正确渲染颜色。apps/api/app/api/routes/generation_cover.py 第 135 行:异常捕获过于宽泛。
except Exception:会捕获所有异常,包括KeyboardInterrupt或SystemExit(虽然在此处概率低),且掩盖了具体的配置错误(如font_size类型转换错误)。(requests.RequestException, subprocess.TimeoutExpired, ValueError)等预期异常,避免掩盖意外的程序错误。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-08-15 07:51:52 | 模型:
🗑️ 预览环境已清理
PR #1375 已关闭或合并,对应的预览环境已被清理。