feat: 视频封面生成 + 视频倒放 + 贴纸叠加 三个渲染能力 #305

Merged
xiaoxia merged 2 commits from feat/cover-reverse-sticker into develop 2026-07-14 11:05:04 +08:00
Owner

功能概述

三个新的视频渲染能力,全部纯 FFmpeg 实现,不引入新服务,默认关闭向后兼容,失败降级不阻断主流程。

核心设计

1. 视频封面生成(cover_generator.py)

  • 三种模式:指定时间抽帧 / 智能封面 / 自定义上传
  • 指定时间点:默认第1秒,支持时间钳制(超长取中间帧,负时间取0)
  • 智能封面:视频中均匀抽3帧(跳过首尾5%),用文件大小近似判断清晰度,选最清晰的一帧
  • 自定义封面:自动调整尺寸到标准 1080x1920,格式转 JPEG
  • 独立工具模块,不侵入渲染主链路,可单独调用

2. 视频倒放(reverse_engine.py)

  • 视频倒放:基于 FFmpeg reverse 滤镜
  • 音频倒放:基于 FFmpeg areverse 滤镜
  • 按 clip 分段倒放:每个 clip 独立配置,支持只倒视频或只倒音频
  • 安全限制:单 clip 超过 120s 自动跳过,防止 reverse 滤镜内存溢出
  • 配置从 clip.config.reverse 读取,零侵入数据模型

3. 贴纸叠加(sticker_engine.py)

  • 图片贴纸:PNG/GIF 叠加,支持 位置/大小/透明度/时间范围/淡入淡出
  • 文字贴纸(花字):字体/颜色/描边/阴影/位置/时间范围/淡入淡出动画
  • 9宫格位置预设 + 自由坐标(像素或百分比)
  • 多贴纸叠加:按 z_index 排序依次叠加
  • 5个预设分类:表情包/文字花字/装饰/箭头指示/边框
  • 降级策略:素材不存在/配置无效时自动跳过,不阻断渲染

改动范围

  • 新增 apps/worker/video_processing/cover_generator.py — 封面生成器
  • 新增 apps/worker/video_processing/reverse_engine.py — 倒放引擎
  • 新增 apps/worker/video_processing/sticker_engine.py — 贴纸引擎
  • 修改 apps/worker/video_processing/unified_render_service.py
    • Step 1 预处理接入视频倒放(filter_complex + 直通双路径)
    • 最终合成后、字幕前接入贴纸叠加
    • 有贴纸时禁用直通模式(图片贴纸需要额外输入)
    • 新增 _build_sticker_filters 辅助方法
  • 修改 apps/worker/video_processing/render_audio.py
    • 单 clip + 多 clip 双路径接入音频倒放
  • 新增 tests/unit/test_cover_reverse_sticker.py — 59个单测

单测数量

  • 59个新增单测,全部通过
  • 全套 1494 个测试零回归

接口文档

封面生成调用

from video_processing.cover_generator import CoverGenerator

# 指定时间抽帧
CoverGenerator.extract_frame(video_path, output_path, time_sec=2.0)

# 智能封面
CoverGenerator.extract_smart_cover(video_path, output_path, frame_count=3)

# 自定义封面
CoverGenerator.process_custom_cover(image_path, output_path)

# 统一入口
CoverGenerator.generate_cover(video_path, output_path, mode="smart")

倒放配置(clip.config.reverse)

{
  "enabled": true,
  "reverse_video": true,
  "reverse_audio": true
}

贴纸配置(plan.config.stickers)

[
  {
    "type": "image",
    "image_path": "/path/to/sticker.png",
    "position": "top_right",
    "scale": 0.5,
    "opacity": 0.8,
    "start_time": 1.0,
    "duration": 3.0,
    "fade_in": 0.3,
    "fade_out": 0.3,
    "z_index": 10
  },
  {
    "type": "text",
    "text": "太棒了!",
    "font_size": 48,
    "font_color": "#FFFFFF",
    "stroke_color": "#000000",
    "stroke_width": 2,
    "position": "bottom_center",
    "start_time": 0.0,
    "duration": 5.0,
    "z_index": 20
  }
]
## 功能概述 三个新的视频渲染能力,全部纯 FFmpeg 实现,不引入新服务,默认关闭向后兼容,失败降级不阻断主流程。 ## 核心设计 ### 1. 视频封面生成(cover_generator.py) - **三种模式**:指定时间抽帧 / 智能封面 / 自定义上传 - **指定时间点**:默认第1秒,支持时间钳制(超长取中间帧,负时间取0) - **智能封面**:视频中均匀抽3帧(跳过首尾5%),用文件大小近似判断清晰度,选最清晰的一帧 - **自定义封面**:自动调整尺寸到标准 1080x1920,格式转 JPEG - 独立工具模块,不侵入渲染主链路,可单独调用 ### 2. 视频倒放(reverse_engine.py) - **视频倒放**:基于 FFmpeg reverse 滤镜 - **音频倒放**:基于 FFmpeg areverse 滤镜 - **按 clip 分段倒放**:每个 clip 独立配置,支持只倒视频或只倒音频 - **安全限制**:单 clip 超过 120s 自动跳过,防止 reverse 滤镜内存溢出 - 配置从 `clip.config.reverse` 读取,零侵入数据模型 ### 3. 贴纸叠加(sticker_engine.py) - **图片贴纸**:PNG/GIF 叠加,支持 位置/大小/透明度/时间范围/淡入淡出 - **文字贴纸(花字)**:字体/颜色/描边/阴影/位置/时间范围/淡入淡出动画 - **9宫格位置预设** + 自由坐标(像素或百分比) - **多贴纸叠加**:按 z_index 排序依次叠加 - **5个预设分类**:表情包/文字花字/装饰/箭头指示/边框 - **降级策略**:素材不存在/配置无效时自动跳过,不阻断渲染 ## 改动范围 - 新增 `apps/worker/video_processing/cover_generator.py` — 封面生成器 - 新增 `apps/worker/video_processing/reverse_engine.py` — 倒放引擎 - 新增 `apps/worker/video_processing/sticker_engine.py` — 贴纸引擎 - 修改 `apps/worker/video_processing/unified_render_service.py` - Step 1 预处理接入视频倒放(filter_complex + 直通双路径) - 最终合成后、字幕前接入贴纸叠加 - 有贴纸时禁用直通模式(图片贴纸需要额外输入) - 新增 `_build_sticker_filters` 辅助方法 - 修改 `apps/worker/video_processing/render_audio.py` - 单 clip + 多 clip 双路径接入音频倒放 - 新增 `tests/unit/test_cover_reverse_sticker.py` — 59个单测 ## 单测数量 - **59个新增单测**,全部通过 - 全套 1494 个测试零回归 ## 接口文档 ### 封面生成调用 ```python from video_processing.cover_generator import CoverGenerator # 指定时间抽帧 CoverGenerator.extract_frame(video_path, output_path, time_sec=2.0) # 智能封面 CoverGenerator.extract_smart_cover(video_path, output_path, frame_count=3) # 自定义封面 CoverGenerator.process_custom_cover(image_path, output_path) # 统一入口 CoverGenerator.generate_cover(video_path, output_path, mode="smart") ``` ### 倒放配置(clip.config.reverse) ```json { "enabled": true, "reverse_video": true, "reverse_audio": true } ``` ### 贴纸配置(plan.config.stickers) ```json [ { "type": "image", "image_path": "/path/to/sticker.png", "position": "top_right", "scale": 0.5, "opacity": 0.8, "start_time": 1.0, "duration": 3.0, "fade_in": 0.3, "fade_out": 0.3, "z_index": 10 }, { "type": "text", "text": "太棒了!", "font_size": 48, "font_color": "#FFFFFF", "stroke_color": "#000000", "stroke_width": 2, "position": "bottom_center", "start_time": 0.0, "duration": 5.0, "z_index": 20 } ] ```
xiaoxia force-pushed feat/cover-reverse-sticker from 17ab88ea87 to f83e7db13c 2026-07-14 10:36:51 +08:00 Compare
xiaoxia added 2 commits 2026-07-14 11:02:24 +08:00
fix: black格式化
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 35s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m30s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m31s
CI/CD Pipeline / Build & Push 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 / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Failing after 1m29s
e7a9c08122
xiaoxia force-pushed feat/cover-reverse-sticker from b4dcd72494 to e7a9c08122 2026-07-14 11:02:24 +08:00 Compare
xiaoxia merged commit 8a2d2df3cd into develop 2026-07-14 11:05:04 +08:00
Sign in to join this conversation.