fix(P0): unified横屏pad取整+错误日志增强+legacy导入+素材created_at #522

Merged
auto-approve-bot merged 2 commits from fix/p0-unified-horizontal-and-asset-api into develop 2026-07-18 16:55:27 +08:00
6 changed files with 16 additions and 8 deletions
View File
+1
View File
@@ -71,6 +71,7 @@ def _to_asset_response(item, storage_service=None) -> AssetResponse:
status=item.status.value,
classification_status=item.classification_status.value,
quality_score=item.quality_score,
created_at=item.created_at.isoformat() if item.created_at else None,
uploaded_by_user_id=item.uploaded_by_user_id,
tag_ids=getattr(item, "tag_ids", []),
)
+1
View File
@@ -50,6 +50,7 @@ class AssetResponse(BaseModel):
status: str
classification_status: str
quality_score: float | None = None
created_at: str
uploaded_by_user_id: str
tag_ids: list[str] = Field(default_factory=list)
@@ -258,12 +258,12 @@ class RenderAdapter:
plan_id,
job_id,
exc.returncode,
stderr_text[:3000],
stderr_text[-2000:] if len(stderr_text) > 2000 else stderr_text,
)
return RenderAdapterResult(
success=False,
error_message=f"FFmpeg渲染失败(exit={exc.returncode}): {stderr_text[:200]}",
error_detail=stderr_text[:3000],
error_detail=stderr_text[-2000:] if len(stderr_text) > 2000 else stderr_text,
)
except Exception as exc:
logger.exception(
@@ -1008,7 +1008,7 @@ class UnifiedRenderService:
else:
# main / broll: 等比缩放 + 居中留黑边(保持原始比例,不裁剪内容)
filters.append(f"scale={self.output_width}:{self.output_height}" ":force_original_aspect_ratio=decrease")
filters.append(f"pad={self.output_width}:{self.output_height}:(ow-iw)/2:(oh-ih)/2:black")
filters.append(f"pad={self.output_width}:{self.output_height}:trunc((ow-iw)/2):trunc((oh-ih)/2):black")
# 调色滤镜
color_grade = ColorGradeConfig.from_dict(clip.config.get("color_grade"))
@@ -1112,12 +1112,15 @@ class UnifiedRenderService:
try:
run_ffmpeg(command)
except subprocess.CalledProcessError as e:
stderr_text = (e.stderr or "").strip()
stderr_tail = stderr_text[-1500:] if len(stderr_text) > 1500 else stderr_text
logger.error(
"直通渲染失败: plan_id=%s clip=%s exit_code=%d\nvf=%s",
"直通渲染失败: plan_id=%s clip=%s exit_code=%d\nvf=%s\nstderr(last 1500):\n%s",
self.plan.id,
clip.clip_id,
e.returncode,
vf_str[:2000],
stderr_tail,
)
raise
@@ -1342,7 +1345,7 @@ class UnifiedRenderService:
filters.append(
f"scale={self.output_width}:{self.output_height}" ":force_original_aspect_ratio=decrease"
)
filters.append(f"pad={self.output_width}:{self.output_height}:(ow-iw)/2:(oh-ih)/2:black")
filters.append(f"pad={self.output_width}:{self.output_height}:trunc((ow-iw)/2):trunc((oh-ih)/2):black")
# 调色滤镜(每个 clip 独立的 color grade 配置)
color_grade = ColorGradeConfig.from_dict(clip.config.get("color_grade"))
@@ -1576,12 +1579,15 @@ class UnifiedRenderService:
try:
run_ffmpeg(command)
except subprocess.CalledProcessError as e:
# 额外记录 filter_complex,方便排查滤镜链构建问题
# 额外记录 filter_complex + stderr,方便排查滤镜链构建问题
stderr_text = (e.stderr or "").strip()
stderr_tail = stderr_text[-1500:] if len(stderr_text) > 1500 else stderr_text
logger.error(
"渲染失败: plan_id=%s exit_code=%d\nfilter_complex:\n%s",
"渲染失败: plan_id=%s exit_code=%d\nfilter_complex:\n%s\nstderr(last 1500):\n%s",
self.plan.id,
e.returncode,
filter_complex[:5000],
stderr_tail,
)
raise
+1 -1
View File
@@ -1801,7 +1801,7 @@ class TestConcatNormalizeVideoResolution:
# 必须用 pad(留黑边),不能用 crop(裁剪)
assert "force_original_aspect_ratio=decrease" in fc, "main 层应使用 decrease 模式(等比缩放到画布内)"
assert "pad=" in fc, "main 层应有 pad 滤镜(留黑边到目标分辨率)"
assert "(ow-iw)/2:(oh-ih)/2:black" in fc, "pad 应该居中+黑边"
assert "trunc((ow-iw)/2):trunc((oh-ih)/2):black" in fc, "pad 应该居中取整+黑边"
# 注意:background 层也用 crop,但 main/broll 应该用 pad
# 检查第一个 [0:v] 处理链(第一个 clip 是 main)
first_v_chain = fc.split("[v0]")[0]