fix: 生成兜底增加自动素材匹配(从项目视频素材库自动选取)
CI/CD Pipeline / Frontend Lint (push) Failing after 19h40m55s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 19h40m55s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1678h16m19s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1678h16m21s
CI/CD Pipeline / Build Production Runtime Images (push) Failing after 1678h16m23s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Failing after 1678h16m23s
CI/CD Pipeline / Deploy Production (push) Failing after 1678h47m49s
CI/CD Pipeline / Frontend Lint (push) Failing after 19h40m55s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 19h40m55s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1678h16m19s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1678h16m21s
CI/CD Pipeline / Build Production Runtime Images (push) Failing after 1678h16m23s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Failing after 1678h16m23s
CI/CD Pipeline / Deploy Production (push) Failing after 1678h47m49s
This commit is contained in:
@@ -22,7 +22,7 @@ from typing import Any, List, Optional
|
||||
|
||||
from app.auth import AuthenticatedUser, get_current_user
|
||||
from app.core.celery_app import celery_app
|
||||
from app.dependencies import get_db_session, get_project_repository
|
||||
from app.dependencies import get_asset_library_repository, get_asset_repository, get_db_session, get_project_repository
|
||||
from app.schemas.generation_task import GenerationTaskResponse
|
||||
from app.services import EditPlanService
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
||||
@@ -35,6 +35,12 @@ from packages.adapters.sqlalchemy_impl.generation_task_repository import (
|
||||
from packages.adapters.sqlalchemy_impl.template_clip_config_repository import (
|
||||
SQLAlchemyTemplateClipConfigRepository,
|
||||
)
|
||||
from packages.adapters.sqlalchemy_impl.asset_library_repository import (
|
||||
SQLAlchemyAssetLibraryRepository,
|
||||
)
|
||||
from packages.adapters.sqlalchemy_impl.asset_repository import (
|
||||
SQLAlchemyAssetRepository,
|
||||
)
|
||||
from packages.adapters.sqlalchemy_impl.template_repository import (
|
||||
SQLAlchemyTemplateRepository,
|
||||
)
|
||||
@@ -441,6 +447,8 @@ def generate_plan(
|
||||
db: Session = Depends(get_db_session),
|
||||
current_user: AuthenticatedUser = Depends(get_current_user),
|
||||
project_repository: Any = Depends(get_project_repository),
|
||||
asset_library_repo: Any = Depends(get_asset_library_repository),
|
||||
asset_repo: Any = Depends(get_asset_repository),
|
||||
) -> EditPlanGenerateResponse:
|
||||
"""触发剪辑计划渲染生成
|
||||
|
||||
@@ -509,22 +517,71 @@ def generate_plan(
|
||||
)
|
||||
logger.info("自动兜底: plan=%s 从旧模型 template_segments 复制了 %d 个片段", plan_id, len(segments))
|
||||
|
||||
# ── 自动兜底 3: 为没有素材的片段分配素材 ──────────────────────────
|
||||
# 如果 plan.config.asset_ids 有素材,但 clips 没有 asset_id,自动按顺序分配
|
||||
all_clips = svc.list_clips(plan_id)
|
||||
clips_without_asset = [c for c in all_clips if not c.asset_id]
|
||||
config_asset_ids = (plan_check.config or {}).get("asset_ids", [])
|
||||
if clips_without_asset and config_asset_ids:
|
||||
logger.info(
|
||||
"自动兜底: plan=%s 为 %d 个无素材片段分配 %d 个素材",
|
||||
plan_id,
|
||||
len(clips_without_asset),
|
||||
len(config_asset_ids),
|
||||
)
|
||||
for i, clip in enumerate(clips_without_asset):
|
||||
asset_idx = i % len(config_asset_ids)
|
||||
svc.assign_asset(clip.id, config_asset_ids[asset_idx])
|
||||
logger.info("自动兜底: plan=%s 素材分配完成", plan_id)
|
||||
# ── 自动兜底 3: 为没有素材的片段分配素材 ──────────────────────────
|
||||
# 如果 plan.config.asset_ids 有素材,但 clips 没有 asset_id,自动按顺序分配
|
||||
all_clips = svc.list_clips(plan_id)
|
||||
clips_without_asset = [c for c in all_clips if not c.asset_id]
|
||||
config_asset_ids = (plan_check.config or {}).get("asset_ids", [])
|
||||
material_mode = (plan_check.config or {}).get("material_mode", "manual")
|
||||
|
||||
if clips_without_asset and config_asset_ids:
|
||||
logger.info(
|
||||
"自动兜底3: plan=%s 为 %d 个无素材片段分配 %d 个指定素材",
|
||||
plan_id,
|
||||
len(clips_without_asset),
|
||||
len(config_asset_ids),
|
||||
)
|
||||
for i, clip in enumerate(clips_without_asset):
|
||||
asset_idx = i % len(config_asset_ids)
|
||||
svc.assign_asset(clip.id, config_asset_ids[asset_idx])
|
||||
logger.info("自动兜底3: plan=%s 素材分配完成", plan_id)
|
||||
clips_without_asset = [] # 已分配完
|
||||
|
||||
# ── 自动兜底 4: 自动素材模式 → 从项目默认视频素材库选取 ────────────
|
||||
if clips_without_asset and material_mode == "auto" and plan_check.project_id:
|
||||
import random
|
||||
|
||||
logger.info(
|
||||
"自动兜底4: plan=%s 自动素材模式,从项目素材库选取素材 (%d 个片段需要)",
|
||||
plan_id,
|
||||
len(clips_without_asset),
|
||||
)
|
||||
# 找到项目的视频素材库
|
||||
libs = asset_library_repo.find_by_project(plan_check.project_id)
|
||||
video_lib = None
|
||||
for lib in libs:
|
||||
lib_kind = lib.kind.value if hasattr(lib.kind, "value") else lib.kind
|
||||
if lib_kind == "video":
|
||||
video_lib = lib
|
||||
break
|
||||
|
||||
if video_lib:
|
||||
assets = asset_repo.find_by_library(video_lib.id)
|
||||
# 筛选 ready 状态的视频素材
|
||||
ready_videos = [
|
||||
a
|
||||
for a in assets
|
||||
if (a.status.value if hasattr(a.status, "value") else a.status) == "ready"
|
||||
and a.mime_type
|
||||
and a.mime_type.startswith("video")
|
||||
]
|
||||
if ready_videos:
|
||||
# 随机选取,按片段数轮询分配
|
||||
random.shuffle(ready_videos)
|
||||
for i, clip in enumerate(clips_without_asset):
|
||||
asset = ready_videos[i % len(ready_videos)]
|
||||
svc.assign_asset(clip.id, asset.id)
|
||||
logger.info(
|
||||
"自动兜底4: plan=%s 从素材库 %s 分配了 %d 个素材给 %d 个片段",
|
||||
plan_id,
|
||||
video_lib.name,
|
||||
len(ready_videos),
|
||||
len(clips_without_asset),
|
||||
)
|
||||
else:
|
||||
logger.warning("自动兜底4: plan=%s 素材库无可用视频素材", plan_id)
|
||||
else:
|
||||
logger.warning("自动兜底4: plan=%s 项目无视频素材库", plan_id)
|
||||
|
||||
# 检查是否可生成
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user