From c9fc7a8cce4d6b96bd4ec54638fb78166f2d26c8 Mon Sep 17 00:00:00 2001 From: saas-backend-agent Date: Mon, 7 Sep 2026 01:27:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(#1749):=20resolver=20=E7=A9=BA=E5=88=97?= =?UTF-8?q?=E8=A1=A8/=E9=95=BF=E5=BA=A61=E5=BD=92=E4=B8=80=E5=8C=96?= =?UTF-8?q?=EF=BC=88=E7=BB=9F=E4=B8=80=E9=85=8D=E9=9F=B3=E5=8F=A3=E5=BE=84?= =?UTF-8?q?=EF=BC=89+=20p02=20trim=20=E6=B5=8B=E8=AF=95=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=20freeze=20=E6=96=B0=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - voice_library_ids 空列表/全空白视为未提供,修复 count=1 无配音误 400 - 长度 1 且 count>1 视为统一配音(与 cover_urls/titles 口径一致) - 严格校验基于原始长度,缺值/数量不符仍 400 - test_p02_p03 trim 断言更新为新行为:trim=目标段长、tpad 末帧冻结、无慢放 --- packages/domain/variant_voice_resolver.py | 22 ++++++++++++++-------- tests/unit/test_p02_p03_fixes.py | 8 +++++++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/domain/variant_voice_resolver.py b/packages/domain/variant_voice_resolver.py index a13a97aef..c9ca121ed 100644 --- a/packages/domain/variant_voice_resolver.py +++ b/packages/domain/variant_voice_resolver.py @@ -45,23 +45,29 @@ def resolve_variant_voice_ids( raise VariantVoiceError("变体数量 count 必须 >= 1") single = (voice_library_id or "").strip() - multi = [str(v).strip() for v in (voice_library_ids or []) if str(v or "").strip()] + # 归一化:None / 空列表 / 全空白 → 未提供独立配音(走统一配音或无配音) + raw_multi = [str(v or "").strip() for v in (voice_library_ids or [])] + multi = [v for v in raw_multi if v] - if voice_library_ids: - # 显式传了独立配音列表:严格校验,禁止静默 fallback - raw = [str(v or "").strip() for v in voice_library_ids] - if len(raw) != count: + if multi: + # 显式传了独立配音列表: + # - 恰好 1 个非空且 count > 1:视为统一配音(与 cover_urls/titles 长度1=共用一致); + # - 否则按独立配音严格校验:原始长度必须 == count 且逐项非空,禁止静默 fallback; + # - 其余长度/缺值 → 400。 + if len(raw_multi) == 1 and count > 1: + return [multi[0]] * count + if len(raw_multi) != count: raise VariantVoiceError( - f"独立配音数量({len(raw)})与视频数量({count})不一致;" + f"独立配音数量({len(raw_multi)})与视频数量({count})不一致;" f"批量独立配音必须为每个视频分别指定配音,或改用统一配音 voice_library_id" ) - missing = [i for i, v in enumerate(raw) if not v] + missing = [i for i, v in enumerate(raw_multi) if not v] if missing: raise VariantVoiceError( f"第 {[i + 1 for i in missing]} 个视频缺少独立配音 voice_library_id;" f"独立配音不允许缺值,也不会回退为统一配音" ) - return raw + return list(raw_multi) if single: return [single] * count diff --git a/tests/unit/test_p02_p03_fixes.py b/tests/unit/test_p02_p03_fixes.py index 5f96080b8..b19c7b00a 100644 --- a/tests/unit/test_p02_p03_fixes.py +++ b/tests/unit/test_p02_p03_fixes.py @@ -234,12 +234,18 @@ class TestEffectiveDurationTrim: assert "trim=duration=7.5" in fc def test_trim_uses_min_of_duration_and_actual(self): - """clip.duration > actual_duration → trim 到 actual_duration。""" + """#1749:clip.duration > actual_duration → 目标段长为准 + tpad 末帧冻结(禁慢放/禁截断)。""" clip = self._make_clip("c1", duration=10.0, actual_duration=2.0) + # 模拟 _resolve_clips 写入的冻结标记(10s 目标 − 2s 素材 = 8s 冻结) + clip.config = {"_freeze_seconds": 8.0} svc = self._make_service([clip]) layers = svc._group_clips_into_layers([clip]) fc, _ = svc._build_filter_complex(layers) + # 素材内只取 2s,末帧冻结 8s 铺满目标 10s assert "trim=duration=2.0" in fc + assert "tpad=stop_mode=clone:stop_duration=8.0" in fc + # 不再有慢放(setpts 调速系数应为 1.0,即无 setpts=PTS/ 出现) + assert "setpts=PTS/" not in fc def test_no_trim_when_both_zero(self): """duration=0 且 actual_duration=0 → 不做 trim。"""