fix: 修复自由创作首尾帧上传人脸图不通过问题
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 张"):
|
||||
|
||||
Reference in New Issue
Block a user