feat: improve subject generation workflow

This commit is contained in:
2026-05-18 17:44:52 +08:00
parent 78bd294d57
commit 1f600ae436
12 changed files with 682 additions and 372 deletions

View File

@@ -17,6 +17,7 @@ import { AdRecreationBoard } from "@/components/ad-recreation-board"
import {
addManualFrame, analyzeJob, createJob, getJob, listJobs, uploadJob, deleteJob, deleteFrame, deleteGeneratedImage,
deleteGeneratedVideo, deleteCutout, generateStoryboardVideo, triggerTranscribe, describeFrame, updateStoryboard, copyProductLibraryAsset,
formatJobError, retryJobDownload,
type Job, type ImageRef, type KeyFrame, type ProductFusionShot, type StoryboardScene, type FrameExtractMode, type FrameExtractQuality, type FrameExtractTarget,
} from "@/lib/api"
import { TRANSPARENT_HUMAN_NEGATIVE_PROMPT, TRANSPARENT_HUMAN_VIDEO_PROMPT } from "@/lib/workflow-target"
@@ -569,15 +570,30 @@ export default function Home() {
const handleStartProduction = useCallback(async (inputUrl?: string) => {
const trimmed = inputUrl?.trim()
const created = trimmed ? await handleSubmit(trimmed) : undefined
const target = created ?? job
let target = created ?? job
if (!target) {
toast.info("先粘贴视频链接或选择一个素材任务")
return
}
if (!created && target.status === "failed") {
autoTriggeredRef.current.delete(`${target.id}:audio`)
autoTriggeredRef.current.delete(`${target.id}:visual`)
}
if (!created && target.status === "failed" && !target.video_url) {
try {
target = await retryJobDownload(target.id)
updateJobInList(target)
toast.info("已重新提交下载;下载完成后会自动跑音频文案路和视觉抽帧路")
} catch (e) {
toast.error("重新下载失败:" + (e instanceof Error ? e.message : String(e)))
return
}
}
setProductionJobIds((prev) => new Set(prev).add(target.id))
toast.success("已进入并行素材分析:下载完成后自动跑音频文案路和视觉抽帧路")
if (target.video_url) toast.success("已进入并行素材分析:音频文案路和视觉抽帧路会同步推进")
else toast.success("已进入并行素材分析:下载完成后自动跑音频文案路和视觉抽帧路")
void startProductionLanesForJob(target)
}, [handleSubmit, job, startProductionLanesForJob])
}, [handleSubmit, job, startProductionLanesForJob, updateJobInList])
useEffect(() => {
if (productionJobIds.size === 0) return
@@ -860,6 +876,9 @@ export default function Home() {
if (job?.status === "downloaded" && prevStatusRef.current !== "downloaded") {
toast.info("视频已下载,音频解析会自动开始;也可以在右侧手动重试", { duration: 6000 })
}
if (job?.status === "failed" && prevStatusRef.current !== "failed") {
toast.error(formatJobError(job.error) || "任务失败", { duration: 10000 })
}
prevStatusRef.current = job?.status ?? null
const TERMINAL: Job["status"][] = ["downloaded", "frames_extracted", "transcribed", "failed"]