Compare commits

...

2 Commits

Author SHA1 Message Date
CI Bot 330710d008 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 / Check if frontend-only change (pull_request) Successful in 32s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 42s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m1s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m52s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m9s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m45s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m28s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m32s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 5m56s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 6m59s
AI Code Review / AI Code Review (pull_request) Successful in 7m11s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 9m48s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 14m44s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 16m15s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 19m42s
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 8m36s
CI/CD Pipeline / CI Gate (pull_request) Successful in 7s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 40s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m33s
2026-08-13 16:30:36 +00:00
CI Bot aacf83dc05 fix: videoRatio aspect ratio parsed as resolution causing scale=9:1920
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 / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 27s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 45s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m12s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m54s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m52s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m27s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m11s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m52s
AI Code Review / AI Code Review (pull_request) Failing after 3m54s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 11m8s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 12m55s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (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
Root cause: videoRatio stores aspect ratio format (e.g. "9:16") but
useGenerateVideo.ts parsed it as resolution with .split("x"), causing
parseInt("9:16") to return 9 instead of 1080.

Fixes:
- Frontend: parse aspect ratio (colon format) and compute pixel dims
- Backend worker: guard output_width < 100, fallback to default
- Backend render_adapter: guard width/height < 100 in _parse_resolution
- API schema: add ge=100 validation on ConfirmGenerationRequest
2026-08-14 00:16:36 +08:00
4 changed files with 55 additions and 7 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ from pydantic import BaseModel, Field, field_validator, model_validator
class ConfirmGenerationRequest(BaseModel):
"""确认生成请求体 — 基于预览任务创建正式生成任务"""
output_width: int = Field(default=1080, description="输出视频宽度")
output_height: int = Field(default=1920, description="输出视频高度")
output_width: int = Field(default=1080, ge=100, description="输出视频宽度")
output_height: int = Field(default=1920, ge=100, description="输出视频高度")
cover_url: str = Field(default="", description="自定义封面图片 URL")
custom_title: str = Field(default="", description="自定义视频标题")
@@ -56,10 +56,41 @@ export function useGenerateVideo(props: UseGenerateVideoProps) {
try {
// 使用确认生成 API(基于预览任务)
// 解析分辨率
const [widthStr, heightStr] = (props.videoRatio || "1080x1920").split("x")
const outputWidth = parseInt(widthStr, 10) || 1080
const outputHeight = parseInt(heightStr, 10) || 1920
// 解析分辨率videoRatio 可能是 "9:16"(宽高比)或 "1080x1920"(分辨率)
const ratio = props.videoRatio || "9:16"
let outputWidth: number
let outputHeight: number
if (ratio.includes(":")) {
// 宽高比格式,如 "9:16" → 基于基准高度 1920 计算
const [rw, rh] = ratio.split(":").map(Number)
if (rw > 0 && rh > 0) {
// 基准:长边 1920,短边按比例计算
const [longSide, shortSide] = rw < rh ? [rh, rw] : [rw, rh]
const baseLong = 1920
const baseShort = Math.round((baseLong * shortSide) / longSide)
// 确保偶数(FFmpeg 要求)
const evenShort = baseShort - (baseShort % 2)
if (rw < rh) {
outputWidth = evenShort
outputHeight = baseLong
} else {
outputWidth = baseLong
outputHeight = evenShort
}
} else {
outputWidth = 1080
outputHeight = 1920
}
} else if (ratio.includes("x")) {
// 分辨率格式,如 "1080x1920"
const [wStr, hStr] = ratio.split("x")
outputWidth = parseInt(wStr, 10) || 1080
outputHeight = parseInt(hStr, 10) || 1920
} else {
outputWidth = 1080
outputHeight = 1920
}
await confirmGeneration(props.previewTaskId, {
output_width: outputWidth,
@@ -47,7 +47,14 @@ def _parse_resolution(resolution_str: str | None) -> tuple[int, int]:
w, h = resolution_str.lower().split("x", 1)
width = int(w.strip())
height = int(h.strip())
if width <= 0 or height <= 0:
# 最小 100px 防护:避免前端传入宽高比(如 "9:16")被 parseInt 截断为极小值
if width < 100 or height < 100:
logger.warning(
"分辨率异常小 (%dx%d),使用默认值。原始值: %s",
width,
height,
resolution_str,
)
return DEFAULT_OUTPUT_WIDTH, DEFAULT_OUTPUT_HEIGHT
return width, height
except (ValueError, TypeError):
@@ -1501,6 +1501,16 @@ def generate_video(self, task_id: str) -> dict:
# 动态分辨率:优先使用 output_width/output_height,其次 resolution 字符串
_ow = task_info.get("output_width", OUTPUT_WIDTH) or OUTPUT_WIDTH
_oh = task_info.get("output_height", OUTPUT_HEIGHT) or OUTPUT_HEIGHT
# 防护:前端可能误传宽高比(如 parseInt("9:16") = 9),宽度 < 100 时忽略
if _ow < 100 or _oh < 100:
logger.warning(
"[task_id=%s] output_width/output_height 异常 (%dx%d),回退到默认",
task_id,
_ow,
_oh,
)
_ow = OUTPUT_WIDTH
_oh = OUTPUT_HEIGHT
if _ow != OUTPUT_WIDTH or _oh != OUTPUT_HEIGHT:
_resolved_resolution = f"{_ow}x{_oh}"
else: