# 灰度对比测试工具 用于统一渲染引擎灰度发布期间的新旧引擎对比验证。 ## 能力 - **像素对比**:基于 FFmpeg SSIM + PSNR 双指标,评估视频画质差异 - **音频对比**:基于差值音频 RMS,评估音频波形差异 - **批量对比**:10个预设场景覆盖 P0/P1/P2 优先级 - **HTML 报告**:可视化对比结果,包含画质、音频、性能三维度 - **两种切换方式**:支持 engine 参数直传 或 Feature Flag 白名单切换 ## 目录结构 ``` tests/render_compare/ ├── __init__.py # 包导出 ├── README.md # 本文档 ├── video_diff.py # 视频像素对比(SSIM + PSNR) ├── audio_diff.py # 音频对比(差值 RMS) ├── scenarios.py # 预定义对比场景(10个) └── runner.py # 批量对比执行器 + HTML 报告生成 ``` ## 快速开始 ### 环境要求 - FFmpeg 4.4+(需带 ssim 和 psnr 滤镜) - Python 3.10+ - httpx(API 调用) ### 配置环境变量 ```bash export STAGING_API_URL=https://api.staging.example.com export STAGING_API_KEY=your_api_key export STAGING_INTERNAL_API_KEY=your_internal_key # 可选,Feature Flag 模式需要 ``` ### 运行对比 ```bash # 运行所有 P0 场景(最核心的5个) python -m tests.render_compare.runner --priority P0 --output ./report/ # 运行 P0 + P1 场景 python -m tests.render_compare.runner --priority P1 --output ./report/ # 只跑指定场景 python -m tests.render_compare.runner --scenarios simple_pass_through,subtitle_rendering # 使用 Feature Flag 方式切换引擎(需要 internal key) python -m tests.render_compare.runner --priority P0 --flag-mode # 自定义阈值 python -m tests.render_compare.runner --priority P0 --ssim-threshold 0.95 --psnr-threshold 30 ``` ## 对比场景 | ID | 名称 | 优先级 | 验证点 | |----|------|--------|--------| | simple_pass_through | 简单直通 | P0 | 直通优化路径正确性 | | multi_clip_transition | 多clip转场 | P0 | 转场效果 + concat | | subtitle_rendering | 字幕渲染 | P0 | ASS字幕渲染 | | independent_audio_track | 独立音频轨 | P0 | 音频混音(amix) | | no_audio_video | 无音轨视频 | P0 | 无音轨防御逻辑 | | picture_in_picture | 画中画 | P1 | overlay 图层 | | multi_layer_mix | 多图层混合 | P1 | 多图层复杂场景 | | image_background | 图片背景 | P1 | background 层 + 无音频 | | long_video_stress | 长视频压力 | P2 | 多clip性能 | | vertical_portrait | 竖屏9:16 | P2 | scale 策略(铺满裁剪) | ## 验收标准(建议) ### 视频质量 - **平均 SSIM >= 0.90**:通过(有微小差异但视觉可接受) - **平均 SSIM >= 0.95**:优秀(视觉几乎无差异) - **平均 PSNR >= 25 dB**:通过 - **分辨率一致 + 时长差 < 0.1s**:通过 ### 音频质量 - **相似度 >= 0.85**:通过 - **采样率/声道数一致**:通过 ### 性能 - **平均性能差异在 ±10% 以内**:可接受 - **直通场景新引擎更快**(预期 +30%) ## API 约定 Runner 默认假设渲染 API 支持以下接口: ### 提交任务 ``` POST /api/v1/render/compose Authorization: Bearer {api_key} Body: { ...plan_payload, "engine": "legacy" | "unified" } Response: { "task_id": "xxx" } ``` ### 查询状态 ``` GET /api/v1/tasks/{task_id} Response: { "status": "completed", "output_url": "...", "duration_sec": 5.2 } ``` ### Feature Flag(flag-mode) ``` PUT /api/v1/internal/feature-flags/render_engine X-API-Key: {internal_key} Body: { "enabled": true, "percentage": 100 } ``` 如果你的 API 接口不同,请修改 `StagingAPI` 类中的对应方法。 ## 故障排查 ### 对比失败定位指南 1. **像素差异大(SSIM < 0.90)** - 检查分辨率是否一致 - 检查帧率是否一致 - 用 `save_diff_frame` 生成差异帧可视化 - 检查转场效果(slideup/slidedown 是新引擎独有) 2. **音频不一致** - 检查音频编码参数(码率、采样率) - 检查主音频源优先级(main > broll) - 用 ffprobe 对比两视频音频流参数 3. **渲染失败** - 检查日志:`[unified-render] render failed` - 检查素材是否完整下载 - 检查 FFmpeg 命令是否正确