拆镜复刻片段重试切片API | 真人/虚拟素材库上传API

This commit is contained in:
2026-07-09 12:07:28 +08:00
parent c05a52498e
commit 2b996e114e
18 changed files with 737 additions and 25 deletions
+18 -3
View File
@@ -241,12 +241,27 @@ class PrivatePortraitAssetGroupOut(BaseModel):
model_config = {"from_attributes": True}
class PrivatePortraitUploadOut(BaseModel):
url: str = Field(..., description="上传后的本地资源 URL,可直接用于创建私域素材")
filename: str = Field(..., description="原始文件名或安全文件名")
type: str = Field(..., description="资源类型:image/video")
module: str = Field(..., description="上传模块:private_portrait_real/private_portrait_virtual")
resource_id: str = Field(..., description="UploadResource.id。创建素材时必须作为 upload_resource_id 传回后端绑定素材")
file_size_bytes: int = Field(0, description="文件大小,单位字节")
duration_seconds: float | None = Field(None, description="视频素材秒数,图片为空")
class PrivatePortraitAssetCreate(BaseModel):
url: str = Field(
...,
min_length=1,
description="已上传到本系统且可公网访问的素材 URL。支持图片/视频,后端会转换为公网地址后调用火山 CreateAsset。",
)
upload_resource_id: str | None = Field(
None,
max_length=32,
description="可选但新客户端必须传:真人/虚拟专用上传接口返回的 UploadResource.id。后端 CreateAsset 成功后会绑定到 PrivatePortraitAsset。",
)
asset_type: str = Field(
default=PrivatePortraitAssetType.IMAGE.value,
description="素材类型枚举:Image=图片,Video=视频,Audio=音频。当前业务仅开放 Image / VideoAudio 会被拒绝。",
@@ -273,10 +288,10 @@ class PrivatePortraitAssetCreate(BaseModel):
@model_validator(mode="after")
def validate_video_duration(self) -> "PrivatePortraitAssetCreate":
if self.asset_type == PrivatePortraitAssetType.VIDEO.value:
# 允许新客户端只传 upload_resource_id,服务层会优先从 UploadResource.duration_seconds 回填秒数。
# 如果前端已传 video_duration,则这里先做范围校验,避免无效视频进入远端入库。
if self.asset_type == PrivatePortraitAssetType.VIDEO.value and self.video_duration is not None:
duration = self.video_duration
if duration is None:
raise ValueError("Video 素材必须提供 video_duration")
if duration < PRIVATE_PORTRAIT_VIDEO_MIN_DURATION_SECONDS:
raise ValueError(f"视频素材最短不能少于 {PRIVATE_PORTRAIT_VIDEO_MIN_DURATION_SECONDS}")
if duration > PRIVATE_PORTRAIT_VIDEO_MAX_DURATION_SECONDS:
@@ -740,6 +740,27 @@ class ShotReanalyzeOut(BaseModel):
analysis_status: str = Field(..., description="重置后的分析状态")
celery_task_name: str = Field(..., description="已投递或待投递的 Celery 任务名")
class ShotSplitRetryRequest(BaseModel):
force: bool = Field(False, description="是否强制重置;当前只用于兼容入参,已完成切片仍会拒绝重切,避免旧文件覆盖和资源释放复杂化")
reason: str | None = Field(None, max_length=200, description="切片失败重试原因,会写入模块日志")
@field_validator("reason", mode="before")
@classmethod
def _strip_reason(cls, value: str | None) -> str | None:
if value is None:
return None
value = str(value).strip()
return value or None
class ShotSegmentSplitRetryOut(BaseModel):
message: str = Field(..., description="操作结果提示")
task_set_id: str = Field(..., description="拆镜总任务集ID")
segment_id: str = Field(..., description="拆镜片段ID")
split_status: str = Field(..., description="重置后的切片状态")
celery_task_name: str = Field(..., description="已投递或待投递的 Celery 任务名")
class ShotSplitByAIOut(BaseModel):
task_set_id: str = Field(..., description="拆镜总任务集ID")
status: str = Field(..., description="总任务状态:pending_analysis/analyzing/analysis_completed/analysis_failed/splitting/split_completed/partial_failed/failed/deleted")
+3 -1
View File
@@ -65,7 +65,7 @@ class UploadResourceHistoryItemOut(BaseModel):
history_source: Literal["upload_resource"] = Field("upload_resource", description="素材云历史来源固定为 upload_resource")
history_source_label: str = Field("历史上传素材", description="素材云历史来源中文名称")
module: str = Field(..., description="上传资源所属模块:common=普通上传,hot_opening_replicate=爆款开头复刻,shot_replicate=拆镜复刻")
module: str = Field(..., description="上传资源所属模块:common=普通上传,hot_opening_replicate=爆款开头复刻,shot_replicate=拆镜复刻private_portrait_real=私域真人素材,private_portrait_virtual=私域虚拟素材")
module_label: str = Field(..., description="上传资源所属模块中文名称")
resource_type: Literal["image", "video", "audio"] = Field(..., description="资源类型:image=图片,video=视频,audio=音频")
resource_type_label: str = Field(..., description="资源类型中文名称")
@@ -182,4 +182,6 @@ UPLOAD_RESOURCE_HISTORY_ALLOWED_MODULES = {
UploadResourceModuleEnum.COMMON.value,
UploadResourceModuleEnum.HOT_OPENING_REPLICATE.value,
UploadResourceModuleEnum.SHOT_REPLICATE.value,
UploadResourceModuleEnum.PRIVATE_PORTRAIT_REAL.value,
UploadResourceModuleEnum.PRIVATE_PORTRAIT_VIRTUAL.value,
}