P1-1: 一键生成P0效果层补齐 - 模板配置注入(BGM/字幕/ASR) + 直通模式调速修复 #465

Merged
xiaoxia merged 1 commits from feature/unified-gen-effect-layer-p0 into develop 2026-07-17 13:39:39 +08:00
2 changed files with 72 additions and 0 deletions
@@ -759,6 +759,19 @@ class UnifiedRenderService:
plan_config = getattr(self.plan, "config", None) or {}
if isinstance(plan_config, dict) and plan_config.get("stickers"):
return False
# 有水印时禁用直通(图片水印需要额外输入,统一走 filter_complex
try:
from video_processing.watermark_engine import WatermarkConfig
wm_config = WatermarkConfig.from_dict(plan_config.get("watermark"))
if wm_config is not None and wm_config.validate()[0]:
return False
except Exception:
pass
# 有调速时仍然可以走直通(视频调速通过 setpts 实现,单输入即可)
return True
def _can_use_stream_copy(
@@ -971,6 +984,11 @@ class UnifiedRenderService:
filters.append(f"trim=duration={effective_duration}")
filters.append("setpts=PTS-STARTPTS")
# 调速 — 与 filter_complex 路径一致
speed = UnifiedRenderService._clip_speed(clip)
if abs(speed - 1.0) >= 1e-6:
filters.append(f"setpts=PTS/{speed:.4f}")
# 倒放滤镜
reverse_config = ReverseConfig.from_dict(clip.config.get("reverse"))
if reverse_config.enabled and reverse_config.reverse_video:
@@ -774,6 +774,47 @@ def _validate_template_exists(template_id: str) -> None:
session.close()
def _load_template_plan_config(template_id: str) -> dict:
"""从模板加载 plan 级配置(BGM、字幕、滤镜等效果层)。
模板不存在时返回空 dict,不阻塞主流程。
"""
if not template_id:
return {}
try:
from packages.adapters.sqlalchemy_impl.models import TemplateModel
session = SessionLocal()
try:
template = (
session.query(TemplateModel)
.filter(
TemplateModel.id == template_id,
TemplateModel.is_active.is_(True),
)
.first()
)
if template is None:
logger.warning("模板不存在,跳过配置加载: template_id=%s", template_id)
return {}
config = template.config or {}
if isinstance(config, str):
import json
config = json.loads(config)
logger.info(
"模板配置加载成功: template_id=%s keys=%s",
template_id,
list(config.keys()),
)
return config
finally:
session.close()
except Exception as e:
logger.warning("加载模板配置失败,跳过: template_id=%s err=%s", template_id, e)
return {}
# ── 渲染引擎选择 ─────────────────────────────────────────────────────────────
@@ -1032,6 +1073,19 @@ def _render_video(
mode=editing_mode.value,
)
# 注入模板配置(BGM、字幕等效果层)
if template_id:
template_config = _load_template_plan_config(template_id)
if template_config:
# 合并:现有 config 优先级更高(目前为空,模板配置直接生效)
base_config = virtual_plan.config or {}
virtual_plan.config = {**template_config, **base_config}
logger.info(
"[task_id=%s] [渲染] 模板配置已注入: keys=%s",
task_id,
list(template_config.keys()),
)
total_duration = sum(c.duration for c in virtual_clips)
logger.info(
"[task_id=%s] [剪辑计划] 片段数=%d, 总时长=%.1fs",