fix: 修复自由创作首尾帧上传人脸图不通过问题

This commit is contained in:
hh
2026-07-09 11:39:54 +08:00
parent 5c9e62a165
commit a82f90d0e0
11 changed files with 357 additions and 100 deletions
+9 -2
View File
@@ -165,7 +165,8 @@ def build_content_items(*, team, prompt: str, mode: str, references: list) -> di
source = str(ref.get("source") or "upload")
duration = float(ref.get("duration") or 0)
dedupe_key = url or f"{source}:{ref.get('asset_id') or ref.get('group_id')}"
dedupe_base = url or f"{source}:{ref.get('asset_id') or ref.get('group_id')}"
dedupe_key = f"{role}:{dedupe_base}" if mode == "keyframe" else dedupe_base
if dedupe_key in seen_urls:
continue
seen_urls.add(dedupe_key)
@@ -197,7 +198,13 @@ def build_content_items(*, team, prompt: str, mode: str, references: list) -> di
raise ValueError(f"素材「{label or fa.name}」尚未就绪,请稍后重试")
resolved_url = f"asset://{_normalize_remote_asset_id(fa.remote_asset_id)}"
kind = {"Video": "video", "Audio": "audio"}.get(fa.asset_type, "image")
asset_type = _push(kind, resolved_url, "reference_video" if kind == "video" else ("reference_audio" if kind == "audio" else "reference_image"), fa.duration or 0.0)
if mode == "keyframe":
if kind != "image":
raise ValueError("首尾帧模式仅支持图片素材")
effective_role = role if role in {"first_frame", "last_frame"} else "first_frame"
else:
effective_role = "reference_video" if kind == "video" else ("reference_audio" if kind == "audio" else "reference_image")
asset_type = _push(kind, resolved_url, effective_role, fa.duration or 0.0)
if label and label not in label_to_placeholder:
label_to_placeholder[label] = _placeholder_for(asset_type)
continue
+46
View File
@@ -10,6 +10,7 @@ from django.test import TestCase
from rest_framework.test import APIClient
from apps.accounts.models import Team, TeamMember, User
from apps.assets.models import FreeAsset, FreeAssetGroup
from apps.ai.free_video import (
build_content_items,
finalize_free_video,
@@ -113,6 +114,51 @@ class BuildContentItemsTests(TestCase):
built = build_content_items(team=self.team, prompt="p", mode="keyframe", references=refs)
self.assertEqual([i["role"] for i in built["content_items"]], ["first_frame", "last_frame"])
def test_keyframe_library_image_keeps_role_and_uses_asset_url(self):
group = FreeAssetGroup.objects.create(team=self.team, name="角色", remote_group_id="Group-1")
first = FreeAsset.objects.create(
group=group,
name="",
url="http://x/first.png",
remote_asset_id="Asset-FIRST",
asset_type=FreeAsset.Type.IMAGE,
status=FreeAsset.Status.ACTIVE,
)
last = FreeAsset.objects.create(
group=group,
name="",
url="http://x/last.png",
remote_asset_id="asset-last",
asset_type=FreeAsset.Type.IMAGE,
status=FreeAsset.Status.ACTIVE,
)
refs = [
{"url": first.url, "type": "image", "role": "first_frame", "asset_id": str(first.id), "source": "library"},
{"url": last.url, "type": "image", "role": "last_frame", "asset_id": str(last.id), "source": "library"},
]
built = build_content_items(team=self.team, prompt="p", mode="keyframe", references=refs)
self.assertEqual([i["role"] for i in built["content_items"]], ["first_frame", "last_frame"])
self.assertEqual(
[i["image_url"]["url"] for i in built["content_items"]],
["asset://asset-FIRST", "asset://asset-last"],
)
def test_keyframe_library_video_rejected_even_if_ref_claims_image(self):
group = FreeAssetGroup.objects.create(team=self.team, name="角色", remote_group_id="Group-1")
asset = FreeAsset.objects.create(
group=group,
name="视频",
url="http://x/v.mp4",
remote_asset_id="Asset-VIDEO",
asset_type=FreeAsset.Type.VIDEO,
status=FreeAsset.Status.ACTIVE,
)
refs = [
{"url": asset.url, "type": "image", "role": "first_frame", "asset_id": str(asset.id), "source": "library"},
]
with self.assertRaisesMessage(ValueError, "仅支持图片素材"):
build_content_items(team=self.team, prompt="p", mode="keyframe", references=refs)
def test_too_many_images_rejected(self):
refs = [{"url": f"http://x/{i}.png", "type": "image"} for i in range(10)]
with self.assertRaisesMessage(ValueError, "最多 9 张"):