优化全能创作部分优化脚本
This commit is contained in:
@@ -71,6 +71,9 @@ def model_resolutions(model_config) -> set[str]:
|
||||
RATIOS = {"21:9", "16:9", "4:3", "1:1", "3:4", "9:16"}
|
||||
RESOLUTIONS = {"480p", "720p", "1080p", "4k"}
|
||||
MODES = {"universal", "keyframe"}
|
||||
# 全能创作 / 分镜路用语义 type(character/product/…);对火山仍是参考图。
|
||||
# 旧逻辑只认 image/video/audio,会把商品/角色图静默 skipped → 成片只靠文案「发明」包装。
|
||||
IMAGE_LIKE_REF_TYPES = {"image", "character", "product", "scene", "model", "asset"}
|
||||
IN_FLIGHT_STATUSES = (
|
||||
AITask.Status.CREATED, # 视频复刻审核中也占并发,避免连点刷出一堆待审任务
|
||||
AITask.Status.RESERVED,
|
||||
@@ -300,7 +303,9 @@ def build_content_items(
|
||||
|
||||
# 三库引用(模块4 · 4.1):资产库 / 模特库 / 商品库 挑出来的东西最终都是一行 Asset,
|
||||
# 所以后端只认一种 source=asset,三个库的差别全在前端的 picker 上。
|
||||
if source == "asset" and ref.get("asset_id"):
|
||||
# 全能创作 resolve_refs / 前端常带 type=character|product 且 source 缺省为 upload,
|
||||
# 只要有 asset_id 就按 Asset 解析(含审核态 → asset://),避免直链分支把语义 type skipped。
|
||||
if ref.get("asset_id") and source in {"asset", "upload", ""}:
|
||||
asset = Asset.objects.filter(id=ref["asset_id"], team=team, is_deleted=False).first()
|
||||
if asset is None:
|
||||
raise ValueError(f"素材「{label or '未命名'}」不存在或已被删除")
|
||||
@@ -326,8 +331,9 @@ def build_content_items(
|
||||
|
||||
# 直传素材(已上传 TOS 的直链)。resolved_url 可覆盖为 asset://(官方模特跨团队等)
|
||||
push_url = str(ref.get("resolved_url") or url)
|
||||
if ref_type == "image":
|
||||
if ref_type in IMAGE_LIKE_REF_TYPES:
|
||||
# 参考图模式下所有图 role 必须 reference_image;keyframe 用 first_frame/last_frame
|
||||
# character/product/scene/model/asset 与 image 同等对待(全能创作语义 type)
|
||||
effective_role = "reference_image" if mode == "universal" else (role or "first_frame")
|
||||
asset_type = _push("image", push_url, effective_role)
|
||||
elif ref_type == "video":
|
||||
@@ -356,6 +362,13 @@ def build_content_items(
|
||||
# @label 替换:按 label 长度降序,防子串吞噬
|
||||
ordered = sorted(label_to_placeholder.items(), key=lambda kv: len(kv[0]), reverse=True)
|
||||
api_prompt = _format_prompt_for_ark(prompt, ordered)
|
||||
# 自由创作 / 全能创作是整段一次出片(没有「第 2 段」),开场先验强 ——
|
||||
# 挂上与专业创作首镜相同的正面洁净指令;最终 enforce_no_embedded_captions 还会改写口播并挂禁令。
|
||||
from .services import OPENING_SHOT_DIRECTIVE, rewrite_speech_as_audio_only
|
||||
|
||||
if OPENING_SHOT_DIRECTIVE not in api_prompt:
|
||||
api_prompt = f"{OPENING_SHOT_DIRECTIVE}\n{api_prompt}"
|
||||
api_prompt = rewrite_speech_as_audio_only(api_prompt)
|
||||
|
||||
return {
|
||||
"content_items": content_items,
|
||||
@@ -480,7 +493,7 @@ def submit_free_video(*, team, user, params: dict) -> AITask:
|
||||
|
||||
if mode == "keyframe":
|
||||
roles = [str(r.get("role") or "") for r in references]
|
||||
if any(str(r.get("type") or "image") != "image" for r in references):
|
||||
if any(str(r.get("type") or "image") not in IMAGE_LIKE_REF_TYPES for r in references):
|
||||
raise ValueError("首尾帧模式仅支持图片素材")
|
||||
if "first_frame" not in roles:
|
||||
raise ValueError("首尾帧模式需要提供首帧图片")
|
||||
|
||||
Reference in New Issue
Block a user