添加seedance2.5

This commit is contained in:
Azmat@qq.com
2026-08-28 16:03:23 +08:00
parent c0a0b9603b
commit a618f02315
16 changed files with 416 additions and 80 deletions
+28 -17
View File
@@ -23,15 +23,16 @@ from apps.products.models import Product
from .free_video import (
FREE_VIDEO_MODELS,
HIGH_RES_MODEL,
REPLACE_MODEL,
IN_FLIGHT_STATUSES,
RATIOS,
RESOLUTIONS,
_reap_stale_free_video_tasks,
model_duration_range,
serialize_free_video_task,
start_pending_free_video,
submit_free_video,
)
from .media_probe import REF_DURATION_MAX
from .models import AITask, ModelConfig
logger = logging.getLogger(__name__)
@@ -43,9 +44,10 @@ LEGACY_PROMPT_PREFIX = "[视频复刻]"
# 商品三视图在商品库是 standalone Asset(metadata.view=three_view + product_id),
# 和项目内的 BaseAssetGroup 是两套存储,这里直接取商品库那份。
TRIVIEW_LABEL = "目标商品三视图"
# 商品复刻的参考视频不进火山、只喂提炼模型,所以不受火山 15 秒参考视频限制。
# 半秒容差同 media_probe 的老规矩(60 秒成片常被探成 60.02)。角色复刻仍是 15 秒
PRODUCT_REF_DURATION_MAX = 60.5
# 复刻统一走 Seedance 2.5,单次能出 30 秒,所以参考视频也按 30 秒收口:
# 商品模式的参考视频只喂提炼模型,角色模式直传火山,两边都不需要超过成片上限的素材
# 半秒容差同 media_probe 的老规矩(30 秒成片常被探成 30.02)。
REPLACE_REF_DURATION_MAX = 30.5
REVIEW_UNAVAILABLE = "素材审核服务暂不可用,请稍后重试"
REVIEW_FAILED = "参考素材未通过真人合规审核,请更换视频或图片后重试"
REVIEW_SUBMIT_FAILED = "素材提交审核失败,请稍后重试"
@@ -257,12 +259,8 @@ def submit_video_replace(*, team, user, params: dict):
video = _team_asset(team, params.get("video_asset_id"), kind=Asset.Type.VIDEO, label="参考视频")
video_seconds = _asset_duration_seconds(video)
if replace_mode == "product":
if video_seconds > PRODUCT_REF_DURATION_MAX:
raise ValueError("参考视频不能超过 60 秒,请剪短后重试")
elif video_seconds > REF_DURATION_MAX:
# 角色复刻把参考视频直传火山,15 秒是火山那边的硬限制,不能跟着放宽。
raise ValueError("参考视频不能超过 15 秒,请剪短后重试")
if video_seconds > REPLACE_REF_DURATION_MAX:
raise ValueError("参考视频不能超过 30 秒,请剪短后重试")
if has_product:
subject_name, image_refs, subject_source = _product_library_refs(team, product_id)
@@ -282,7 +280,8 @@ def submit_video_replace(*, team, user, params: dict):
}
base_params = {
"mode": "universal",
"model": str(params.get("model") or HIGH_RES_MODEL),
# 商品和角色都固定走 Seedance 2.5:只有它支持 30 秒单次出片,不接受前端指定别的档
"model": REPLACE_MODEL,
"aspect_ratio": str(params.get("aspect_ratio") or "9:16"),
"resolution": str(params.get("resolution") or "720p"),
"duration": duration,
@@ -494,7 +493,7 @@ def _create_reviewing_task(*, team, user, params: dict, digest_pending: bool = F
两种情况共用:①角色复刻的素材还在审核 ②商品复刻的参考视频还没拆解。
"""
model_name = str(params.get("model") or HIGH_RES_MODEL)
model_name = str(params.get("model") or REPLACE_MODEL)
aspect_ratio = str(params.get("aspect_ratio") or "9:16")
resolution = str(params.get("resolution") or "720p")
try:
@@ -507,8 +506,9 @@ def _create_reviewing_task(*, team, user, params: dict, digest_pending: bool = F
raise ValueError("画面比例无效")
if resolution not in RESOLUTIONS:
raise ValueError("分辨率无效")
if not 4 <= duration <= 15:
raise ValueError("视频时长需在 4-15 秒之间")
low, high = replace_duration_range()
if not low <= duration <= high:
raise ValueError(f"视频时长需在 {low}-{high} 秒之间")
model_config = (
ModelConfig.objects.select_related("provider")
@@ -754,16 +754,27 @@ def _asset_duration_seconds(asset: Asset) -> float:
return primary.duration_ms / 1000.0
def replace_duration_range() -> tuple[int, int]:
"""复刻模型(Seedance 2.5)支持的出片时长区间。模型没配好时回落 4–15,不至于炸。"""
model = (
ModelConfig.objects.filter(
name=REPLACE_MODEL, capability=ModelConfig.Capability.VIDEO, status=ModelConfig.Status.ACTIVE
).first()
)
return model_duration_range(model)
def _output_duration(requested, video_seconds: float) -> int:
low, high = replace_duration_range()
try:
value = int(requested) if requested not in (None, "") else 0
except (TypeError, ValueError):
value = 0
if value:
return min(15, max(4, value))
return min(high, max(low, value))
if video_seconds:
return min(15, max(4, int(round(video_seconds))))
return 15
return min(high, max(low, int(round(video_seconds))))
return high
def _owned_ref(asset: Asset, *, kind: str, role: str, label: str) -> dict: